RTZ shows how to use a NXT motor as a rotation sensor that always returns to a fixed orientation after being rotated. The technique is pretty useless, but the behavior of the robot is interesting to watch. The technique also shows some interesting and non-obvious aspects of the behavior of the NXT motors.
I wanted to build a vehicle that would be able to sense that it is hitting a wall on the left or right side, back up a little, and turn, to avoid a collition with the wall. David Baum's book shows how to do this with the RCX kits, using two touch sensors. Each sensor is pressed by an antenna-like structure. When one (or both) of the antenna hits the wall, it releases the sensor, and the robot knows that a wall is coming on that side.
The NXT kit only comes with one tough sensor, so I could not use this simple strategy.
I decided to try to use a long rotating bumber that will be mounted horizontally on a vertical axle connected to a NXT motor. If the bumper rotates clockwise, the robot knows that it hit something on the right side. If the bumper rotates counter clockwise, the robot hit something on the left. The robot won't detect frontal collisions with this bumper, since the bumber won't rotate, but we can use the single touch sensor to detect such collisions. The pictures below show the physical structure of the robot.
To be useful, the rotating bumper must return to the original position after it bumps into something. The obvious solution is to use rubber bands to do that. But what I decided to do (mostly because I didn't think of the rubber-band solution) is to use motor action to return the bumper to the original solution. This turned out to be quite challenging.
You may want to try to solve the design challenge in this vehicle before you read how I solved it.
Here is the definition of the challenge. Connect a single motor to the NXT. Put an axle through the motor, and connect a perpendicular axle to the first one. The second axle acts like a hand of a clock: the motor can rotate it around, and when the motor coasts, you can also rotate it. Write a program that will allow you to rorate the hand, but which will return it to the original position every time you rorate it more than, say, 20 degrees. After it returns to the original position, it must be set to "coast", not to "brake", to allow it to sense future rorations.
This movie (3MB) shows how this mechanism should behave.
Solving this challenge will allow us to use the motor as a rotation sensor that springs back to its original position.
The basic structure of the solution is simple:
This should work for returning the motor from, say clockwise rotation. To handle both direction, I used two such sequences, each inside an appropriate switch block (one testing for clockwise rotation and the other for counter clockwise). But let's focus first on the basic idea.
Unfortunately, this simple 4-step solution doesn't work. The first thing that you will notice (especially if you delete step 4 and end the sequence with a motor in the brake state) is that it does not return to the original position. In my experiments, it rotated twice as much as needed. Why does this happen?
It turns out that this happens because the NXT firmware remembers the rotations that the motor performs while in coast mode, and compensates for them in the next rotation that ends with a break. The documentation of the "Reset Motor" block in the NXT-G online help explains this behavior. In our case, the software remembers that we rotated the motor when we used it in sensor mode, and it adds or subtracts these rotations to the number of degrees it is to told to rorate in the motor block. The solution is to insert a "Reset Motor" block just before the Motor block.
Now the motor brakes at exactly the starting orientation. Now we have to set it to coast. When I tried to let it coast directly after the Motor block, it rotated quite a bit even when the second Motor block (the one whose function is just to let the motor coast) was executed. This happened even if I specified 0 time, 0 force, or 0 rotations or degrees.
The reason for this rotation is as follows. Suppose that we tell the motor to rotate 73 degrees (after a Reset Motor block) and brake. The software first rotates the motor until it reaches exactly 73 degrees. Then it applies the breaking mechanism, and moves to execute the next block. The motor still has kinetic energy left, but if the brakes are on, they will ensure that the motor remains in the correct orientation. But if you remove the brakes immediately after the block ends, that kinetic energy will cause the motor to rotate again.
The solution is to wait a bit before releasing the brakes. This allows the braking mechanism to dissipate all the kinetic energy in the motor, so when the brakes are released, the motor stands still. In my experiments, waiting 0.5 seconds was sufficient , but 0.25 was not.
The following My Block shows my solution. We read the rotation sensor, reset the motor, rotate it back and brake it, wait for a second, reset it again, and release the brakes. A similar My block corrects rotations in the other direction.
The complete program is shown next. It resets motor A (the bumper) and enters an infinite loop. In the loop, it starts a forward movement of the vehicle, and then checks the touch sensor. If it is pressed, we just had a frontal collision. We back up and turn a bit (by moving just one of the wheels). Now we check the rotating bumper. If it was rotated more than 7 degrees in a certain direction, we back up, return the bumper to zero (hence the name of the vehicle, Return To Zero), and turn a bit to avoid the wall. If it was not rotated in the first direction but was rotated in the other, we perform a similar sequence.
Here is a video showing the vehicle's behavior (6MB mpeg). The act of returning the bumper to the original orientation is very noticeable.
Using rubber bands would be simpler (and is thus the better engineering solution), but this solution is much more intersting.
© 2006, Sivan Toledo