UP | HOME

Homework 2

Logistics

  1. Create a git repository using the link provided in Canvas.
  2. Your homework will be submitted via this git repository.
  3. I will grade whatever is on the main branch when I clone the repository.
  4. 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
  5. In general, you should refer to ROS entities using relative names from within your nodes (i.e., no leading "/")
  6. All python launchfiles written for this assignment should use a declarative style:
  7. 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

  1. turtle_brick (an ament_python package)
  2. turtle_brick_interfaces (for any custom interfaces that must be defined)

Hints

Here are some general hints for this assignment:

  1. Familiarize yourself with the overall problem by reading the homework description.
  2. 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.
  3. Slowly introduce node functionality over time.
  4. Write launchfiles early in the process. Use these launchfiles to make testing nodes easier.

Frames

The following coordinate frames will be used:

  1. world. This is the fixed frame, representing the location of entities in the world
    • All other frames are descendants of world
  2. 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 from world and represents the initial location of the turtle.
  3. brick. This frame is the location of the brick
  4. base_link. This frame is the base location of the robot
    • The base_link has other child frames, as defined by the robot's urdf file

The Robot

  1. The turtle robot has the same kinematics as the turtlesim
  2. 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 the base_link, so that it may rotate fully without colliding with the base link.
      • A fixed cylindrical link should connect the base_link to the platform
    • A stem is a cylindrical link that turns about the vertical z-axis and is below the base_link
    • A wheel is connected to the stem and can roll as the robot moves
    • Each link should be a different color.
  3. 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).
  4. The .urdf.xacro file for the robot should be in urdf/turtle.urdf.xacro
  5. The visual and collision components can be the same. The inertial components can be omitted because we are only using this model kinematically.
hw2_robot.png
Figure 1: A picture of the robot. Your robot should use different colors and sizes

The Arena

  1. The arena should be depicted in rviz2, with rectangular walls (drawn as markers) denoting its boundary
  2. 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

Configuration

  1. A configuration file called config/turtle.yaml should include
    • The platform_height of the robot's platform 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.
  2. 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 different platform_height or wheel_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.

Visualizing the Robot

  1. Write a launchfile called show_turtle.launch.{py,xml} that displays the turtle robot (as defined by turtle.urdf.xacro) in rviz
    • The launchfile argument use_jsp controls the behavior of the joint_state_publisher
      • If use_jsp is gui then the joint_state_publisher_gui is used to publish joint states (the default)
      • If use_jsp is jsp then the joint_state_publisher is used to publish joint states
      • If use_jsp is none then no nodes that publish joint_states are started by the launchfile
      • Document the arguments that the documentation shows up when using ros2 launch -s
    • The launchfile argument rviz_config contains the name of the rviz 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

Turtle Node

  1. A node called turtle_robot serves as a bridge between the turtlesim and actual ros 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 the odom frame
    • Publishing nav_msgs/Odometry message on the odom topic (covariance can be ignored, twist can be a direct copy of the latest cmd_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), so cmd_vel commands may include a y component.
      • The turtlesim can be made holonomic by setting the appropriate parameter.
    • Subscribing to a goal_pose topic of the geometry_msgs/msg/PoseStamped message type.
      • When the node receives this message it starts driving the robot toward the goal pose using cmd_vel messages
    • Subscribing to a tilt message (of custom type turtle_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.
  2. Write a launchfile called run_turtle.launch.{py,xml} that
    • Starts the turtlesim node (with holonomic set to True)
    • Starts the turtle_robot node
    • Includes show_turtle.launch.{py,xml} as appropriate to draw the turtle robot in rviz
      • 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.

Physics Module

  1. A module called physics.py should contain ROS-independent code to keep track of the physics of the environment.
  2. 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

  1. 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 in rviz
    • Offer a service called place (of custom type turtle_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.
    • The node should simulate the physics at 250 Hz
  2. The node should use the physics module to perform all calculations.

Control Node

  1. 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 and platform_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.
  2. 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

Testing

  1. Your code should pass all the standard tests that are run with colcon test
  2. Write at least one pytest unit test for each of the (required) members of the physics.World class
  3. Write a test launchfile called test_brick_launch.py that verifies that the turtle_robot node publishes cmd_vel commands at 100 Hz
  4. 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}
  1. You should capture of each of the following scenarios
    1. The brick is dropped but cannot be caught
    2. The brick is dropped and is caught
  2. The directory structure of your git repository should look like
    • homework2
    • homework2/
    • homework2/README.md
    • homework2/turtle_brick
    • homework2/turtle_brick_interfaces

Author: Matthew Elwin.