Last post I introduced Agilis, and I discussed the calculations needed for driving the motors and for doing odometry. This time I’ll discuss how it moves. But first, let us take a look at a video.

In the video we see that Agilis can make some amazing movements. It circles around while facing in one direction for example. It’s movements are not constraint in heading nor in direction, it can make any movement. This makes Agilis a holonomic robot. Any movement a holonomic robot can possibly make, can be described as a combination of two functions. One function describes the robots location (X and Y coordinates) in time. The second describes its heading (H) in time. The two functions together give the robots pose at a given moment.

For the above example the function for location is
```x=cos(t)*radius; Y=sin(t)*radius;```
`h=aConstantValue`

As I discussed in my previous post, Agilis accepts a speed vector {x,y,h} as input for its drive system. The speed vector is the derivative of pose. So we need to use the derivative of the above functions if we want to use these to make Agilis move. This might sound complicated, but what it means is that we need functions that give a speed at moment in time. For our example these functions are

``` x=-sin(t)*radius; Y=cos(t)*radius; ```
The function for h is
`h=0`

There are two important remarks to the above.
First, it seems arbitrary to say that x and y are bundled together in one function and h is calculated in another function. This is for a good reason, it is how we think. We think of a robot driving in circles, this is x and y together. We think of a robot facing north. Also, if we have to independent functions in the program than we can make very interesting combinations of location and heading functions.
Second, you might wonder why I discussed the two forms of the formulas. Well, in most cases it is best to use the speed (or derivative) form of a function. In some cases though, there is no (obvious) derivate of a function. This is especially the case when a function relates to the outside world. An example of this would be a function that makes the robot “look” at a fixed point in space, no matter where it is going. That leaves us with a problem though. If there is no derivative of a function, how do you get a speed from such a function? The way to go is to calculate the difference between the desired position or heading and the actual position or heading and then to translate this difference into speed. I use a PID controller to make this translation.

This brings me to the way this is implemented for Agilis. In the code I created a pilot. This pilot is responsible for performing movements. It must be instructed which movements to make so it can execute them. While executing a movement the pilot periodically queries the two movements for the desired speed and location. If it is a location that the movement returns then pilot translates this into speed using the PID controller. It then transforms this speed vector from a global coordinate system into the local coordinate system of the robot and then passes the speed vector on to the chassis. The chassis is a logical part in my program that should be envisioned just below the pilot. It accepts a speed vector, translates this to speed of the motors and then drives the motors.

The pilot handles two functions in parallel, one for location and one for heading. Each of the functions can return either speed or location. In any combination. A function can have an end to it, like go straight for one meter. But this is not obliged, like keep facing north.

I have implemented or planned these functions for location.

• stand still
• drive a straight line
• drive an arc

I have implemented or planned these functions for heading.

• rotate
• hold still
• look to a fixed direction
• look around (from left to right and back and so on)
• look where you’re going

This is basically all there is to it. This program allows Agilis to perform all the movements you see in the video. But as you can notice the transition from one movement to another isn’t smooth yet. I plan to make it smooth with a technique I call maneuver blending. What it should do is to blend two maneuvers so that a transition between the two appears to be natural. As said, I haven’t programmed this jet. If I succeed I will dedicate a post to it. If not, it is most unlikely that i’ll write about it š