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.
Part I: Gazebo Differential Drive Challenge (Individual)
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.
Package Structure
The package should be called diff_drive
In addition to the standard ROS directories, the package should be structured as
config/
(.yaml
files)urdf/
(urdf.xacro
and.gazebo.xacro
files)launch/
(.launch.py
files)worlds/
(.sdf
files, if needed)models/
(.sdf
files, if needed)
There is a hints section at the bottom of each section.
Creating the World
- Using models from Gazebo Fuel (and optionally the resource spawner) create a world called
worlds/ddrive.world.sdf
with the following features- An asphalt ground plane
- At least two Jersey Barriers
- At least two Cardboard Boxes
- At least two other models of your choosing
- All models should be stored under the
models/
directory (rather than being references viauri
).
- Write a launchfile called
launch/ddrive.launch.{py,xml}
(python or xml your choice).- For now, it should launch gazebo and load the world you just created.
- IMPORTANT Make sure that the world
sdf
file does not contain any absolute paths. It seems that the resource spawner will useabsolute
paths on your local machine. You will likely need to manually edit thesdf
file and replacefile://
absolute paths withmodel://
relative paths. See Resource Spawner Notes for more details.
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 (though trying to be realistic in terms of mass and density can help).
- 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.xacro
file and include it inurdf
xacro
file.
- The dimensional parameters of the robot should be stored in a
- Create a launchfile called
ddrive_rviz.launch.{py,xml}
that launches theurdf
in RViz, along with arobot_state_publisher
- If argument
view_only
is true, then ajoint_state_publisher_gui
is also launched - This launchfile will be useful for debugging.
- If argument
Gazebo Extensions
- Add the "Differential Drive" plugin to your robot, as appropriate (in the
ddrive.gazebo.xacro
file). - Add a new
rviz
configuration that also shows theodom
message inrviz
.- Load this configuration when
view_only
is false inddrive_rviz.launch.{py,xml}
- Load this configuration when
- Modify
ddrive.launch.{py,xml}
so that it- Spawns the URDF model in the gazebo world and starts the simulation.
- Runs
ros2_gz_bridge
so that odometry and joint states are published from the robot to ROS on the appropriate topics - Includes
ddrive_rviz.launch.{py,xml}
to launch rviz.
Control
- Write a node called
flip
that makes the robot move back and forth along a line by flipping over itself rather than turning.- Both wheels 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 the
teleop_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.
- Make sure that
ddrive.launch.{py,xml}
starts theflip
node
Hints
- 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.
- There is an option for viewing inertias in
rviz
under theRobotModel
view
- Just like with ROS nodes, an old gazebo simulation running in the background can be trouble.
- Use
ps aux | grep gazebo
to find old gazebo instances
- Use
Part II: Motion Planning Interface (Group)
The ROS 2 API for motion planning revolves around actions, services, and topics provided by the /move_group
node.
However, filling in the appropriate messages, requests, and goals can become tedious.
Instead, the goal is to make a library that abstracts the lower-level ROS API away and makes planning easier.
The project can roughly be divided into the following components. It is important to read about all the components to get a wider understanding of the project itself.
Group Organization
- This part is done in your final project groups and should be submitted as a single git repository via the link on canvas.
- Everyone is expected to contribute equally (as evidenced by commits and peer evaluations).
- Use the Simple Git Workflow to coordinate git commits with each other
- It is important that you follow the workflow so that everybody's contributions are incorporated and counted.
- In your
README.md
, list all group members as authors and provide instructions on how to use your package (written from the perspective of somebody who is already familiar with ROS 2).- Authors of the package need not be cited in
citations.txt
- Authors of the package need not be cited in
Dividing the Work
- I have divided the project into components that can be worked on mostly independently, once interfaces between them are designed.
- I have also rated the effort required for each task
- Each person should take on approximately 4 units of effort as their primary responsibility, and should also try to work on at least two areas.
- Each person should be available to help on any of the sections.
- Motion Planning: 8 units
- Planning Scene: 2 units
- Robot State: 2 units
- Integration: 4 units
- Sample Task 4 units
Work Flow
- It makes sense to setup the project so that different people are working in different files.
- If one module depends on another, define the module boundaries early and implement stubs. Then fill in the stubs later.
- In some cases, the best way to help is via pair programming: one student works at the keyboard while another looks on and helps.
- If you do pair programming, it is important that you take turns so that each partner can have commits.
- Especially at the beginning, as you are trying to establish the structure of the project, everyone being together and working on the same project makes sense.
- It is crucial to follow the Simple Git Workflow and integrate your code into the
main
branch frequently- The longer the team diverges, the harder it is to integrate the code later.
- Prior to getting to fancy and dividing up the tasks, it makes sense to work together on the MoveIt Activity to get up to speed on how MoveIt works and get some basic functionality working.
Motion Planning
Write a class called MotionPlanner
that enables a user to:
- Plan a path from any valid starting joint configuration to any valid goal joint configuration.
- If the starting configuration is not provided, the current robot position is used.
- Plan a path from a specified pose (position and orientation) from any starting configuration
- If the starting configuration is not provided, the current robot position is used.
- If the goal position is not specified, the plan should achieve the specified orientation (at any position)
- If the goal orientation is not specified, the plan should achieve the specified position (at any orientation)
- Plan a Cartesian path from any valid starting pose to a goal pose.
- If the starting configuration is not provided, the current robot position is used.
- Plan a path from any valid starting pose to a named configuration
- Any of the paths should be able to
- Be executed immediately after planning
- Be saved and inspected at a later time
- Estimated Work Effort: 8 Work Units
Planning Scene
Write a class called PlanningScene
that enables a user to:
- Add or remove boxes to the planning scene dynamically, at any location
- Attach and detach collision objects to the robot's end-effector.
- Load a planning scene from parameters that specify the locations and sizes of objects.
- Estimated Work Effort: 1 Work Unit
Robot State
Write a class called RobotState
that enables a user to:
- Perform inverse kinematics on the robot from an arbitrary end-effector pose
- If no pose is specified, use the current location
- Perform forward kinematics on the robot from an arbitrary joint state
- If no pose is specified, use the current location
- Retrieve the most up-to-date joint configuration or end-effector pose from the robot.
- Estimated Work Effort: 2 Work Units
Integration
The goal of integration is to combine the MotionPlanner
, PlanningScene
, and RobotState
(referred to as MotionPlanningInterface
)
with each other and present it in a form that makes it easy to incorporate into a custom node (referred to as UserNode
).
Here are some challenges:
- What
UserNode
does is not known at the time of creating theMotionPlanningInterface
.- The user needs to be able to create
UserNode
in the usual way, while also usingMotionPlanningInterface
- The user needs to be able to create
MotionPlanningInterface
requires aNode
object in order to maintain theRobotState
and use theROS API
provided by themove_group
node.- These components must all share the same
Node
.
- These components must all share the same
- Some of the above functionality takes a long time (such as planning and moving the arm) so
UserNode
needs to have the ability to either wait for the task to complete or initiate a task, work on something else, and check for the result later. - Estimated Work Effort: 4 Work Units
Sample Task
Setting The Scene
For this task you will assume full knowledge of locations and sizes of the following objects:
- A Table: this should be part of the planning scene.
- An object: the goal should be to grab this object and move it somewhere else
- An obstacle: this obstacle should be in between the end-effector and the object such that moving in a straight line would cause the robot to hit the obstacle
The Node
Write a node called pick_node
that does the following in response to a call to it's /pick
service:
- Moves the arm directly above the object
- Opens the gripper
- Moves directly downwards until the object is between the grippers
- Closes the grippers
- Lifts the object slightly off the table
- Attaches a rectangle (roughly corresponding to the size of the object) to the end-effector
- Moves the object to the other side of the obstacle
- Releases the object and detaches the rectangle
The Launchfile
Write a launchfile called pickplace.launch.{xml,py}
(your choice of xml
or python
that
- Takes an argument called
demo
- If
demo
is true, it starts the Frankademo.launch.py
- If
demo
is false, it just startsrviz
(and assumes the proper nodes are running onstation
).
- If
- Starts the Franka demonstration.
- Runs the
pick_node
The Videos
- Take a screencast of the robot performing it's task in demonstration mode.
- Take a video of the the robot performing the task in the real world.
- Include both videos in the
README.md
and make sure that they play properly onGitHub
.
Testing and Documentation
- Write an integration test that uses the kinematic Franka simulation to command the
Franka Panda
robot to move from one pose to another and verify that the pose is achieved. - Write an integration test, using the
Franka Panda
Robot demonstration that creates a planning scene object and attempts to move the robot into that object and verify that planning fails. - Running
rosdoc2
on your library should provide usable API documentation.