Introduction to Robotics
Team
Simon Opelt (0355763), Philipp Aumayr (0356068), Jürgen Holzleitner (0056645)
Line Following Robot
Construction
Our robot has a 3 wheel design with 2 wheels attached to two motors and one wheel for stabilization. Turning is achieved by running the motors at different rotation speeds. One Light Sensor at the front of the car measuring.
Software
The goal of our robot algorithm is to follow a thick black line on the ground. Since we have only a single light sensor available for this project, we follow the edge of the line instead of the line itself.
At the beginning of the algorithm we try to find the minimum and maximum light levels by turning around a full circle. The 360-degree turn is not measured accurately but based on tested values (This does not have any influence on the rest of the algorithm, since it tries finding the first edge by turning in the other direction). This calibration step is especially important with light sensors as the minimum and maximum gray level values vary from hour to hour.
By averaging the maximum and minimum values we determine the target gray value which should be measured if the sensor is above the left edge of the line (seen from driving direction).
For driving we have two different speed values, one for turning and one for driving a straight line. The light value is measured as often as possible. Depending on the difference between the target gray value and the measured sensor value, we adjust the steering factor accordingly.
Based on the difference we calculate a basis move speed and add / subtract the turn speed which results in different speeds for each motor. The ratio between the move speed and the turn speed is defined by the absolute difference between the measured value and the target value.
All of the speed values are calculated relative to a maximum speed value, which can be adjusted according to the environmental constraints.
Mounting the sensor not immediately above the edge of the line allowed the sensor to see more of the line which made it react more smoothly.
Issues
Slippy floor makes it difficult to drive accurately.
The sensor was mounted too far from the turning axle of the driving wheels, and we therefore got fewer samples than required for optimal steering.
Minimum and maximum (linear interpolation) calculation had to be solved by fixed-point arithmetic.
Conclusio
Even tough we had to fight with these issues we mastered winning the competition far ahead of the rest and could almost keep up with the RCX sets which have the advantage of using two light sensors and a very accurate and powerful chain-drive with lots of grip.
Source Code
path.nxc#include "NXCDefs.h"void RotateLeft();void StopRotating();task main(){ // enable sensor light SetSensorLight(IN_1); int maxlight, minlight; maxlight = 0; minlight = 100; int maxspeed = 75; RotateLeft(); for(int i = 0; i < 210; i++) { int x = Sensor(IN_1); if(x > maxlight) maxlight = x; if(x < minlight) minlight = x; NumOut(0, LCD_LINE1, minlight); NumOut(0, LCD_LINE2, maxlight); Wait(5); } StopRotating(); int nTotalDiff=maxlight-minlight; int target = (minlight + maxlight) / 2; while(true) { int sensval = Sensor(IN_1); long diff = ((target - sensval)*1000)/nTotalDiff; long absDiff=diff; if (absDiff<0) absDiff=-absDiff; int movSpeed = (((500-absDiff)*maxspeed)/500)); int turnSpeed = ((diff*maxspeed)/1000) ; int nSpeedA=( movSpeed - turnSpeed ); int nSpeedC=( movSpeed + turnSpeed ); NumOut(0, LCD_LINE3, nSpeedA); NumOut(0, LCD_LINE4, nSpeedC); NumOut(0, LCD_LINE5, target); NumOut(0, LCD_LINE6, diff); if(nSpeedA > 0) OnRev(OUT_A, nSpeedA); else OnFwd(OUT_A, -nSpeedA); if(nSpeedC > 0) OnRev(OUT_C, nSpeedC); else OnFwd(OUT_C, -nSpeedC); }}void RotateLeft(){ OnFwd(OUT_A, 100); OnRev(OUT_C, 100);}void StopRotating(){ Off(OUT_AC);}
Parallel Parking
Introduction
Our project is about parallel parking a vehicle with a car-like steering mechanism. For this we used the standard NXT parts including an ultra-sonic rangefinder, 3 motors (one for driving, one for steering and one for sweeping the ultra-sound sensor in future development) and a touch sensor to detect the maximum steering amount.
Construction
We started construction by modularizing the problem into two separate parts: The rear section providing the drive system (forward and backward) and the front section responsible for steering left and right.
Beginning with the rear part we immediately recognized a problem. Car-like steering requires differential rotation on the rear-wheels of the car. Fortunately the older RCX development set provided a differential gear and the problem was solved in compact fashion.
Next we focused on the development of the steering mechanism. A typical car steering mechanism rotates the wheels around individual axle bearing points at the center of each wheel. We solved this by using the standard Lego parallel axis steering approach. To enable our steering mechanism to auto-calibrate itself we mounted a touch sensor that gets triggered immediately before the steering would be blocked by the mechanical limit.
We first tried a direct steering by a motor but the stepping resolution was too low and inaccurate to provide sufficiently detailed steering. We then applied a simple gearing to achieve a higher motor-rotation vs. steering ratio.
The next step would have been a direct connection of the rear and the front part, which would have resulted in quite a long vehicle. Thanks to a hint by our instructor, Zoltan Istenes, we came up with a solution where the rear part was mounted vertically instead of horizontally. This reduced the length of the vehicle enormously, making parallel parking easier.
Additionally, the vertical mount of the rear part provided a solid basis for mounting the NXT Brick and stabilizing the vehicle as a whole.
The final task was to place the ultrasonic sensor. A good position for accurate, fail-safe, reliable measurement requires free line of sight, a central position concerning horizontal as well as vertical alignment.
Setting up the working environment
From the lessons learned during the first project, we tried to get Bluetooth reprogramming of the device working. This would have allowed us to reprogram the Brick at the test-site without having to connect the Brick to the Notebook via USB.
While we were not able to get reprogramming working reliably (without having to repair every time, and without crashing the IDE every other time) we have found out the following facts:
Firmware version 1.4 included some patches to the Bluetooth connectivity.
In the BrixCC Root installation folder a file called NXT.dat caches a list of known NXT devices which prevents detection of Bluetooth enabled bricks. Simply deleting the file and restarting the IDE causes BrickCC to rescan and rebuild the file.
In case BrixCC cannot find the device or multiple devices are available, one can specify the MAC address of the device using the following syntax: BTH::NXT::00:16:53:03:3c:71 (BTH::NXT::<MAC>).
Since Bluetooth reprogramming required a firmware upgrade but didn't resolve all issues, we decided to downgrade to firmware version 1.3 due to other bugs found in version 1.4. The first time we tried flashing the firmware using the BrixCC we ended up with a non-responding NXT device. After a first shock, we reset the device and reprogrammed the brick using firmware version 1.3 and Lego's proprietary software in order to continue our time-critical mission.
We also considered using leJOS in combination with the Eclipse IDE development plugin. We found out that the plugin and the leJOS firmware works perfectly with the older RCX brick, but NXT support is still preliminary and under heavy development.
Software
The software we developed for parallel parking our vehicle is separated into 4 distinct parts:
Setup and Calibration
Searching for a parking lot big enough for our car
A fixed parking routine
Staying in track by driving at a fixed distance to the side of the road
Setup and Calibration
At the beginning of our algorithm the steering is calibrated. This is done by turning the steering motor until the steering-touch-sensor is triggered. Then the current motor rotation count is retrieved, and the motor is turned on into the other direction until the touch sensor is triggered again. This gives us the total range of the steering motor without breaking any hardware. To center the wheels we turn again half-way towards the other direction. This has proven to be accurate enough for our purposes.
Issues
Although the algorithm itself is working it has shown to be quite error-prone due to the relative rotation of the car to the wall. The reason for this is that due to the nature of the steering a change in turn has a very long delay until showing an effective change in the measurement. This would have been quite easy to solve by using two ultra-sonic range finders at the front and the rear of the car, revealing the relative rotation of the car to the wall.
The rotation of the car also affects the measurement since the range finder is not always perpendicular to the wall and therefore measures a distance greater than the effective minimum distance to the wall. Measurements made not perpendicular to an object have also shown to be quite inaccurate.
During the development we have found out that the ResetMotorRotation count does not always reliably reset the motor rotation, and we there have to generally measure relative rotation counts. Changing the code was done quickly, but up to that point this bug had caused a lot of collateral damage.