feat: Implement UDP feedback for RM75 robot arms
This commit is contained in:
@@ -121,6 +121,17 @@ def _xrobotoolkit_bridge_command() -> str:
|
||||
)
|
||||
|
||||
|
||||
def _xrobotoolkit_cleanup_patterns(*, stop_pc_service: bool) -> tuple[str, ...]:
|
||||
patterns = (
|
||||
XROBOTOOLKIT_BRIDGE_EXECUTABLE,
|
||||
"RobotLinuxDemo.x86_64",
|
||||
"PXREAClientUnity",
|
||||
)
|
||||
if stop_pc_service:
|
||||
return (*patterns, "RoboticsServiceProcess")
|
||||
return patterns
|
||||
|
||||
|
||||
def _tool_command(arm: str, open_tool: bool) -> str:
|
||||
arm_name = "left_rm75" if arm == "left" else "right_rm75"
|
||||
value = "true" if open_tool else "false"
|
||||
@@ -289,8 +300,7 @@ def build_commands_by_mode(mode: str) -> list[tuple[str, str]]:
|
||||
("Ping Left RM75", f"ping -c 4 {DEFAULT_LEFT_IP}"),
|
||||
(
|
||||
"Left Arm RealMan Launch",
|
||||
"ros2 launch xr_rm_bringup arm_debug.launch.py arm:=left use_mock:=false "
|
||||
f"left_robot_ip:={DEFAULT_LEFT_IP}",
|
||||
"ros2 launch xr_rm_bringup arm_debug.launch.py arm:=left use_mock:=false",
|
||||
),
|
||||
("XRobotoolkit UDP Bridge (90 Hz)", _xrobotoolkit_bridge_command()),
|
||||
("Left Tool Open", _tool_command("left", True)),
|
||||
@@ -306,8 +316,7 @@ def build_commands_by_mode(mode: str) -> list[tuple[str, str]]:
|
||||
("Ping Right RM75", f"ping -c 4 {DEFAULT_RIGHT_IP}"),
|
||||
(
|
||||
"Right Arm RealMan Launch",
|
||||
"ros2 launch xr_rm_bringup arm_debug.launch.py arm:=right use_mock:=false "
|
||||
f"right_robot_ip:={DEFAULT_RIGHT_IP}",
|
||||
"ros2 launch xr_rm_bringup arm_debug.launch.py arm:=right use_mock:=false",
|
||||
),
|
||||
("XRobotoolkit UDP Bridge (90 Hz)", _xrobotoolkit_bridge_command()),
|
||||
("Right Tool Open", _tool_command("right", True)),
|
||||
@@ -324,9 +333,7 @@ def build_commands_by_mode(mode: str) -> list[tuple[str, str]]:
|
||||
("Ping Right RM75", f"ping -c 4 {DEFAULT_RIGHT_IP}"),
|
||||
(
|
||||
"Dual Arm RealMan Launch",
|
||||
"ros2 launch xr_rm_bringup arm_debug.launch.py arm:=both use_mock:=false "
|
||||
f"left_robot_ip:={DEFAULT_LEFT_IP} right_robot_ip:={DEFAULT_RIGHT_IP} "
|
||||
"move_to_initial_pose_on_connect:=false",
|
||||
"ros2 launch xr_rm_bringup arm_debug.launch.py arm:=both use_mock:=false",
|
||||
),
|
||||
("XRobotoolkit UDP Bridge (90 Hz)", _xrobotoolkit_bridge_command()),
|
||||
(
|
||||
@@ -1283,13 +1290,27 @@ class LauncherApp:
|
||||
return closed
|
||||
|
||||
def on_close_requested(self) -> None:
|
||||
if self.stop_launched_processes(confirm=True, notify=False):
|
||||
if self.stop_launched_processes(
|
||||
confirm=True,
|
||||
notify=False,
|
||||
stop_pc_service=True,
|
||||
):
|
||||
self.root.destroy()
|
||||
|
||||
def kill_launched_processes(self) -> None:
|
||||
self.stop_launched_processes(confirm=True, notify=True)
|
||||
self.stop_launched_processes(
|
||||
confirm=True,
|
||||
notify=True,
|
||||
stop_pc_service=False,
|
||||
)
|
||||
|
||||
def stop_launched_processes(self, *, confirm: bool, notify: bool) -> bool:
|
||||
def stop_launched_processes(
|
||||
self,
|
||||
*,
|
||||
confirm: bool,
|
||||
notify: bool,
|
||||
stop_pc_service: bool,
|
||||
) -> bool:
|
||||
if confirm and not messagebox.askyesno(
|
||||
"Confirm Stop",
|
||||
"Stop XR-RM launcher terminals, topic monitors, ROS nodes, and bridge processes started from this workspace?",
|
||||
@@ -1302,7 +1323,7 @@ class LauncherApp:
|
||||
"ros2 run xr_rm_input",
|
||||
"ros2 run xr_rm_teleop",
|
||||
"XR_RM_LAUNCHER_SESSION=1",
|
||||
XROBOTOOLKIT_BRIDGE_EXECUTABLE,
|
||||
*_xrobotoolkit_cleanup_patterns(stop_pc_service=stop_pc_service),
|
||||
TERMINAL_TITLE_PREFIX,
|
||||
TOPIC_MONITOR_TITLE,
|
||||
CMD_VEL_MONITOR_TITLE,
|
||||
@@ -1326,6 +1347,20 @@ class LauncherApp:
|
||||
"ros2 topic list",
|
||||
"ros2 node list",
|
||||
]
|
||||
pc_service_keep_pid: int | None = None
|
||||
if not stop_pc_service:
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
["pgrep", "-o", "-f", "RoboticsServiceProcess"],
|
||||
text=True,
|
||||
)
|
||||
pc_service_keep_pid = int(output.strip())
|
||||
patterns.append("RoboticsServiceProcess")
|
||||
except (subprocess.CalledProcessError, ValueError):
|
||||
pass
|
||||
except Exception as exc:
|
||||
print(f"Failed to find the oldest RoboticsServiceProcess: {exc}")
|
||||
|
||||
protected = {os.getpid(), os.getppid()}
|
||||
killed: set[int] = set()
|
||||
|
||||
@@ -1345,6 +1380,8 @@ class LauncherApp:
|
||||
continue
|
||||
if pid in protected or pid in killed:
|
||||
continue
|
||||
if pattern == "RoboticsServiceProcess" and pid == pc_service_keep_pid:
|
||||
continue
|
||||
try:
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
killed.add(pid)
|
||||
|
||||
Reference in New Issue
Block a user