Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question]: Not able to control robot via publihing on command/joint_group #235

Open
vignesh-anand opened this issue Dec 19, 2024 · 4 comments
Labels
manipulators Issues related to manipulators question Further information is requested

Comments

@vignesh-anand
Copy link

vignesh-anand commented Dec 19, 2024

Question

How do i precisely control joint positions via a publisher in ros2 humble

Robot Model

wx250s

Operating System

Ubuntu 22.04

ROS Version

ROS 2 Humble

Additional Info

vignesh@vignesh-OMEN:~$ ros2 topic list
/follower/commands/joint_group
/follower/commands/joint_single
/follower/commands/joint_trajectory
/follower/joint_states

I see these topics and I am trying to command joint positions at 30 Hz via a publisher that looks like this

self.arm_pub.publish_commands("arm", leader_joints[:-1])

class WidowXPublisher:
    def __init__(self, node: Node, topic_name: str, debug: bool = False) -> None:
        self.node = node
        self.debug = debug
        
        # Create QoS profile matching the subscriber
        qos = QoSProfile(
            reliability=QoSReliabilityPolicy.RELIABLE,
            durability=QoSDurabilityPolicy.VOLATILE,
            history=QoSHistoryPolicy.KEEP_LAST,
            depth=10
        )
        
        # Create the publisher using the provided node
        self.publisher = self.node.create_publisher(
            JointGroupCommand,
            topic_name,
            qos
        )
        
    def publish_commands(self, group_name: str, commands: np.ndarray) -> None:
        """
        Publish joint commands to the specified group
        
        Args:
            group_name: Name of the joint group to control
            commands: numpy array of joint commands
        """
        msg = JointGroupCommand()
        msg.name = group_name
        msg.cmd = commands.tolist()  # Convert numpy array to list for ROS message
        self.publisher.publish(msg)
        if self.debug:
            self.node.get_logger().info(f"Published {group_name} commands: {commands}")
        else:
            self.node.get_logger().debug(f"Published {group_name} commands: {commands}")

Either I get the very first pose being acted on and then everything else ignored or , nothing at all.

@vignesh-anand vignesh-anand added manipulators Issues related to manipulators question Further information is requested labels Dec 19, 2024
@lukeschmitt-tr
Copy link
Member

Please enable debug logging on the xs_sdk of the follower and provide the results.

@vignesh-anand
Copy link
Author

vignesh-anand commented Dec 21, 2024

[xs_sdk-2] [INFO] [1734762026.178721740] [interbotix_xs_sdk.xs_sdk]: InterbotixRobotXS is up!
[xs_sdk-2] [DEBUG] [1734762026.185234] ID: 1, writing position command 2096.
[xs_sdk-2] [DEBUG] [1734762026.185297] ID: 2, writing position command 796.
[xs_sdk-2] [DEBUG] [1734762026.185310] ID: 4, writing position command 3115.
[xs_sdk-2] [DEBUG] [1734762026.185319] ID: 6, writing position command 2058.
[xs_sdk-2] [DEBUG] [1734762026.185327] ID: 7, writing position command 1730.
[xs_sdk-2] [DEBUG] [1734762026.185334] ID: 8, writing position command 2158.
[xs_sdk-2] [DEBUG] [1734762026.185570] ID: 1, writing position command 2096.
[xs_sdk-2] [DEBUG] [1734762026.185612] ID: 2, writing position command 796.
[xs_sdk-2] [DEBUG] [1734762026.185626] ID: 4, writing position command 3115.
[xs_sdk-2] [DEBUG] [1734762026.185635] ID: 6, writing position command 2058.
[xs_sdk-2] [DEBUG] [1734762026.185642] ID: 7, writing position command 1730.
[xs_sdk-2] [DEBUG] [1734762026.185649] ID: 8, writing position command 2158.
[xs_sdk-2] [DEBUG] [1734762026.185866] ID: 1, writing position command 2096.
[xs_sdk-2] [DEBUG] [1734762026.185898] ID: 2, writing position command 796.
[xs_sdk-2] [DEBUG] [1734762026.185908] ID: 4, writing position command 3115.
[xs_sdk-2] [DEBUG] [1734762026.185915] ID: 6, writing position command 2059.
[xs_sdk-2] [DEBUG] [1734762026.185923] ID: 7, writing position command 1730.
[xs_sdk-2] [DEBUG] [1734762026.185930] ID: 8, writing position command 2158.

Only this is output and nothing else.

jetson1@jetson4-desktop:~/marcel-brain/ros2_ws (manipulation)$ ros2 topic hz /follower/commands/joint_group 
average rate: 33.326
	min: 0.029s max: 0.031s std dev: 0.00034s window: 35
average rate: 33.338
	min: 0.028s max: 0.032s std dev: 0.00040s window: 69
average rate: 33.339
	min: 0.028s max: 0.032s std dev: 0.00035s window: 103

Commands are definitely being published

Here are my configs

port: /dev/ttyDXL

groups:
  arm:
    operating_mode: position
    profile_type: time
    profile_velocity: 2000
    profile_acceleration: 1000
    torque_enable: true

singles:
  gripper:
    operating_mode: position
    torque_enable: true
port: /dev/ttyDXL

joint_order: [waist, shoulder, elbow, forearm_roll, wrist_angle, wrist_rotate, gripper]
sleep_positions: [0, -1.80, 1.55, 0, 0.8, 0, 0]

joint_state_publisher:
  update_rate: 100
  publish_states: true
  topic_name: joint_states

groups:
  arm: [waist, shoulder, elbow, forearm_roll, wrist_angle, wrist_rotate]

grippers:
  gripper:
    horn_radius: 0.014
    arm_length: 0.024
    left_finger: left_finger
    right_finger: right_finger

shadows:
  shoulder:
    shadow_list: [shoulder_shadow]
    calibrate: true
  elbow:
    shadow_list: [elbow_shadow]
    calibrate: true

sisters:

motors:
  waist:
    ID: 1
    Baud_Rate: 3
    Return_Delay_Time: 0
    Drive_Mode: 0
    Velocity_Limit: 131
    Min_Position_Limit: 0
    Max_Position_Limit: 4095
    Secondary_ID: 255

  shoulder:
    ID: 2
    Baud_Rate: 3
    Return_Delay_Time: 0
    Drive_Mode: 0
    Velocity_Limit: 131
    Min_Position_Limit: 819
    Max_Position_Limit: 3345
    Secondary_ID: 255

  shoulder_shadow:
    ID: 3
    Baud_Rate: 3
    Return_Delay_Time: 0
    Drive_Mode: 1
    Velocity_Limit: 131
    Min_Position_Limit: 819
    Max_Position_Limit: 3345
    Secondary_ID: 2

  elbow:
    ID: 4
    Baud_Rate: 3
    Return_Delay_Time: 0
    Drive_Mode: 0
    Velocity_Limit: 131
    Min_Position_Limit: 648
    Max_Position_Limit: 3094
    Secondary_ID: 255

  elbow_shadow:
    ID: 5
    Baud_Rate: 3
    Return_Delay_Time: 0
    Drive_Mode: 1
    Velocity_Limit: 131
    Min_Position_Limit: 648
    Max_Position_Limit: 3094
    Secondary_ID: 4

  forearm_roll:
    ID: 6
    Baud_Rate: 3
    Return_Delay_Time: 0
    Drive_Mode: 0
    Velocity_Limit: 131
    Min_Position_Limit: 0
    Max_Position_Limit: 4095
    Secondary_ID: 255

  wrist_angle:
    ID: 7
    Baud_Rate: 3
    Return_Delay_Time: 0
    Drive_Mode: 1
    Velocity_Limit: 131
    Min_Position_Limit: 910
    Max_Position_Limit: 3447
    Secondary_ID: 255

  wrist_rotate:
    ID: 8
    Baud_Rate: 3
    Return_Delay_Time: 0
    Drive_Mode: 0
    Velocity_Limit: 131
    Min_Position_Limit: 0
    Max_Position_Limit: 4095
    Secondary_ID: 255

  gripper:
    ID: 9
    Baud_Rate: 3
    Return_Delay_Time: 0
    Drive_Mode: 0
    Velocity_Limit: 131

Echoing the /follower/commands/joint group shows that the right commands I want are definitely being published
using self.arm_pub.publish_commands("arm", leader_joints[:-1]) in my script

#!/usr/bin/env python3

import rclpy
from rclpy.node import Node
from sensor_msgs.msg import JointState
from interbotix_xs_msgs.msg import JointGroupCommand
from manipulation.utils import WidowXSubscriber, WidowXPublisher
import numpy as np
from math import pi

class FollowerNode(Node):
    def __init__(self):
        super().__init__('follower_node')
        self.get_logger().debug('Initialized follower node')
        
        # Create subscribers for both leader and follower
        self.leader_sub = WidowXSubscriber(self, '/leader/joint_states', False)
        self.get_logger().debug('Created leader subscriber')
        
        self.follower_sub = WidowXSubscriber(self, '/follower/joint_states', False)
        self.get_logger().debug('Created follower subscriber')
        
        # Create publishers using WidowXPublisher classd
        self.arm_pub = WidowXPublisher(self, '/follower/commands/joint_group', False)
        self.get_logger().debug('Created arm publisher')
        
        self.gripper_pub = WidowXPublisher(self, '/follower/commands/joint_single', False)
        self.get_logger().debug('Created gripper publisher')
        
        # Create timer for control loop (10Hz)
        self.timer = self.create_timer(0.2, self.control_loop)
        self.get_logger().debug('Created control loop timer')
        
    def control_loop(self):
        # Get current joint positions
        leader_joints = self.leader_sub.get_joint_positions()
        follower_joints = self.follower_sub.get_joint_positions()
        
        # Check if either subscriber returned None
        if leader_joints is None or follower_joints is None:
            self.get_logger().warn('Joint positions not available yet')
            return
            
        # Directly command the follower to match leader positions
        # Handle arm joints (all except last)
        self.arm_pub.publish_commands("arm", leader_joints[:-1])
        
        # Handle gripper (last joint)
        self.gripper_pub.publish_commands("gripper", np.array([leader_joints[-1]]))

def main(args=None):
    rclpy.init(args=args)
    node = FollowerNode()
    rclpy.spin(node)
    rclpy.shutdown()

if __name__ == '__main__':
    print("STARTING FOLLOWER NODE")
    main()

@vignesh-anand vignesh-anand changed the title [Question]: [Question]: Not able to control robot via publihing on command/joint_group Dec 21, 2024
@lukeschmitt-tr
Copy link
Member

Please provide the RMW implementation you're using by running printenv RMW_IMPLEMENTATION. We've seen more reliable communication when using rmw_cyclonedds_cpp over the default rmw_fastrtps_cpp.

@vignesh-anand
Copy link
Author

Hi Lukeschmitt,
So the arm works perfectly on my laptop, and my DDS works perfectly as well, I get the joint states and everything perfectly and all the echo/hz tests I have done work perfectly. It is when I run the driver on the Jetson, that none of the services or subscribers work in the SDK. The callbacks never get triggered. The joint state publisher works great

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
manipulators Issues related to manipulators question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants