import rclpy from rclpy.node import Node from sensor_msgs.msg import JointState from pythonosc.udp_client import SimpleUDPClient class JointStateOSC(Node): def __init__(self): super().__init__('joint_states_osc') # Create a ROS 2 subscriber to /joint_states topic self.subscription = self.create_subscription( JointState, '/joint_states', self.joint_states_callback, 1 # Queue size ) # Open Sound Control (OSC) Client settings self.osc_ip = "127.0.0.1" # Replace with the target IP self.osc_port = 8000 # Replace with the target port self.osc_client = SimpleUDPClient(self.osc_ip, self.osc_port) def joint_states_callback(self, msg): """Callback function to handle incoming joint states.""" header = msg.header joint_names = msg.name joint_positions = msg.position joint_velocity = msg.velocity joint_effort = msg.effort joint_names_str = "\n- ".join(joint_names) joint_positions_str = "\n- ".join(map(str, joint_positions)) joint_velocity_str = "\n- ".join(map(str, joint_velocity)) joint_effort_str = "\n- ".join(map(str, joint_effort)) info = f""" --- header: stamp: sec: {header.stamp.sec} nanosec: {header.stamp.nanosec} name: - {joint_names_str} position: - {joint_positions_str} velocity: - {joint_velocity_str} effort: - {joint_effort_str} ---""" self.osc_client.send_message(f"/joint_states", info) # Send each joint state as an OSC message for i, name in enumerate(joint_names): self.osc_client.send_message(f"/joint_states/header/sec", header.stamp.sec) # Publish Time (sec) self.osc_client.send_message(f"/joint_states/header/nanosec", header.stamp.nanosec) # Publish Time (nanosec) self.osc_client.send_message(f"/joint_states/{name}/position", joint_positions[i]) # Publish position self.osc_client.send_message(f"/joint_states/{name}/velocity", joint_velocity[i]) # Publish velocity self.osc_client.send_message(f"/joint_states/{name}/effort", joint_effort[i]) # Publish effort def main(): rclpy.init() node = JointStateOSC() rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()