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

DynamixelCommand Client #381

Open
NAEE09 opened this issue Feb 7, 2024 · 1 comment
Open

DynamixelCommand Client #381

NAEE09 opened this issue Feb 7, 2024 · 1 comment
Assignees

Comments

@NAEE09
Copy link

NAEE09 commented Feb 7, 2024

HI!!

I just want to use a dynamixel motor (PM42) with operanting mode: 4 (extended position control mode). I have already created a new file yaml for the dynamixel_controllers.launch, and use the command line "rosservice call /dynamixel_workbench/dynamixel_command command: ' ' .... " and it works, but I want to make a python script with a client for dynamixel_command, but It gives me an error. Maybe this is something very simple, but if you can help me, I will be very grateful!

Model Name: PM42-010-S260-R
yaml file:

dyna1:
  ID: 1
  Return_Delay_Time: 0
  Operating_Mode: 4

Client script

#!/usr/bin/env python
import rospy
from dynamixel_workbench_msgs.srv import DynamixelCommand



if __name__ == "__main__":
	rospy.init_node('set_position')
	rospy.wait_for_service('dynamixel_workbench/dynamixel_command')
	client_pos = rospy.ServiceProxy('dynamixel_workbench/dynamixel_command',DynamixelCommand)
	request = DynamixelCommand()
	request.command = ''
	request.id = 1
	request.addr_name = 'goal_position'
	request.value = 263000
	is_success = client_pos(request)

The commands I used in order

$ roslaunch dynamixel_workbench_controllers dynamixel_controllers.launch

$ rosrun my_dynamixel_tutorial control_position_spool.py 

Error message on terminal

raceback (most recent call last):
  File "/home/me/catkin_ws/devel/lib/my_dynamixel_tutorial/control_position_spool.py", line 15, in <module>
    exec(compile(fh.read(), python_script, 'exec'), context)
  File "/home/me/catkin_ws/src/my_dynamixel_tutorial/src/control_position_spool.py", line 21, in <module>
    is_success = client_pos(request)
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/impl/tcpros_service.py", line 442, in __call__
    return self.call(*args, **kwds)
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/impl/tcpros_service.py", line 498, in call
    request = rospy.msg.args_kwds_to_message(self.request_class, args, kwds) 
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/msg.py", line 122, in args_kwds_to_message
    return data_class(*args)
  File "/home/me/catkin_ws/devel/lib/python3/dist-packages/dynamixel_workbench_msgs/srv/_DynamixelCommand.py", line 42, in __init__
    super(DynamixelCommandRequest, self).__init__(*args, **kwds)
  File "/opt/ros/noetic/lib/python3/dist-packages/genpy/message.py", line 354, in __init__
    raise TypeError('Invalid number of arguments, args should be %s' % str(self.__slots__) + ' args are' + str(args))
TypeError: Invalid number of arguments, args should be ['command', 'id', 'addr_name', 'value'] args are(<dynamixel_workbench_msgs.srv._DynamixelCommand.DynamixelCommand object at 0x7f085cec16a0>,)
@yun-goon
Copy link

Hi @NAEE09
Apologies for the delayed response.
The issue in your script is due to the way you are trying to call the DynamixelCommand service. The DynamixelCommandRequest object, which is the expected input for the service, requires the fields command, id, addr_name, and value to be specified individually. However, in your script, you are incorrectly creating a DynamixelCommand object and passing it directly, which results in a TypeError.

Here’s how to fix the issue:

Correct Python Client Script:

#!/usr/bin/env python
import rospy
from dynamixel_workbench_msgs.srv import DynamixelCommand

if __name__ == "__main__":
    rospy.init_node('set_position')  # Initialize the ROS node
    rospy.wait_for_service('dynamixel_workbench/dynamixel_command')  # Wait for the service to become available
    
    # Create a client for the DynamixelCommand service
    client_pos = rospy.ServiceProxy('dynamixel_workbench/dynamixel_command', DynamixelCommand)

    try:
        # Call the service with the correct parameters
        response = client_pos(
            command='',       # Empty string for command
            id=1,             # Dynamixel ID
            addr_name='Goal_Position',  # Address name to write
            value=263000      # Value to write
        )
        
        # Check the response from the service
        if response.comm_result:
            rospy.loginfo("Successfully sent the goal position!")
        else:
            rospy.logerr("Failed to send the goal position.")

    except rospy.ServiceException as e:
        rospy.logerr(f"Service call failed: {e}")

Key Fixes:

  1. Directly Pass Parameters to ServiceProxy: Instead of creating a DynamixelCommand object manually, pass the required fields (command, id, addr_name, and value) directly to the ServiceProxy call.

  2. Proper Error Handling: Added error handling to log the service exception if it occurs.

If you get the "Failed to send the goal position" error, try decreasing the value.

This corrected script should work as intended for setting the goal position. Let me know if you encounter further issues!

@yun-goon yun-goon self-assigned this Jan 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants