|
37 | 37 | import rclpy |
38 | 38 | from geometry_msgs.msg import Inertia, Vector3 |
39 | 39 | from rclpy.node import Node |
| 40 | +from rclpy.qos import DurabilityPolicy, QoSProfile, ReliabilityPolicy |
40 | 41 | from control_msgs.action import FollowJointTrajectory |
41 | 42 | from controller_manager_msgs.srv import SwitchController |
| 43 | +from std_msgs.msg import Bool |
| 44 | +from ur_dashboard_msgs.msg import RobotMode, SafetyMode |
42 | 45 |
|
43 | 46 | sys.path.append(os.path.dirname(__file__)) |
44 | 47 | from test_common import ( # noqa: E402 |
@@ -100,6 +103,46 @@ def test_get_robot_software_version(self): |
100 | 103 | self._configuration_controller_interface.get_robot_software_version().major, 1 |
101 | 104 | ) |
102 | 105 |
|
| 106 | + def test_mock_hardware_publishes_operational_status(self): |
| 107 | + """Mock hardware reports deterministic happy-path status on latched topics.""" |
| 108 | + messages = {} |
| 109 | + qos = QoSProfile( |
| 110 | + depth=1, |
| 111 | + durability=DurabilityPolicy.TRANSIENT_LOCAL, |
| 112 | + reliability=ReliabilityPolicy.RELIABLE, |
| 113 | + ) |
| 114 | + subscriptions = [ |
| 115 | + self.node.create_subscription( |
| 116 | + RobotMode, |
| 117 | + "/io_and_status_controller/robot_mode", |
| 118 | + lambda msg: messages.setdefault("robot_mode", msg.mode), |
| 119 | + qos, |
| 120 | + ), |
| 121 | + self.node.create_subscription( |
| 122 | + SafetyMode, |
| 123 | + "/io_and_status_controller/safety_mode", |
| 124 | + lambda msg: messages.setdefault("safety_mode", msg.mode), |
| 125 | + qos, |
| 126 | + ), |
| 127 | + self.node.create_subscription( |
| 128 | + Bool, |
| 129 | + "/io_and_status_controller/robot_program_running", |
| 130 | + lambda msg: messages.setdefault("program_running", msg.data), |
| 131 | + qos, |
| 132 | + ), |
| 133 | + ] |
| 134 | + |
| 135 | + deadline = time.monotonic() + 10.0 |
| 136 | + while len(messages) < 3 and time.monotonic() < deadline: |
| 137 | + rclpy.spin_once(self.node, timeout_sec=0.1) |
| 138 | + |
| 139 | + self.assertEqual(messages.get("robot_mode"), RobotMode.RUNNING) |
| 140 | + self.assertEqual(messages.get("safety_mode"), SafetyMode.NORMAL) |
| 141 | + self.assertIs(messages.get("program_running"), True) |
| 142 | + |
| 143 | + for subscription in subscriptions: |
| 144 | + self.node.destroy_subscription(subscription) |
| 145 | + |
103 | 146 | def test_start_jtc_controller(self): |
104 | 147 | # Deactivate controller, if it is not already |
105 | 148 | self.assertTrue( |
|
0 commit comments