Class Meeting 2: Sensory-Motor Control, ROS Recap, and an Introduction to Gazebo


Today's Class Meeting



What You'll Need for Today's Class



Sensory-Motor Control and PID Control


The content in this section summarizes the main points covered in today's lecture.

One foundational concept in robotics is sensory-motor loops and control. The robot's sensor readings inform how it moves in its environment, which will then influence the next sensor readings from the robot, and the loop goes on. One of the most well known sensory-motor control methods is PID (Proportional Integral Derivative) control, which is depicted in the block diagram below:

PID control

A block diagram of a PID controller in a feedback loop. Source: Wikipedia.

The PID control function can be represented as follows:

\( u_t = K_P \cdot e(t) + K_I \cdot \int_0^1 e(\tau)d\tau + K_D \cdot \frac{d}{dt} e(t) \)

Where KP, KI, and KD, are the constant coefficients for the proportional, integral, and derivative terms; e(t) represents the difference between the goal (setpoint) and the sensor measurement (process variable). The three following graphs display how a system responds to a step change in the setpoint to each component of the PID controller separately and all the components combined at different values of KP, KI, and KD.

Proportional control

Response of the process variable to a step change of the setpoint for different values of KP. Source: Wikipedia.

Integral control

Response of the process variable to a step change of the setpoint for different values of KI. Source: Wikipedia.

Derivative control

Response of the process variable to a step change of the setpoint for different values of KD. Source: Wikipedia.

This YouTube video by Brian Douglas is a great resource providing a clear explanation of the PID controller.

Looking Ahead


In our next lab, you'll have the opportunity to implement proportional control on the turtlebots by programming them to follow a line on the floor.


Gazebo Simulator Initial Instructions and Overview of Class Exercises


For these class exercises, please work alongside one partner. Each of you will work individually on your own computers, but feel free to communicate and collaborate with your partner as you work.

Today, we will be completing the same exercises you did in Lab A, but this time, we'll be doing it in simulation. You'll learn:

Feel free to use the Gazebo simulator when working on your projects throughout the quarter. Often using Gazebo can be more convenient than physically coming to CSIL, so feel free to use that to your advantage. However, please note that your final project deliverables must be run on the physical Turtlebot3.


Class Exercise #1: Turtlebot3 Spinning in Circles - in Simulation


In this exercise, you will recreate the spin in circles exercise from Lab A in the Gazebo simulator.

Setting the ROS_MASTER_URI and ROS_HOSTNAME


When you are planning to use Gazebo and are not planning to connect with a physical turtlebot you'll need to make sure that your ROS_MASTER_URI and ROS_HOSTNAME environment variables are set to http://localhost:11311 and localhost respectively. This will ensure that the ROS environment you are launching is independent of whatever network you are connected to, and will enable you to use Gazebo on a different network than intro-robo, enabling you to program the turtlebot from home or on uchicago-secure.

Starting the Gazebo Simulator


Bring up an empty world in the Gazebo simulator. Run:

$ roscore
and, in a second terminal, run:
$ roslaunch turtlebot3_gazebo turtlebot3_empty_world.launch

You should now see a virtual Turtlebot3 in an empty room, as pictured below.

empty Gazebo world
Note: You can launch the robot in many pre-built simulated worlds. To see a list of worlds, type in
$ roslaunch turtlebot3_gazebo turtlebot3_
and double tap tab, which should offer you a list of possible launch files that will load different simulated worlds. For instance, if we use the turtlebot3_gazebo_house.launch launch file, you will some terminal output and a visualization like the following will pop up.
Screenshot of a turtlebot3 waffle within house. Includes gazebo interface.

Now run:

$ rostopic list
You should see all of the same ROS topics listed here that you would see after running bringup on the physical Turtlebot3.

Run Your Spin in Circles Code


Now, let's get that simulated turtlebot moving! You'll run the same spin in circles code you developed in lab A:

$ rosrun lab_a_spin_circles spin_in_circles.py

You should see the turtlebot spinning in circles now!

spin circles

As you can see here, that aren't too many differences between running your code on the simulated versus physical turtlebot:

We'll get more into the details of the ROS launch file contents in the next exercise.


Class Exercise #2: Turtlebot3 Stopping in Front of a Wall in a Custom Gazebo World


In this exercise, you will recreate the stop in front of a wall exercise from Lab A in the Gazebo simulator. This will involve building a new Gazebo world, saving it, loading it from a launch file, and running your code to have the robot move to and stop in front of a wall.

Setup


To start out today's class exercise, we'll create a new ROS package:

$ cd ~/catkin_ws/src/intro_robo
$ catkin_create_pkg class_meeting_02_custom_gazebo_world rospy std_msgs geometry_msgs sensor_msgs
$ cd ~/catkin_ws && catkin_make
$ source devel/setup.bash

Just to keep everything organized, we'll want to create directories called launch and worlds within the class_meeting_02_custom_gazebo_world directory:

~/catkin_ws/src/intro_robo/class_meeting_02_custom_gazebo_world/launch
~/catkin_ws/src/intro_robo/class_meeting_02_custom_gazebo_world/worlds

Building & Saving a New Gazebo World


Your first objective is to build a new Gazebo world. We'll use the building editor to create an enclosed room (that's the only constraint we'll ask you to follow) - anything else you want to add is up to you!

Please start up Gazebo (run gazebo in a new terminal) and utilize the building editor (here's a helpful page detailing how to use the building editor) to build your own custom Gazebo world. You can see what using the building editor should look like in the gif below.

Gazebo building editor

Once you've finished creating your enclosed room (in whatever shape and texture you like):

  1. Save your enclosed room model by clicking on File/Save (you can name it whatever you like)
  2. Exit the building editor - File/Exit Building Editor
  3. Save your Gazebo world by clicking on File/Save World As. You can name it whatever you like as long as:
    • You don't include any whitespaces in your world filename
    • You use the .world file extension
    • You put it within the ~/catkin_ws/src/intro_robo/class_meeting_02_custom_gazebo_world/worlds directory
  4. Exit Gazebo (Ctrl+C in the terminal where you ran gazebo)

Incorporating Your New Gazebo World into a New ROS Lauchfile


What we want to do next is start up a world file that has our Turtlebot3 within it, so we can run our stop_at_wall.py code. We'll do this by building a roslaunch file. roslaunch is a tool that easily enables you to launch multiple ROS nodes from the same terminal and also set various parameters.

Copy and paste the following code and put it in a file named turtlebot3_in_enclosed_room.launch within the ~/catkin_ws/src/intro_robo/class_meeting_02_custom_gazebo_world/launch directory. The one edit you'll want to make to this file is replacing your_gazebo_world_name.world with the name of the world file you saved in the last step.

<launch>
      <arg name="model" default="$(env TURTLEBOT3_MODEL)" doc="model type [burger, waffle, waffle_pi]"/>
      <arg name="x_pos" default="0.0"/>
      <arg name="y_pos" default="0.0"/>
      <arg name="z_pos" default="0.0"/>

      <include file="$(find gazebo_ros)/launch/empty_world.launch">
        <arg name="world_name" value="$(find class_meeting_02_custom_gazebo_world)/worlds/your_gazebo_world_name.world"/>
        <arg name="paused" value="false"/>
        <arg name="use_sim_time" value="true"/>
        <arg name="gui" value="true"/>
        <arg name="headless" value="false"/>
        <arg name="debug" value="false"/>
      </include>

      <param name="robot_description" command="$(find xacro)/xacro --inorder $(find turtlebot3_description)/urdf/turtlebot3_$(arg model).urdf.xacro"/>

      <node pkg="gazebo_ros" type="spawn_model" name="spawn_urdf" args="-urdf -model turtlebot3_$(arg model) -x $(arg x_pos) -y $(arg y_pos) -z $(arg z_pos) -param robot_description"/>

    </launch>

Now we'll go through each part of this roslaunch file to understand what's going on:

Note: Let's say that you write a Python script my_ros_node.py within the class_meeting_02_custom_gazebo_world ROS package and you want to add it to your launchfile. You would add the following line to your launchfile:
<node pkg="class_meeting_02_custom_gazebo_world" type="my_ros_node" name="my_ros_node_1"/>
While the pkg and type fields are specific to the ROS package and Python script you want to run, the name field can be anything you want (as long as no other ROS node running on the same network has the same name).

Now after all that, run your turtlebot3_in_enclosed_room.launch ROS launch file:

roslaunch class_meeting_02_custom_gazebo_world turtlebot3_in_enclosed_room.launch
Your turtlebot should now be located within the enclosed room you made within the Gazebo simulator.

Running Your Stop at Wall Code


Now that you have your turtlebot on and running in your enclosed Gazebo room, let's run your stop_at_wall.py code. You can either run:

$ rosrun lab_a_stop_at_wall stop_at_wall.py
or add a line to your turtlebot3_in_enclosed_room.launch file, where the:
<node pkg="my_ros_package" type="my_ros_node" name="my_ros_node_1"/>

Depending on how you implemented your algorithm, you may find that the simulated robot does not exhibit the same behavior as the physical one. Unlike the physical robot, which reports ranges where nothing is detected as having distances of 0, the simulated robot will instead report ranges of infinity. This is just one example of how running your code in Gazebo can produce different results, so it's usually a good idea to make your algorithm robust to both platforms.

Once you've taken the new LiDAR measurements into account, you should now see your robot stop in front of one of the walls in your enclosed room.

stop at wall

Once you've finished getting your simulated turtlebot to spin in circles and stop in front of a wall in your Gazebo world with an enclosed room, you are free to either: