Skip to content

Commit dc0ca74

Browse files
authored
Simplify ROS2Heartbeat (#653)
1 parent 0b39765 commit dc0ca74

File tree

3 files changed

+24
-54
lines changed

3 files changed

+24
-54
lines changed

ihmc-communication/src/main/java/us/ihmc/communication/ros2/ROS2Heartbeat.java

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
import std_msgs.msg.dds.Empty;
44
import us.ihmc.commons.UnitConversions;
5-
import us.ihmc.commons.exception.DefaultExceptionHandler;
6-
import us.ihmc.commons.exception.ExceptionTools;
7-
import us.ihmc.commons.thread.ThreadTools;
8-
import us.ihmc.commons.thread.Throttler;
5+
import us.ihmc.commons.thread.RepeatingTaskThread;
96
import us.ihmc.ros2.ROS2Node;
107
import us.ihmc.ros2.ROS2Publisher;
118
import us.ihmc.ros2.ROS2Topic;
@@ -42,23 +39,16 @@ public class ROS2Heartbeat
4239
*/
4340
public static final double STATUS_FREQUENCY = 2.5;
4441
public static final double HEARTBEAT_PERIOD = UnitConversions.hertzToSeconds(STATUS_FREQUENCY);
45-
private ROS2PublishSubscribeAPI ros2;
46-
private ROS2Publisher<Empty> heartbeatPublisher;
47-
private final Empty emptyMessage = new Empty();
48-
private final ROS2Topic<Empty> heartbeatTopic;
49-
private volatile boolean alive = false;
50-
private final Throttler throttler = new Throttler();
42+
private static final Empty EMPTY_MESSAGE = new Empty();
5143

52-
public ROS2Heartbeat(ROS2PublishSubscribeAPI ros2, ROS2Topic<Empty> heartbeatTopic)
53-
{
54-
this.ros2 = ros2;
55-
this.heartbeatTopic = heartbeatTopic;
56-
}
44+
private final ROS2Publisher<Empty> heartbeatPublisher;
45+
private final RepeatingTaskThread publishThread;
5746

5847
public ROS2Heartbeat(ROS2Node ros2Node, ROS2Topic<Empty> heartbeatTopic)
5948
{
60-
this.heartbeatTopic = heartbeatTopic;
6149
heartbeatPublisher = ros2Node.createPublisher(heartbeatTopic);
50+
publishThread = new RepeatingTaskThread("Heartbeat-" + heartbeatTopic.getName(), () -> heartbeatPublisher.publish(EMPTY_MESSAGE));
51+
publishThread.setFrequencyLimit(STATUS_FREQUENCY);
6252
}
6353

6454
/**
@@ -67,34 +57,14 @@ public ROS2Heartbeat(ROS2Node ros2Node, ROS2Topic<Empty> heartbeatTopic)
6757
public void setAlive(boolean alive)
6858
{
6959
if (alive)
70-
{
71-
if (!this.alive)
72-
ThreadTools.startAsDaemon(() -> ExceptionTools.handle(this::publishThread, DefaultExceptionHandler.MESSAGE_AND_STACKTRACE),
73-
"Heartbeat-" + heartbeatTopic.getName());
74-
this.alive = true;
75-
}
60+
publishThread.startRepeating();
7661
else
77-
{
78-
this.alive = false;
79-
}
80-
}
81-
82-
private void publishThread()
83-
{
84-
while (alive)
85-
{
86-
if (ros2 != null)
87-
ros2.publish(heartbeatTopic);
88-
else
89-
heartbeatPublisher.publish(emptyMessage);
90-
throttler.waitAndRun(HEARTBEAT_PERIOD);
91-
}
62+
publishThread.stopRepeating();
9263
}
9364

9465
public void destroy()
9566
{
96-
setAlive(false);
97-
if (heartbeatPublisher != null)
98-
heartbeatPublisher.remove();
67+
publishThread.kill();
68+
heartbeatPublisher.remove();
9969
}
10070
}

ihmc-footstep-planning/src/visualizers/java/us/ihmc/footstepPlanning/ui/RemoteFootstepPlannerUI.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
import javafx.stage.Stage;
55
import us.ihmc.communication.PerceptionAPI;
66
import us.ihmc.communication.ros2.ROS2Heartbeat;
7-
import us.ihmc.communication.ros2.ROS2Helper;
87
import us.ihmc.footstepPlanning.communication.FootstepPlannerMessagerAPI;
98
import us.ihmc.javaFXToolkit.ApplicationNoModule;
109
import us.ihmc.messager.javafx.SharedMemoryJavaFXMessager;
10+
import us.ihmc.ros2.ROS2Node;
11+
import us.ihmc.ros2.ROS2NodeBuilder;
1112

1213
/**
1314
* This class provides a visualizer for the remote footstep planner found in the footstep planner toolbox.
@@ -20,6 +21,7 @@ public class RemoteFootstepPlannerUI extends ApplicationNoModule
2021
private RemoteUIMessageConverter messageConverter;
2122

2223
private FootstepPlannerUI ui;
24+
private final ROS2Node ros2Node = new ROS2NodeBuilder().build("height_map_heartbeat_node");
2325
private ROS2Heartbeat heightMapHeartbeat;
2426

2527
@Override
@@ -28,7 +30,8 @@ public void start(Stage primaryStage) throws Exception
2830
messager = new SharedMemoryJavaFXMessager(FootstepPlannerMessagerAPI.API);
2931
messageConverter = RemoteUIMessageConverter.createConverter(messager, "");
3032

31-
heightMapHeartbeat = new ROS2Heartbeat(new ROS2Helper("height_map_heartbeat"), PerceptionAPI.REQUEST_HEIGHT_MAP);
33+
34+
heightMapHeartbeat = new ROS2Heartbeat(ros2Node, PerceptionAPI.REQUEST_HEIGHT_MAP);
3235
heightMapHeartbeat.setAlive(true);
3336

3437
messager.startMessager();
@@ -41,6 +44,7 @@ public void start(Stage primaryStage) throws Exception
4144
public void stop() throws Exception
4245
{
4346
heightMapHeartbeat.destroy();
47+
ros2Node.destroy();
4448

4549
super.stop();
4650

ihmc-high-level-behaviors/src/libgdx/java/us/ihmc/rdx/ui/graphics/ros2/RDXYOLOv8Settings.java

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@
55
import imgui.type.ImInt;
66
import perception_msgs.msg.dds.YOLOv8ParametersMessage;
77
import us.ihmc.commons.thread.Notification;
8+
import us.ihmc.commons.thread.Throttler;
89
import us.ihmc.communication.PerceptionAPI;
910
import us.ihmc.communication.ros2.ROS2Heartbeat;
10-
import us.ihmc.communication.ros2.ROS2PublishSubscribeAPI;
11-
import us.ihmc.rdx.imgui.ImGuiTools;
11+
import us.ihmc.communication.ros2.ROS2Helper;
1212
import us.ihmc.rdx.ui.graphics.RDXVisualizer;
13-
import us.ihmc.commons.thread.Throttler;
14-
15-
import java.util.Arrays;
16-
import java.util.HashSet;
1713

1814
/*
1915
* FIXME: It doesn't make sense to have a visualizer for settings.
@@ -25,7 +21,7 @@ public class RDXYOLOv8Settings extends RDXVisualizer
2521
private static final String[] AVAILABLE_SENSORS = {"ZED", "D455"};
2622
private static final double MESSAGE_PUBLISH_PERIOD = 2; // publish messages every 2 seconds
2723

28-
private final ROS2PublishSubscribeAPI ros2;
24+
private ROS2Helper ros2Helper;
2925

3026
private final ImFloat confidenceThreshold = new ImFloat(0.8f);
3127
private final ImFloat nmsThreshold = new ImFloat(0.1f);
@@ -41,14 +37,14 @@ public class RDXYOLOv8Settings extends RDXVisualizer
4137
private final Throttler messagePublishThrottler = new Throttler().setPeriod(MESSAGE_PUBLISH_PERIOD);
4238
private final Notification parametersChanged = new Notification();
4339

44-
public RDXYOLOv8Settings(String title, ROS2PublishSubscribeAPI ros2)
40+
public RDXYOLOv8Settings(String title, ROS2Helper ros2Helper)
4541
{
4642
super(title);
4743

48-
this.ros2 = ros2;
44+
this.ros2Helper = ros2Helper;
4945

50-
demandYOLOv8ICPZed = new ROS2Heartbeat(ros2, PerceptionAPI.REQUEST_YOLO_ZED);
51-
demandYOLOv8ICPRealsense = new ROS2Heartbeat(ros2, PerceptionAPI.REQUEST_YOLO_REALSENSE);
46+
demandYOLOv8ICPZed = new ROS2Heartbeat(ros2Helper.getROS2Node(), PerceptionAPI.REQUEST_YOLO_ZED);
47+
demandYOLOv8ICPRealsense = new ROS2Heartbeat(ros2Helper.getROS2Node(), PerceptionAPI.REQUEST_YOLO_REALSENSE);
5248

5349
// Select all target detections at beginning
5450
// targetDetections.addAll(Arrays.asList(YOLOv8DetectionClass.values()));
@@ -122,7 +118,7 @@ public void update()
122118
// for (YOLOv8DetectionClass targetDetection : targetDetections)
123119
// message.getTargetDetectionClasses().add(targetDetection.toByte());
124120

125-
ros2.publish(PerceptionAPI.YOLO_PARAMETERS, message);
121+
ros2Helper.publish(PerceptionAPI.YOLO_PARAMETERS, message);
126122
}
127123
}
128124

0 commit comments

Comments
 (0)