Homework 2
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.- As per the guidelines, your code must pass
colcon test
cleanly
- As per the guidelines, your code must pass
- In general, you should refer to
ROS
entities using relative names from within your nodes (i.e., no leading "/") - All python launchfiles written for this assignment should use a declarative style:
- When a launch file is listed as
filename.launch.{py,xml}
you should implement both an XML and python version of that launchfile.
Overview
We will use turtlesim
to simulate a robot in ROS. The turtle
robot will be integrated into various standard ROS systems (e.g., tf
, joint_states
, etc)
and then we will control it to catch a brick that is dropped from the sky.
The repository is called homework2
and there will be two packages within the repository
turtle_brick
(anament_python
package)turtle_brick_interfaces
(for any custom interfaces that must be defined)
Hints
Here are some general hints for this assignment:
- Familiarize yourself with the overall problem by reading the homework description.
- Work on the
urdf.xacro
file to build up the robot and the launchfile to visualize the robot simultaneously- It is especially useful to be able to view and manipulate the robot when debugging
.urdf.xacro
files and the launchfile makes this process much simpler.
- It is especially useful to be able to view and manipulate the robot when debugging
- Slowly introduce node functionality over time.
- Write launchfiles early in the process. Use these launchfiles to make testing nodes easier.
Frames
The following coordinate frames will be used:
world
. This is the fixed frame, representing the location of entities in the world- All other frames are descendants of
world
- All other frames are descendants of
odom
. Items relative to this frame represent their location relative to the starting location of the turtle.- The turtle's location relative to
odom
is it's position according to its wheel odometry - The
odom
frame is at a fixed offset fromworld
and represents the initial location of the turtle.
- The turtle's location relative to
brick
. This frame is the location of the brickbase_link
. This frame is the base location of the robot- The
base_link
has other child frames, as defined by the robot'surdf
file
- The
The Robot
- The turtle robot has the same kinematics as the
turtlesim
- The robot is modeled as a unicycle robot that "self balances" on a caster. It consists of
- A
base_link
that is the main location of the robot and is represented by a cube. - A
platform
which is a cylindrical link at the top of the robot- The base of the
platform
should be parallel to the ground in the zero position, but should be able to rotate so that the brick can be dumped. - The
platform
should be a fixed vertical distance above thebase_link
, so that it may rotate fully without colliding with the base link. - A fixed cylindrical link should connect the
base_link
to theplatform
- The base of the
- A
stem
is a cylindrical link that turns about the vertical z-axis and is below thebase_link
- A
wheel
is connected to the stem and can roll as the robot moves - Each link should be a different color.
- A
- The robot has a maximum translational speed but infinite rotational speed, making it effectively omni-directional
- To move in a given direction, the
stem
points in that direction and then the robot translates (while the wheel rolls).
- To move in a given direction, the
- The
.urdf.xacro
file for the robot should be inurdf/turtle.urdf.xacro
- The visual and collision components can be the same. The inertial components can be omitted because we are only using this model kinematically.
The Arena
- The arena should be depicted in
rviz2
, with rectangular walls (drawn as markers) denoting its boundary - The arena should be the same size as the
turtlesim
simulator and have a matching coordinate system- The
world
frame should be the fixed frame. - The
odom
frame should be at the initial location of the turtle
- The
Configuration
- A configuration file called
config/turtle.yaml
should include- The
platform_height
of the robot'splatform
above the ground - The
wheel_radius
of the robot's wheel - The
max_velocity
, maximum translational velocity of the robot - The
gravity_accel
, the acceleration due to gravity - The default values of these configuration items can be chosen by you.
- The
- Anything that relies on these parameters should read the appropriate parameters from the configuration file
- In other words, changing
config/turtle.yaml
should be the only change required to work with a differentplatform_height
orwheel_radius
and have the robot appear correctly - Changes to
config/turtle.yaml
need only take affect after the code is re-built and re-run.
- In other words, changing
Visualizing the Robot
- Write a launchfile called
show_turtle.launch.{py,xml}
that displays the turtle robot (as defined byturtle.urdf.xacro
) inrviz
- The launchfile argument
use_jsp
controls the behavior of thejoint_state_publisher
- If
use_jsp
isgui
then thejoint_state_publisher_gui
is used to publish joint states (the default) - If
use_jsp
isjsp
then thejoint_state_publisher
is used to publish joint states - If
use_jsp
isnone
then no nodes that publishjoint_states
are started by the launchfile - Document the arguments that the documentation shows up when using
ros2 launch -s
- If
- The launchfile argument
rviz_config
contains the name of therviz
configuration file relative to the project's share directory. - The launchfile starts any other nodes that may be necessary to display the URDF in
rviz
- The launchfile argument
Turtle Node
- A node called
turtle_robot
serves as a bridge between theturtlesim
and actualros
interfaces and is responsible for- Publishing the
joint_states
of the turtle robot- The wheel joint state should be published so that the wheel is rolling without slipping (compute based on the wheel radius and the forward velocity).
- Broadcasting the location of the
base_link
frame relative to theodom
frame - Publishing
nav_msgs/Odometry
message on theodom
topic (covariance can be ignored, twist can be a direct copy of the latestcmd_vel
) - Publishing a
cmd_vel
message.- If the turtle is not moving, this node should publish a
cmd_vel
of 0 (a real robot would then detect the absence of such commands as a fault condition). - The robot is
holonomic
(e.g., omni-directional), socmd_vel
commands may include ay
component. - The
turtlesim
can be madeholonomic
by setting the appropriate parameter.
- If the turtle is not moving, this node should publish a
- Subscribing to a
goal_pose
topic of thegeometry_msgs/msg/PoseStamped
message type.- When the node receives this message it starts driving the robot toward the goal pose using
cmd_vel
messages
- When the node receives this message it starts driving the robot toward the goal pose using
- Subscribing to a
tilt
message (of custom typeturtle_brick_interfaces/msg/Tilt
).- The tilt angle of the platform is set to the last message received on this topic
- Subscribes to the
turtle1/pose
message- This message provides the location of the robot, and can be used to set the odometry messages and transforms
- All publishing and broadcasting shall be done at 100 Hz.
- Publishing the
- Write a launchfile called
run_turtle.launch.{py,xml}
that- Starts the
turtlesim
node (withholonomic
set toTrue
) - Starts the
turtle_robot
node - Includes
show_turtle.launch.{py,xml}
as appropriate to draw theturtle
robot inrviz
- Python launchfiles can be included in xml launchfiles and vice versa, you can use any combination you would like here.
- You can now test the
goal_pose
command and should see the robot move to the goal location - Use a declarative style for the launchfile.
- Starts the
Physics Module
- A module called
physics.py
should contain ROS-independent code to keep track of the physics of the environment. It should provide a class with the following definition.
class World: """Keep track of the physics of the world.""" def __init__(self, brick, gravity, radius, dt): """ Initialize the world. Args: brick - The (x,y,z) location of the brick gravity - the acceleration due to gravity in m/s^2 radius - the radius of the platform dt - timestep in seconds of the physics simulation """ pass @property def brick(self): """ Get the brick's location. Return: (x,y,z) location of the brick """ pass @brick.setter def brick(self, location): """ Set the brick's location. Args: location - the (x,y,z) location of the brick """ pass def drop(self): """ Update the brick's location by having it fall in gravity for one timestep """ pass
Arena Node
- A node called
arena
is responsible for simulating the environment by- Publishing markers that denote the boundaries of the environment
- Broadcasting the
brick
frame at the location of the brick, and a marker to show it's location inrviz
- Offer a service called
place
(of custom typeturtle_brick_interfaces/srv/Place
) that moves the brick to a specified location - Offering a service called
drop
that causes the brick to fall in gravity according to the specified rules:- After the service responds, the brick starts falling in gravity (using the specified
gravity
acceleration). - If the brick hits the platform or the ground it stops falling.
- If the brick hits the platform it should move with the platform
- Your code can assume that the platform is at 0 degrees when the brick is dropped and does not need to handle other cases.
- If the brick is on the platform and the platform tilts, it should slide off the platform (friction-less, but in gravity)
- When the trailing-edge brick clears the platform, it magically floats in place.
- The angle of the brick relative to the ground should be the same as the angle of the platform relative to the ground at all times.
- After the service responds, the brick starts falling in gravity (using the specified
- The node should simulate the physics at
250 Hz
- The node should use the
physics
module to perform all calculations.
Control Node
- Write a node called
catcher
that causes the turtle to catch a falling brick- When the node detects that the brick is falling it first computes (based on
max_velocity
andplatform_height
) whether it can reach the brick on-time- If the brick cannot be caught on time, the node publishes a Text marker that lasts for 3 seconds that says "Unreachable"
- If the brick can be caught on time, the robot drives under the brick.
- When the brick is caught, the robot drives back to the arena center and
tilts
the brick off.
- When the brick is caught, the robot drives back to the arena center and
- When the node detects that the brick is falling it first computes (based on
- Write a launchfile called
turtle_arena.launch.{py,xml}
that runs all the nodes necessary for the turtle to catch a brick- The launchfile should include
run_turtle.launch.{py,xml}
as needed - The
rviz
configuration should show the turtle, the arena, and the brick
- The launchfile should include
Testing
- Your code should pass all the standard tests that are run with
colcon test
- Write at least one
pytest
unit test for each of the (required) members of thephysics.World
class - Write a test launchfile called
test_brick_launch.py
that verifies that theturtle_robot
node publishescmd_vel
commands at 100 Hz - Your final result should not have any
rviz
errors or warnings once all nodes in a given launchfile have started running.
README
In the base directory of your repository (e.g. homework2
) create a README.md
using the following template (be sure to update the ${}
with the answers.)
# ME495 Embedded Systems Homework 2 Author: ${Your Name} ${A brief overview of what the package does} ## Quickstart 1. Use `ros2 launch ${pkg} ${launchfile} ${options}` to start the arena and turtle simulation 2. Use ${ros2 service call here} to drop a brick 3. Here is a video of the turtle when the brick is within catching range ${embed video here, it must be playable on github. Upload the video as an issue and link to it} 4. Here is a video of the turtle when the brick cannot be caught ${embed video here, it must be playable on github. Upload the video as an issue and link to it}
- You should capture of each of the following scenarios
- The brick is dropped but cannot be caught
- The brick is dropped and is caught
- The directory structure of your git repository should look like
homework2
homework2/
homework2/README.md
homework2/turtle_brick
homework2/turtle_brick_interfaces