Skip to content

Controlling a Toy Car

Adnan Munawar edited this page Apr 16, 2019 · 5 revisions

Controlling dVRK Manipulators

This is an example of how to begin using the AMBF Simulator. Let's start by going to the launch file in your local cloned repository. This launch file is located in ambf/ambf_models/descriptions/launch. Let's open up this file in your favorite editors and uncomment the dVRK Manipulators while commenting out the other Robots. Your launch file should look like this.

Again, be careful to not remove any whitespace, just the # comment symbols.

Now let's launch the simulator as described in Launching the Simulator. Do you see the dVRK ECM, PSM, and MTM as shown below? If yes, great, otherwise close the simulator and double check to see if you have any unintended whitespaces or extra tab spaces in the ambf/ambf_models/descriptions/launch file above. Correct these and relaunch the simulator

Controlling using RQT GUI

As a demo, some premade RQT files have been placed in ambf/ambf_utilities/rqt_perspectives to get you up and running.

In a terminal, launch rqt_gui using:

rosrun rqt_gui rqt_gui

Now in the top menu of rqt_gui, navigate to Perspectives -> Import

From the file browser, head to ambf/ambf_utilities/rqt_perspectives and select the ecm-psm-mtm-rqt-gui.perspective file. Note that AMBF could be installed in a non-default path in your system, so make sure to go to the correct path.

Great. You should see some topics already visible for selection in the rqt_gui. Select the checkbox for any topics to see the effect on the corresponding dVRK manipulator. Uncheck the checkbox to reset the commands. You can expand the topics in the RQT Gui to see what kind of command are we issuing to the manipulators.

Controlling using the Python Client

Now let's use the provided python client for finer control of the manipulators. you can use the following python code snippet:

# Import the Client from ambf_client package
from ambf_client import Client
import time

# Create a instance of the client
_client = Client()

# Connect the client which in turn creates callable objects from ROS topics
# and initiates a shared pool of threads for bi-directional communication
_client.connect()

print('\n\n----')
raw_input("We can see what objects the client has found. Press Enter to continue...")
# You can print the names of objects found. We should see all the links found
print(_client.get_obj_names())

# Lets get a handle the chassis of the toy car
chassis_handle = _client.get_obj_handle('Chassis')

# Let's get a handle to the two front suspensions which have the wheels
# as their children
shock_fr_handle = _client.get_obj_handle('ShockFR')
shock_fl_handle = _client.get_obj_handle('ShockFL')

# Let's sleep for a very brief moment to give the internal callbacks
# to sync up new data from the running simulator
time.sleep(0.2)

print('\n\n----')
raw_input("Let's Get Some Pose Info. Press Enter to continue...")
# Not we can print the pos and rotation of object in the World Frame
print('Chassis Pos:')
print(chassis_handle.get_pos())
print('Chassis Rot:')
print(chassis_handle.get_rot())


print('\n\n----')
raw_input("Let's get Joints and Children Info. Press Enter to continue...")
# We can get the number of children and joints connected to each object as
chassis_num_joints = chassis_handle.get_num_joints() # Get the number of joints of this object
chassis_joint_names = chassis_handle.get_joint_names() # Get a list of children names belonging to this obj
chassis_children_names = chassis_handle.get_children_names() # Get a list of children names belonging to this obj
print('Number of Joints in Chassis:')
print(chassis_num_joints)

print(' ')
print('Joint names for Chassis:')
print(chassis_joint_names)

print(' ')
print('Name of Chassis\' children:')
print(chassis_children_names)

print('\n\n----')
raw_input("Control Wheel Angles. Press Enter to continue...")
# In this example, rather than controlling the joints from Chassis, lets control
# them from lower down the hierarchy. In this case, we shall use the FR Shock and FL
# Shock which parent the FR Wheel and FL Wheel respectively.

# Set the position of FL wheel
shock_fl_handle.set_joint_pos(0, 1.57)

# Set the Position of FR Wheel
shock_fr_handle.set_joint_pos(0, -1.57)

print('\n\n----')
raw_input("Control Wheel Torques. Press Enter to continue...")
# Now lets directly control the wheel torques.
shock_fl_handle.set_joint_effort(0, 0.6)
# Set some torque for FR Wheel
shock_fr_handle.set_joint_effort(0, 0.9)
# Lets sleep for a few seconds to see the effect
time.sleep(5)

shock_fl_handle.set_joint_effort(0, 0.0)
# Set some torque for FR Wheel
shock_fr_handle.set_joint_effort(0, 0.0)

print('\n\n----')
raw_input("Set force on Chassis for 5 secs. Press Enter to continue...")
# Let's directly control the forces and torques on the Chassis Link
# Notice that these are in the world frame. Another important thing to notice
# is that unlike position control, forces control requires a continuous update
# to meet a watchdog timing condition otherwise the forces are cleared. This
# is purely for safety reasons to prevent unchecked forces in case of malfunctioning
# python client code
for i in range(0, 500):
    chassis_handle.set_force(100, 0, 0)  # Set 100 N in the World Z axis
    time.sleep(0.01)  # Run the loop for 5 seconds

print('\n\n----')
raw_input("Set torque on Chassis for 2 secs. Press Enter to continue...")
# Similarly we can individually apply the torque
for i in range(0, 200):
    chassis_handle.set_torque(0, 0, 60)  # Set 100 Nm in the World Z axis
    time.sleep(0.01)  # Run the loop for 2 seconds

print('\n\n----')
raw_input("Set force on Chassis in Body Frame 5 secs. Press Enter to continue...")
# The above force and torques were in the World frame. In many instances we care
# about setting the wrench in body frame. This is just as convenient. Lets see how to
# do that.
#
# Make sure you have PyKDL installed
from PyKDL import Rotation, Vector

for i in range(0, 500):
    cur_rot = chassis_handle.get_rot()
    # Rotation of Chassis in World
    R_cINw = Rotation.Quaternion(cur_rot.x, cur_rot.y, cur_rot.z, cur_rot.w)
    fw = Vector(15, 0, 0) # Lets set a force along body's X axis
    fc = R_cINw * fw  # Converted force in World Frame that would act in Body Frame
    chassis_handle.set_force(fc.x(), fc.y(), fc.z())  # Set 100 N in the World Z axis
    time.sleep(0.01)  # Run the loop for 5 seconds

print('\n\n----')
raw_input("Let's clean up. Press Enter to continue...")
# Lastly to cleanup
_client.clean_up()
Clone this wiki locally