1
1
package us .ihmc .lerobot ;
2
2
3
- import behavior_msgs .msg .dds .VisuomotorOperationMessage ;
3
+ import behavior_msgs .msg .dds .VLAOperationMessage ;
4
4
import org .bytedeco .opencv .global .opencv_core ;
5
5
import org .bytedeco .opencv .global .opencv_imgproc ;
6
6
import org .bytedeco .opencv .opencv_core .Mat ;
34
34
import us .ihmc .robotics .robotSide .RobotSide ;
35
35
import us .ihmc .robotics .robotSide .SideDependentList ;
36
36
import us .ihmc .ros2 .ROS2Node ;
37
- import us .ihmc .ros2 .ROS2NodeBuilder ;
38
37
import us .ihmc .ros2 .ROS2Publisher ;
39
38
import us .ihmc .ros2 .ROS2Topic ;
40
39
import us .ihmc .sensors .ImageSensor ;
46
45
import java .util .concurrent .CompletableFuture ;
47
46
48
47
/**
49
- * Autonomy process thread for managing visuomotor inference and supporting remote UI.
50
- * Manages communication with the Python side, which is running the LeRobot code
51
- * with pytorch inference of the visuomotor policy. We use a ROS 2 API to interface with it.
48
+ * Autonomy process thread for managing vision-language-action (VLA) inference and supporting remote UI.
49
+ * Manages communication with the Python side, which is running the openpi.
52
50
*/
53
- public class VisuomotorPolicyUpdateThread extends RepeatingTaskThread
51
+ public class VLAUpdateThread extends RepeatingTaskThread
54
52
{
55
- public static final ROS2IOTopicPair <VisuomotorOperationMessage > OPERATOR_UI
56
- = new ROS2IOTopicPair <>(new ROS2Topic <>().withPrefix ("lerobot_ui" ).withTypeName (VisuomotorOperationMessage .class ));
57
-
53
+ public static final ROS2IOTopicPair <VLAOperationMessage > UI = new ROS2IOTopicPair <>(new ROS2Topic <>().withPrefix ("vla_ui" )
54
+ .withTypeName (VLAOperationMessage .class ));
58
55
private final ROS2SyncedRobotModel syncedRobot ;
59
56
private final ImageSensor zedSensor ;
60
57
private String status = "Not connected to openpi" ;
@@ -73,23 +70,23 @@ public class VisuomotorPolicyUpdateThread extends RepeatingTaskThread
73
70
private final Throttler actionThrottler = new Throttler ().setFrequency (5.0 );
74
71
private final int planSize = 5 ;
75
72
76
- private final ROS2Node ros2Node = new ROS2NodeBuilder ().build ("visuomotor_update_thread" );
77
73
private final LatestTimestampModifiable latestTimestampModifiable ;
78
74
private long sequenceID = 0L ;
79
75
private final CRDTBidirectionalBoolean running ;
80
76
private final CRDTBidirectionalBoolean controlRobot ;
81
- private final TypedNotification <VisuomotorOperationMessage > uiCommandSubscription ;
82
- private final ROS2Publisher <VisuomotorOperationMessage > uiStatusPublisher ;
77
+ private final TypedNotification <VLAOperationMessage > uiCommandSubscription ;
78
+ private final ROS2Publisher <VLAOperationMessage > uiStatusPublisher ;
83
79
84
80
private final ROS2Publisher <KinematicsStreamingToolboxInputMessage > kstInputPublisher ;
85
81
private final ROS2Publisher <ToolboxStateMessage > kstStatePublisher ;
86
82
87
- public VisuomotorPolicyUpdateThread (ROS2PeerClockOffsetEstimator clockOffsetEstimator ,
88
- DRCRobotModel robotModel ,
89
- ROS2SyncedRobotModel syncedRobot ,
90
- ImageSensor zedSensor )
83
+ public VLAUpdateThread (ROS2Node ros2Node ,
84
+ ROS2PeerClockOffsetEstimator clockOffsetEstimator ,
85
+ DRCRobotModel robotModel ,
86
+ ROS2SyncedRobotModel syncedRobot ,
87
+ ImageSensor zedSensor )
91
88
{
92
- super (VisuomotorPolicyUpdateThread .class .getSimpleName ());
89
+ super (VLAUpdateThread .class .getSimpleName ());
93
90
94
91
this .syncedRobot = syncedRobot ;
95
92
this .zedSensor = zedSensor ;
@@ -104,8 +101,8 @@ public VisuomotorPolicyUpdateThread(ROS2PeerClockOffsetEstimator clockOffsetEsti
104
101
running = new CRDTBidirectionalBoolean (latestTimestampModifiable , false );
105
102
controlRobot = new CRDTBidirectionalBoolean (latestTimestampModifiable , false );
106
103
107
- uiCommandSubscription = ROS2Tools .createNotificationSubscription (ros2Node , OPERATOR_UI .getTopic (ROS2ActorDesignation .ROBOT .getIncomingQualifier ()));
108
- uiStatusPublisher = ros2Node .createPublisher (OPERATOR_UI .getTopic (ROS2ActorDesignation .ROBOT .getOutgoingQualifier ()));
104
+ uiCommandSubscription = ROS2Tools .createNotificationSubscription (ros2Node , UI .getTopic (ROS2ActorDesignation .ROBOT .getIncomingQualifier ()));
105
+ uiStatusPublisher = ros2Node .createPublisher (UI .getTopic (ROS2ActorDesignation .ROBOT .getOutgoingQualifier ()));
109
106
110
107
kstInputPublisher = ros2Node .createPublisher (ToolboxAPIs .getIKStreamingInputTopic (robotModel .getSimpleRobotName ()));
111
108
kstStatePublisher = ros2Node .createPublisher (ToolboxAPIs .getIKStreamingStateTopic (robotModel .getSimpleRobotName ()));
@@ -116,7 +113,7 @@ protected void runTask()
116
113
{
117
114
if (uiCommandSubscription .poll ())
118
115
{
119
- VisuomotorOperationMessage uiCommand = uiCommandSubscription .read ();
116
+ VLAOperationMessage uiCommand = uiCommandSubscription .read ();
120
117
latestTimestampModifiable .fromMessage (uiCommand .getLatestTimestampModifiable ());
121
118
boolean wasRunning = running .getValue ();
122
119
running .fromMessage (uiCommand .getRunning ());
@@ -300,7 +297,7 @@ else if (openpiRequest.isDone())
300
297
status = "Not running" ;
301
298
}
302
299
303
- VisuomotorOperationMessage uiStatus = new VisuomotorOperationMessage ();
300
+ VLAOperationMessage uiStatus = new VLAOperationMessage ();
304
301
latestTimestampModifiable .toMessage (uiStatus .getLatestTimestampModifiable ());
305
302
uiStatus .setSequenceId (sequenceID ++);
306
303
uiStatus .setRunning (running .toMessage ());
@@ -310,15 +307,12 @@ else if (openpiRequest.isDone())
310
307
uiStatus .getActionHandPoses ()[side .ordinal ()].set (actionHandPoses .get (side ));
311
308
uiStatus .getActionForearmPoses ()[side .ordinal ()].set (actionForearmPoses .get (side ));
312
309
}
313
- uiStatus .setPythonStatusFrequency (statusFrequency .getFrequencyDecaying ());
314
- uiStatus .setPythonStatusMessage (status );
315
- uiStatus .setReceivedActions (numberOfActionsReceived );
310
+ uiStatus .setStatusMessage ("%-30s Actions: %d" .formatted (status , numberOfActionsReceived ));
316
311
uiStatusPublisher .publish (uiStatus );
317
312
}
318
313
319
314
public void destroy ()
320
315
{
321
316
blockingKill ();
322
- ros2Node .destroy ();
323
317
}
324
318
}
0 commit comments