Wednesday, December 3, 2014

Going Vertical with Differential Steering

In Teaching a Robot How to Dance, an introductory computer science course for high school students, we ask students to program a robot to dance to unknown music and with an unknown robot dance partner. To do this, the robot has to be able to track its dance partner and move accordingly. One of the sub-tasks that we ask students to complete while developing this dance behavior is to first figure out how to program their robot to track and simply follow an infrared (IR) beacon.

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.

Tuesday, December 2, 2014

Teaching a Robot How to Dance: A Case Study

In 2011, I began working with a small team to develop an introductory computer science course for high school students with little prior experience or interest in technology. Daniel and Tim were experts in robotics and software engineering who had come together to design a marine robotics course at M.I.T., and Lee was a professor teaching computer science and doing research in computational biology.

When I joined the group, I suggested that we engage in a backward design process and start by articulating the objectives of the course. While we shared a common desire to encourage more students to pursue careers in STEM, we were all coming at the problem from different directions and operating with different assumptions. To get on the same page as a group, we had to clarify our own thinking as individuals.

We agreed that the focus of the course should be on computational thinking. We wanted students to develop a conceptual foundation and habits of mind that would enable them to apply advanced computation in any field. Daniel and Tim wanted the course to involve robotics, but they didn’t want to focus on mechanical design and programming. They wanted students to experience robotics as a rich and engaging problem space driven by the interaction of hardware, software, and the environment. Finally, it was important for students to drill down to some form of ground truth when engaging in the engineering design process; we wanted them to have to consider and eventually learn about underlying mechanisms: what happens when the wheels in the differential drive system slip, the charge in the battery gets low, or you are limited by the sampling frequency of the sensor data and behavior arbitration system?

Designing a task aligned with our objectives took discipline. We needed a project where students would have to meet our objectives in order to complete the task. It would have been simpler and faster to design a fun and engaging task, and then layer our objectives on top of it, but it also would have been far less effective. After a great deal of thought and brainstorming, we came up with the idea of teaching a robot how to dance. Teaching a robot how to dance isn’t the same as programming a robot to follow a pre-scripted choreography to music. Students needed to figure out how to teach a robot to dance to unknown music and with an unknown robot dance partner, which means detecting the tempo of the music and the position and movement of the robot dance partner, and reacting appropriately. It is the kind of rich, complex problem that would engage and challenge an expert roboticist.

Once the task was defined, I began designing the course, breaking the task into sub-tasks and creating sequences of lessons to develop skills and concepts. I introduced the group to Moodle, a learning management system (LMS). We planned to deliver the course using face-to-face instruction, but we wanted to post assignments and materials online. I also often use threaded discussions to increase accountability, enable students who like to process their thoughts longer or need more wait time to participate more actively, and make it easier to follow up and build on earlier points in the discussion.

The group was impressed with how I developed skills and concepts in a logical and cohesive progression, but they had concerns that students would be unable to progress at the rate that I anticipated. Even though we had agreed that the course would be project-based with a constructivist approach, there was some desire to pull back and spend more time constructing foundational skills before getting to the heart of the project. We decided to test components of the course with small groups of high school students to see how they responded.

We challenged students to program a robot to track and follow an infrared (IR) beacon, which is one of the critical sub-tasks in Teaching a Robot How to Dance. We recorded the second session, and I documented it through a series of videos on the Computing Explorations website. (I also posted a short introductory video on YouTube.) Initially, the two students in the session, Amalia and Ariana, spend more time trying to get through questions than answering them. But later, they begin reasoning things out and using the tools and strategies modeled by Daniel, their guide and instructor. By the end, as their capabilities and understanding have expanded, they are visibly more confident and engaged in the task, and they are even questioning and answering each other.

I enjoyed the development of Teaching a Robot How to Dance on multiple levels:

  • I had the opportunity to immerse myself in a new discipline and to view the world through the eyes of a roboticist.
  • Starting with a blank slate, I was able to take risks and push myself to design innovative curriculum based on constructivist learning principles.
  • We took the time to design a course that was cohesive and fully aligned with our objectives.
  • I learned about new technologies and was able to share what I knew about curriculum design and instruction.
  • By collaborating, we designed a course that none of us could have designed on our own, and we developed common understandings that will impact our thinking moving forward. We also built a level of trust that enabled us to uncover our own assumptions, take risks, and challenge core beliefs.

I believe that this is the kind of process that all educators should be going through in order to develop the curriculum and instruction our students need and deserve.