The robot in Teaching a Robot How to Dance uses differential steering. It has two wheels, one on the left and the other on the right. To move forward, you program the two wheels to rotate at the same velocity. To turn to the right, you program the left wheel to rotate at a greater velocity than the right wheel. In this video, Daniel (the instructor) explains how the drive system on the robot works:
And in this video, Amalia and Ariana (the two high school students) figure out how to use the drive system to turn the robot to the right:
Altogether, it takes less than a minute for Amalia and Ariana to understand differential steering well enough to complete the task of programming a robot to track and follow an IR beacon. By the end of the session, they are comfortably adjusting wheel velocities as they improve their design.
When we first started working on Teaching a Robot How to Dance, we had a number of discussions about how the students would drive the robot. In most introductory robotics courses, students program the robot to “move forward” or “turn right,” where “turn right” is a pre-programmed subroutine that turns the robot in place 90˚ clockwise. When Daniel worked at iRobot, they developed an application programming interface (API) for driving the Roomba using subroutines that drove the Roomba in arcs.
An API is helpful because it is much easier to think in terms of angles and distances when driving a robot than left and right wheel velocities. But for Teaching a Robot How to Dance, we wanted to stress that the robot is essentially sensors and actuators, with behaviors linking those sensors and actuators. In this case, the wheels on the robot are the actuators, and we did not want to abstract that away.
Once we agreed that students would drive the robot by setting left and right wheel velocities, we started to discuss how to build differential steering into the curriculum. I did not want to spend a couple of days focused on differential steering, asking students to just drive their robots around. Since this was a project-based course, I wanted to dump the students into the deep end and have them start working on complex behaviors, such as follow-the-leader, right away. I felt that differential steering was something that students could learn just-in-time as needed.
Now, Amalia and Ariana only scratched the surface of differential steering. Their robot might be rolling forward at 200 mm/s when it suddenly needs to turn to the right. When that happens, the left wheel continues moving forward at 200 mm/s, but the right wheel is thrown abruptly into reverse, moving at -200 mm/s. The robot basically comes to a full stop in order to turn in place… and the transition between moving forward and turning can easily happen dozens of times a second. That might be acceptable for follow-the-leader behavior, but it doesn’t look very smooth for a dance partner.
At some point, students are going to want to program smoother and more complex movements into their dance steps, and they aren’t going to want to do it by setting wheel velocities. When that happens, the students will begin designing their own API for driving the robot, and the design of that API will be informed by the kind of movements they want their robot to do.
Imagine that we want our robot to have a dance step where it spins 360˚ in place. If that spin move happens in four beats, it needs to be programmed so that the speed of the robot adapts to the tempo of the music. If our robot’s dance partner moves away in the middle of the spin, our robot may want to drift slowly in the same direction while spinning instead of spinning in place. And if the dance partner gets too far away, our robot may want to break out of the spin after one, two, or three beats, and transition to a different dance move that will close the gap between it and its dance partner a little faster.
By the end of the course, the drive system of the robot would consist of multiple layers of software and hardware, and we wanted the students to design as many of those layers as possible. Sitting above the wheels, there would be an API for setting wheel velocities that we would provide. Sitting on top of that, there would be an API for driving the robot that would be designed by the student. This basic driving API would then be used by the student to program the robot with a repertoire of dance steps, and the design of the API would be informed by the kind of dance steps the student wanted to implement, and it would be redesigned as needed. Each dance step would share a common interface so that the robot could select and use dance steps interchangeably, and there would be a layer for choosing which dance steps to take. Ultimately, there could even be layers for learning which dance steps are better for a given piece of dance music or dance partner, or for tweaking parameters in the dance steps. Sitting below the wheel velocity API, there could be a layer for dealing with wheel slippage. If the wheels are set to rotate at 200 mm/s but they are slipping on the dance floor, the robot’s dance steps might be thrown off.
A key feature of Teaching a Robot How to Dance is that students are constructing and then climbing up and down their own abstraction ladders. You don’t want to have to think in terms of wheel velocities when designing dance steps, so you build an abstraction layer on top of that. You don’t want to have to think about custom interfaces for each dance step, so you modularize them and add another abstraction layer. The more well-designed the abstraction layer, the easier it is to build on top of it and make your own life easier. Are you running into some unexpected behavior in an edge case? You may want to drill down to a lower abstraction layer to see what is really happening. This design encourages students to apply and appreciate computational thinking.
Differential steering represents a tiny fraction of the content in Teaching a Robot How to Dance, but we had to make dozens of design decisions on how to implement it in the course. The decisions we made are highly case-specific; we would have designed things differently if we were implementing differential steering in a different context. But constructing and then climbing abstraction ladders is something that I am passionate about, and it is part of what I mean when I talk about vertical learning. This is something that all kids (and adults) can and should be doing.