Today
For Next Time
Thinking back to the first day of class, one way to think of the intelligence that drives a robot is as a sensory-motor loop.
Today, we will kick off a week long project to investigate how we can create sensory-motor loops that can realize intelligent behavior on a robot.
Find another person in the class to work with. In pairs, you will begin to explore the idea of a sensory-motor loop on the Neatos.
In order to get started, create a package for the code that you will be writing today. As with all ROS packages in your workspace, it must be inside of your catkin_ws/src
folder. Besides this requirement, you are free to put the package anywhere, however, I recommend that put it in the root directory of your comprobo17
repository.
$ cd ~/catkin_ws/src/comprobo17
$ catkin_create_pkg in_class_day03 rospy std_msgs geometry_msgs neato_node sensor_msgs
The first sensory-motor loop we will create is one in which the robot moves forward at a fixed speed until it senses an obstacle (using the bump sensor) and then stops. For a rundown of the bump sensors on the Neato, check out the Warmup project page.
Hints:
Call your node something like emergency_stop.py
. Make sure to make it executable and put it inside a scripts
directory in your in_class_day03
ROS package.
The next sensory-motor loop I suggest that you create should be called distance_emergency_stop.py
. This node should be identical to emergency_stop.py
except it should use the laser range finder to detect when an obstacle is within a specified distance and stop if this is the case. It is up to you how you implement this. You can either use just the measurements in front of the robot, or perhaps use all of the measurements. Again, for more detail on using the Neato sensors (including the laser range finder), see the Warmup Project page.
Sometimes you want your robot to switch between multiple behaviors. One very simple architecture for this is to use something called finite-state control. The idea is that your robot can be in one of a finite number of states. Each state prescribes a different pattern of behavior for the robot. The robot transitions between states using various rules.
As an example, let's consider a robot that can be in one of three states:
Each state prescribes a very easy to program behavior. In each case depending on the robot's state we would either drive forward at a fixed velocity, drive backward at a fixed velocity, or rotate left at a fixed velocity.
Let's say that our robot starts in the moving forward
state. We can now define a series of rules for transitioning between the states based on the Neato's sensors.
moving forward
moving backward
rotating left
What would the behavior of this robot be? Do a quick whiteboard based simulation to probe the robot's behavior in various situations. What range of behaviors would the robot exhibit.
With your partner, implement a ROS Python node that realizes this behavior. For the timing related tasks you will want to check out this ROS documentation page.
Thus far we have been using objects and classes (e.g., in the context of interacting with ROS), however, we have not been using object-oriented programming when writing our own ROS code. If you need a refresher on the basics of object-oriented programming in Python, I'm happy to walk through this with interested parties. If you'd rather refresh on your own, consider looking back at the relevant chapters in ThinkPython (15-18), or look at one of the many online tutorials on the subject.
Rewrite at least one of the nodes you wrote today in an object-oriented fashion. Before starting, I recommend brainstorming the various ways that you might design your node. Try to flesh out the pros and cons of different ideas your group comes up with. Once you've settled on a structure, go ahead and translate your node to your new object-oriented design.
Check out the tutorials for the smach ROS package. Use smach to either rewrite your finite state controller to use smach, or devise a new finite-state controller and implement it using smach.