Programming a Service client for ROBOTIS Open Manipulator

Written by Marco Arruda

27/03/2020

Hello ROS Developers!

In this post, we are going to show a way of creating a custom program to send desired positions with respect to the task space of the Open Manipulator end effector.

There are many possibilities to program this robot. For the sake of simplicity, we will use a single service available to move the arm to a specific position.

Although, the step-by-step explanation will show you how to use everything this simulation provides.


 

Configuring the Environment

If you haven’t configured the environment from the previous ROSJect, please open it using this link.

Though if you prefer to learn how to configure the environment and the simulation from scratch, start from this post.


 

How to interact with the robot – Choosing a specific service

After having the simulation running, you need to launch the controller node. This node will provide the services that send references to the real robot or the simulation (in this case, it is the simulation).

user:~$ roslaunch open_manipulator_controller open_manipulator_controller.launch use_platform:=false

Then, in another web shell, we are able to check the services available:

user:~$ rosservice list

We have many services available, let’s check the one we will use, which is  /open_manipulator/goal_task_space_path_position_only.

In order to call for the service, we need to know its structure:

user:~$ rosservice type /open_manipulator/goal_task_space_path_position_only

open_manipulator_msgs/SetKinematicsPose

We have to deal with this kind of message: open_manipulator_msgs/SetKinematicsPose

Its structure is:

user:~$ rossrv show open_manipulator_msgs/SetKinematicsPose

string planning_group
string end_effector_name
open_manipulator_msgs/KinematicsPose kinematics_pose
  geometry_msgs/Pose pose
    geometry_msgs/Point position
      float64 x
      float64 y
      float64 z
    geometry_msgs/Quaternion orientation
      float64 x
      float64 y
      float64 z
      float64 w
  float64 max_accelerations_scaling_factor
  float64 max_velocity_scaling_factor
  float64 tolerance
float64 path_time
---
bool is_planned

 

Let’s code!

Certainly, we need a simple ROS node that will act as a service client. The basic structure goes below:

#!/usr/bin/env python

import sys
import rospy
from open_manipulator_msgs.srv import *

def set_position_client(x, y, z, time):
    ...

def usage():
    return "%s [x y z]"%sys.argv[0]

if __name__ == "__main__":

    if len(sys.argv) == 5:
        x = float(sys.argv[1])
        y = float(sys.argv[2])
        z = float(sys.argv[3])
        time = float(sys.argv[4])
    else:
        print usage()
        sys.exit(1)
    print "Requesting [%s, %s, %s]"%(x, y, z)
    response = set_position_client(x, y, z, time)
    print "[%s %s %s] returns [%s]"%(x, y, z, response)

For instance, this is a template took from the ROS wiki tutorial, modified in such a way we only need to implement the service client.

Let’s check it line-by-line:

def set_position_client(x, y, z, time):
    service_name = '/open_manipulator/goal_task_space_path_position_only'

    rospy.wait_for_service(service_name)

    try:
        set_position = rospy.ServiceProxy(service_name, SetKinematicsPose)

        arg = SetKinematicsPoseRequest()
        arg.end_effector_name = 'gripper'
        arg.kinematics_pose.pose.position.x = x
        arg.kinematics_pose.pose.position.y = y
        arg.kinematics_pose.pose.position.z = z
        arg.path_time = time
        resp1 = set_position(arg)
        print 'Service done!'
        return resp1
    except rospy.ServiceException, e:
        print "Service call failed: %s"%e
        return False

It is defined the service name we want to call. Then, we wait for the service to get ready.

To start the try/catch block, we create a proxy object, that represents the service server.

A new variable will contain the required parameters for the service. We need to fill it with the arguments of the function, except for the end_effector_name, which will always be the same for this robot: gripper.

We finally call for the server (set_position) and wait for its response!


 

Demonstration

Before pressing the play button of the simulation, run the controllers in the simulation mode:

user:~$ roslaunch open_manipulator_controller open_manipulator_controller.launch use_platform:=false

Now, start the simulation with the play button.

Let’s try sending some commands to the robot, one just after another:

user:~$ rosrun programming_manipulator test.py -0.1 0.1 0.16 1

Then:

user:~$ rosrun programming_manipulator test.py 0.1 0.3 0.18 1

The result must be something like below:


 

Conclusion

This is how you can start programming for the Open Manipulator robot.

Don’t forget, if you missed any of the steps above, you can get a copy of the generated ROSJect along this post: http://www.rosject.io/l/11185626/

If you like this kind of post, share it and leave a comment!

See you in the next one!

Cheers

Topics:

Discover How to Equip Your Teams with ROS Skills Fast

The Construct For Enterprise

Check Out These Related Posts

0 Comments

Share This