Homework 3
Logistics
- Create a git repository using the link provided in Canvas.
- Your homework will be submitted via this git repository.
- I will grade whatever is on the
main
branch when I clone the repository. - Guidelines provides important information about what
you should turn-in, including information about your
README.md
file. You will create two separate ROS packages for this assignment but store them in the same git repository. T
my_git_repository/diff_drive/{package.xml, CMakeLists.txt, README.md, etc} my_git_repository/arm_move/{package.xml, CMakeLists.txt, README.md, etc}
- Each package should have it's own
README.md
.
- Each package should have it's own
Robots
- This assignment will use the
pincherX 100
robot. - If you are not an MSR student, follow the setup guide: PincherX 100
Part I: Gazebo Differential Drive Challenge
The challenge is to create a differential-drive robot that can be simulated in Gazebo and controlled by ROS.
- The robot will be able to flip over and continue driving
- The robot will move through a world filled with Jersey Barriers and trash.
Your submission should be a subdirectory with
package.xml
CMakeLists.txt
/config
(.yaml
files)/urdf
(.xacro
and.gazebo
files)/launch
(.launch
files)/worlds
(.world
files)/nodes
(Your ROS nodes.)
There is a hints section at the bottom of each section.
Creating the World
- Use the Gazebo GUI to create your world. Place an asphalt plane over the ground plane.
Then add some Jersey Barriers (at least 2), A few cardboard boxes (at least 3) and something
else you find interesting. Save your world as
ddrive.world
in theworld/
directory of your project - Write a launchfile called
ddrive.launch
. For now, it should launch gazebo and load the world you just created.
The Xacro URDF
Robot Description
- The robot has a body consisting of a rectangular prism. It has two cylindrical wheels on the front and a caster at the rear.
- There should be a caster on the top and bottom of the robot so that it is symmetrical about its horizontal plane
- Each caster link should be modified to have no friction in gazebo so that it can slide freely.
- Feel free to set the masses and dimensions of the robot to suit your needs.
- Create a
ddrive.urdf.xacro
file to describe the differential-drive robot.- The dimensional parameters of the robot should be stored in a
.yaml
file and referenced in thexacro file
- Each link you add must have the proper collision bounding box and inertia.
- Place
gazebo
specific tags in a separateddrive.gazebo
file that is included in your mainurdf
xacro
.
- The dimensional parameters of the robot should be stored in a
- Create a launchfile called
ddrive_rviz.launch
that launches theurdf
in RViz, along with arobot_state_publisher
and optionally ajoint_state_publisher_gui
. This launchfile will be useful for debugging. - Modify
ddrive.launch
so that it spawns your URDF model in the gazebo world.- Use a launchfile argument to start gazebo with the simulation paused. You will need to remember to unpause when you actually want the simulation to run.
- Modify
ddrive.launch
so that it loads the urdf into the/robot_description
parameter.
Gazebo Extensions
- Add gazebo materials to each of your links so they appear as an appropriate color.
Add the "Differential Drive" plugin to your robot.
You may adapt the following code (which I adapted from the Gazebo Plugins in Ros Tutorial
<gazebo> <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so"> <rosDebugLevel>na</rosDebugLevel> <alwaysOn>true</alwaysOn> <updateRate>100</updateRate> <leftJoint>left_wheel</leftJoint> <rightJoint>right_wheel</rightJoint> <wheelSeparation>${body_width+wheel_width}</wheelSeparation> <wheelDiameter>${wheel_radius}</wheelDiameter> <wheelTorque>20</wheelTorque> <commandTopic>diff/cmd_vel</commandTopic> <odometryTopic>diff/odom</odometryTopic> <odometryFrame>odom</odometryFrame> <robotBaseFrame>base_link</robotBaseFrame> <publishWheelTF>false</publishWheelTF> <publishOdomTF>true</publishOdomTF> <publishWheelJointState>true</publishWheelJointState> <wheelAcceleration>false</wheelAcceleration> <odometrySource>world</odometrySource> <publishTf>1</publishTf> </plugin> </gazebo>
- The above code assumes your wheel joints are called
left_wheel
andright_wheel
and also refers to somexacro
parameters I defined for the dimensions of the robot. You may need to modify it to match yoururdf.xacro
file. - Create a new
rviz
configuration using theodom
frame as the fixed frame. Theodom
frame is published by the differential drive gazebo plugin - Launch rviz with this configuration so that you can visualize where the robot thinks it is, according to it's wheel odometry.
Control
- Write a node called
flip
that makes the robot move back and forth along a line by flipping over itself rather than turning. (i.e., both wheels should move with the same velocity at all times). You will need to use the dynamics of the robot to accomplish this task. You may find that theteleop_twist_keyboard
package is useful for letting you get a feel for the dynamics.- Precise control is great but not necessary, just have fun doing some flips.
Hints
- If your model is loaded into the
/robot_description parameter
, and gazebo is running: userosrun gazebo_ros spawn_model -urdf -param robot_description -model ddrive -b
- The
-b
will cause gazebo to delete the model when you kill the node - The
-param
loads the urdf from the parameter server. You can use-file
to load from a urdf file (converted usingxacro
manually) - Links will not be exported to the
sdf
unless they have visual and inertial elements. - I suggest pausing the simulation when you spawn the robot.
- If you are not careful about where you spawn the robot or having a collision element (so it doesn't fall through the ground), it can fly off into space.
- You can run the spawn_model node from a launchfile for easier use
- The
- For this exercise, you may wish to use
xacro
macros to create the visual, collision, and inertial elements from a single set of parameters specifying the geometry and orientation of the link.- For example, in this case the visual and collision elements can be identical
- Macros can be nested. So build them up slowly and view the results incrementally by outputting the urdf file from the xacro file.
- For your links to show up with the proper colors in gazebo, you need to assign them a gazebo material, as per the Using URDF in Gazebo tutorial.
- The URDF material tag does not get translated so your links will just show up as gray if you don't include this separately.
- The view menu in gazebo can let you visualize the inertial properties See in the "Checking in Gazebo section" of http://gazebosim.org/tutorials?tut=inertia&cat=build_robot
- If gazebo is having trouble opening, it may not have exited cleanly:
ps aux | grep gazebo
will show gazebo processes to killrosnode kill
will show ros nodes to killps aux | grep ros
will show ros processes to kill- You can try
killall gzserver
to kill the gazebo server - You can try
killall gzclient
to kill the gazebo client
- It is helpful to not need to restart gazebo every time you want to test your robot.
- Feel free to arrange your launchfiles such that starting gazebo is optional and in a way that makes it easy to spawn/remove your model
- You can also call gazebo services from the command-line or use rosrun to help during debugging
- The simulation can be rather finicky when it comes to ground contact and friction with the wheels.
If you are having trouble with the robot sliding oddly or not moving when you spin the wheels:
- Make sure that the bottom of the caster and the bottom of the wheels are at the exact same height
- Make sure that the dimensions and mass of the vehicle are reasonable in relation to each other
- Make sure the wheels have high friction coefficients (.e.g,
<mu1>999</mu1>
and<mu2>999</mu2>
i You can adjust some collision properties in the
gazebo
part of theurdf
, which may help:<gazebo reference="wheel_name_here"> <mu1>1</mu1> <mu2>1</mu2> <kp>500000.0</kp> <kd>10.0</kd> <minDepth>0.001</minDepth> <maxVel>0.1</maxVel> <fdir1>1 0 0</fdir1> </gazebo>
- Depending on your vehicle inertias, you may need to adjust these parameters
- Read more about the parameters here: Gazebo Elements For Links
- If your robot is drifting a little when not commanded with a velocity that is okay. You can usually correct
for this by always explicitly sending a
/cmd_vel
command of 0.
Part II: Motion Planning
- You will do this final task on the real robot and in gazebo.
- The overall goal is to train a robot to follow a series of waypoints to grab an object
- Copy the launchfile used by the px100 gazebo program to
arm_box.launch
and modify it so that it loads a custom world containing a RealSense Box. The box is 14cm x 9cm x 5cm and weights 100g - In this project you will use the MoveIt Python API to create a planning scene and perform some path planning tasks
- The robot arm sits on top of a table. The RealSense Box also sits on top of the table and is an obstacle
- Create a node called
mover
that implements the following:- Upon startup, adds a collision object representing the table to the planning scene.
- The node loads a list of waypoints from the parameter server
- If waypoints do not yet exist, the list is empty
- A
reset
service that- Takes a position and orientation of the realsense box and creates/moves the Realsense Box to the appropriate location
- Moves the robot to its pre-defined
'Home'
position without hitting the box ('Home'
is pre-defined by the SDK) - Reset takes a parameter that determines if the waypoints are cleared or not.
- A
step
service that moves the robot to a user-specified position and also a gripper state (open or closed)step
returns the MoveItErrorCode to indicate success or failure of the plan- If the motion plan succeeds,
step
adds the position to the list of waypoints, storing it in the parameter server, and executes the plan - If the motion plan fails, it is okay, use the MoveItErrorCode to interpret why
- A
follow
service that has the robot move to each waypoint, in sequence- Follow should contain an option that determines if the cycle should be repeated or run just once.
- Add another small light object to the (real/simulated) world. Use the
step
andfollow
services to generate a sequence of waypoints that allows the robot to pick up the object from a fixed location and drop it off elsewhere.- When you get a working sequence, save the corresponding ROS parameters to a yaml file and include it in your repository
- Your launchfile should load the waypoints from the yaml file
- Write a launchfile called
arm.launch
- The launchfile should setup the robot or simulation (depending on the value of an argument called
use_sim
) to be controlled from themover
node - Include an option to run the MoveIt
fake_node
instead of gazebo, whenuse_sim
is true. - The
mover
node should start and be loaded with an initial waypoint sequence - RViz should be loaded.
Rviz
should show the robot and the planning scene
- The launchfile should setup the robot or simulation (depending on the value of an argument called
- Write a launchfile called
arm.test
for your integration tests- This should use fake moveit and also start your
mover
node. - It should call
reset
service - It should then call the
step
service in such a way that the robot will crash into the floor- Verify that the
step
service returns an error code
- Verify that the
- It should also call the
step
service in such a way that it succeeds.- Verify the success
- This test launchfile should be added to
catkin
so that it runs withcatkin_make
run tests
- This should use fake moveit and also start your
- Include a link to a video in your README.md of the robot in gazebo and in the real world accomplishing its task
Hints
- It is often easier to launch gazebo and keep it running. Then just kill and manually restart your node
- You may wish to do the bulk of your testing with the
fake
MoveIt node prior to involving the simulation or the real robot.- With the interactive
moveit
view you can interactively determine lots of information about the robot such as- It's planning groups,
- It's built-in positions
- With the interactive
- You may wish to run through some tutorials prior to attempting the assignment:
- Remember, this robot has fewer than 6-dof, so many 6-DOF poses of the end effector are invalid.
- You can
set_position_target
to set position without respect to pose andset_orientation_target
orset_rpy_target
to set one without regard for the other. You can also plan to joint positions. get_current_pose()
is also helpful for debugging to see the exact current location of the end effector- You can try out most things in the RViz GUI prior to coding them
- There are two tricky parts to PlanningSceneInterface that you must work around
- After creating the PlanningSceneInterface, it's publishers may not have necessarily finished connecting to their respective topics
- This means that you can potentially add an object prior to the PlanningSceneInterface being ready, in which case the object will not get added
- Your node could exit after modifying the planning scene but before the message is published.
- To solve these issues, you should, after every action on a planning scene, wait (with a timeout) to see if your changes actually took effect
- Sample code for doing this is provided in the tutorial
- Depending on the context, the action you take after a timeout failure is different
- For example, if you just started the planning scene, you may wish to retry the addition a few times upon timing out
- After creating the PlanningSceneInterface, it's publishers may not have necessarily finished connecting to their respective topics
- All parameters/names used by the interbotix arm are stored under the
/px100
namespace. This means that you will need to specify/remap names throughout this assignment so that they use the appropriate values in the /px100 namespace- In particular, when launching the
mover
node you should- remap
/attached_collision_object
to/px100/attached_collision_object
- remap
/collision_object
to/px100/collision_object
- Launch your node in the
px100
namespace
- remap
- In particular, when launching the
- It is up to you what rotational representation (e.g., quaternions or euler angles) to use for your services
- If the gazebo simulation drops the object, you may wish to edit
custom_ws/interbotix_ros_manipulators/interbotix_xsarm_gazebo/config/interbotix_texture.gazebo
to increase the coefficient of friction on the grippers.
Resources
- The MoveIt Notes
- The Gazebo notes
- See Test A ROS Node
1 The moveit tutorials https://ros-planning.github.io/moveit_tutorials/
- It may help to go through some tutorials prior to starting
- MoveitQuickstart in Rviz, Move Group Python Interface are the two most important