Mechatronics Exercises

Workspace Navigation

RC Car Follower

 

Project overview

The purpose for this project was to build a RC car that could follow an object automatically with a set distance. Idea for this project was originally found from SARTRE Project and from youtube.

Sartre Project is a EU funded project which aims to "encourage a step change in personal transport usage by developing of environmental roadtrains called platoons." These platoons are basically traffic queues where one car operates as a lead car and others can join the queue and thereby drive to the desired destination without the need for the driver to actually drive the car. This project aims to re-produce this functionality in miniature-scale.

The project consisted of three main phases:

  • Prototyping
    • We created a prototyping board to which we attached a servo, electric motor and the ir sensors. This prototyping board was used to make a proof-of-concept for the project.  In this phase we started to implement the code for the step-wise speed control and for the method for reading the ir sensor data.
  • Printed Circuit Board
    • The protoboard (with jumper wires) was causing us problems as the wires came loose and the testing had to be stopped in order to find out what leads were not attached. In the beginning of the project we had also decided to make a PCB in order to get acquainted with the procedure.
  • On-board testing
    • As the PCB was finished, we attached it to the car and started to create the actual program that would provide the needed operations. The first implementation used a step-wise control for the speed; as the front car went further, the follower gained more speed using a hard-coded step-wise logic. This implementation worked ok, but as we had decided earlier, we wanted to use a PID controller for the speed. The PID controller was implemented to the second implementation by using arduino PID library.

Technical description

We evaluated a few different approaches on how the turning and the speed control could be implemented. The options evaluated were:

  • a) Machine vision 
    • Machine vision needs a powerful processor to interpret the data coming from the hardware camera. As we decided to use only micro controllers, this option was dropped in the beginning of the project; there would not be enough room for an actual computer on board.
  • b) Ultrasonic sensors 
    • Ultrasonic sensors use sound to calculate distance from an object by measuring the time the signal takes to bounce back from an object. Ultrasonic sensor's beam is quite wide and thereby sensors that are attached near to each other can interpret the signal coming from another sensor. As the application needed more point-like measurements of distances we decided not to use ultrasonic sensors.
  • c) Color coding (gray scale)
    • Color coding was the original idea for us, but as we looked into the existing sensors, we noticed that the operation of the sensor is strongly affected by the amount of light available. Because we wanted to have reliable operation in many different environments, this option was dropped.
  • d) Infrared sensors.
    • Infrared sensors use a point-like infrared beam. The distance value is calculated from the reflection angle by using a fairly simple triangulation method. As the sensors are quite inexpensive and fairly reliable, we decided to purchase three Sharp IR sensors and implement the application using them.

We decided to build the application so that all of the components could be placed on-board. This decision limited the physical size of the components and thereby we decided to use arduino prototyping board and an own-made printed circuit board (PCB) to implement the project.

Mechanical components 

Both front car and follower car were working RC-cars so we just had to do some small improvements and changes to get them working for our purpose.

  • Front car holder for paper sheet in back of car made from aluminum parts taken from K3 mechanical design lab junk metal.

  • An additional weight was mounted in the front car in order to not let it accelerate too fast and to avoid spinning of driving wheels. This additional weight was removed later when it seemed not to be good for the car engine durability. The metal parts for the additional weight and mounting were taken from K3 mechanical design lab junk metal.

  • Follower car stands for IR-sensors in front and back of car made from aluminum parts taken from K3 mechanical design lab junk metal. Stand in front of car was painted blue using a permanent marker.

  • Plastic cover for follower car taken from front car. The cover did not fit on the front car anymore after mounting on the paper sheet holder so we decided to put in on the follower car to make it look better.

Electrical components

Infra red sensors are capable of measuring the distance from 20 to 150 cm. There is a "blank spot" in the beginning of the measuring area that is caused by the way the distance is transformed to voltages. Typical sensor transformation graph is shown in the picture below. From the picture one can notice that the low distances (0...20cm) have the same values as the real (usable) measurements from the linear part of the graph.

Because of the infra red sensors cannot measure distances below 20cm, we decided to place one of the sensors (distance sensor) to the back of the car and thereby eliminating the sensor's "dead spot"; the length of the car removes this blank spot as the sensor is placed to the back of the car.

PCB is done so that the arduino board can be placed on top of it. As the arduino board's connectors are on the other side, it is placed on top of the PCB so that the board's faceplate is facing the PCB. This means that also the arduino's reset button is facing the PCB and therefore we had to implement an external reset button to the PCB.

Software

The programming was done with arduino enviroment. The control is based on arduino built-in libraries.         

 

Steering is made possible by determining the distance difference (ΔL) of the reflection sheet of the front car when it is turning. The distance to the front car is measured with two IR-sensor on both sides of the follower car. By calculating the distance difference between left and right side IR-sensors readings the adequate steering command is calculated. The measurements of the sensors are read on every cycle of the program and an average of last two measurements is calculated to smooth the tuning command on the steering servo.

The IR-sensor on the back of the car is responsible of the speed control of the car. The distance between target and the car is measured also on every cycle of the program and with PID controllor the speed command is calculated to keep the distance constant.

 

Components and budget

ComponentDescriptionQuantityPrice/ itemTotal (incl. shipping)

IR-sensor

Sharp GP2Y0A02YK0F315,00€48,95€
Micro-controllerArduino duemilanove1(23,00€)borrowed from Mechatronics lab
leader RC-carNikko1-owned by project member
follower RC-carS10 Twister Buggy1(164,70€)borrowed from Mechatronics lab
PCBMade in Mechatronics lab by team members1-

components from Mechatronics lab

Batteries9V for micro-controller21,5€3€
The restWiring,electronic and mechanical componentsxx-from Mechatronics lab
 Total budget
  51,95€

 

User manual

The follower car uses a standard, automatically calibrated ESC (electronic speed controller) which needs for the calibration receive a neutral signal first and then signal for going forward. The automatic calibration caused us some problems as we didn't notice this calibration method in the beginning of the project; values set for the speed control changed during the testing as the ESC battery was taken out.

In order to operate the car:

  1. Detach the 7,2V battery from the ESC and let it be for approx 10 seconds. Steering servo will not work at this point.
  2. Attach the 9V battery to the arduino using the power socket on arduino board.
  3. Place the car so that there is no object in front of the car (IR sensors see "blank")
  4. Attach the 7,2V battery to the ESC and turn the ESC power switch to "ON". Steering servo will go to the middle position.
  5. Place an object 30 cm front of the follower car, the car should not move at this point
  6. Move the object further from the follower car. This should cause the follower car to move forward, if not, start again from step 1.

As the calibration is finished, the follower car follows the object in front of it.

Conclusions and suggestions

The project managed to overall achieve it's goals, which were set in the beginning of the project. The project finished on time and followed quite decently the timetable created in the beginning of the project. Also every planned task for the project was finished.

To improve next time:
  • Current implementation does not hold in any method for going reverse. This feature was not implemented deliberately as we wanted to save the motor. We feared that the rapid change of direction could break the motor or the differential gear. Now, as we have a better knowledge on the RC motors, this feature could be implemented by utilizing the brake functionality in the ESC. This feature could also improve the distance for being constant.
  • There is an option to add two more IR sensor to each side of the follower car so that they are facing in the right-front and left-front directions. This improvement could provide a better control for the steering in tight corners as these sensors could be used as a "back up". This way the follower car would not lose sight of the front car as easy and it could continue to operate until also the side facing sensors lost their sight.
    • Other way to implement this functionality without new sensors is to implement a timer for the "blind operation"; when all sensors lose their sight on the front car, a timer will start to repeat the last speed & turning command until a set period has passed or one of the sensors will gain sight of the front car again.
  • PCB could be improved by adding LEDs to show the status of the battery.

Attachments

Other attachements:

Project web page

First implementation (without PID controller):

Second implementation (with PID control)

In Car view

 

Code

Rc Car Follower Arduino code
//
// Control program of the RC-car follower
// 
// *************************************************************************
// 
//    Authors:
//    
//    Evgeni Tjurnev (ET)
//	  Jan Liljeström (JL)
//    Teemu Niippa	 (TN)
//
// *************************************************************************
// 
//    Revision history:
//
// REV   DATE       	 AUTHOR    COMMENT
// ===   ======     	 =======   =======
// 1.0	 1-April-2013    TN  	   First Revision 
// 1.1	 15-April-2013   ET        Speed Control PID implementation 
// 1.2	 23-April-2013   ET        Improvements to steering control
//
// *************************************************************************
//

#include <Servo.h>
#include <stdio.h>
#include <PID_v1.h>
#define SteeringCenter 1600 //Steering servo's center position
#define fullStop 1500  //DC motor stop value
//************************************************************//
//INITIALIZATION
//steering servo range: 1300 (full left) 1600 (center) 1900 (full right)
Servo motor;
Servo steering;
int pinIrLeft = A4;
int pinIrRight = A5;
int pinIrDistance = A3;
float RightValue = 30;
float LeftValue = 30;
int SteeringValue = 0;
double idist, odist, sdist;
double idistOld = 0;
const int numReadings = 2;			//HOW MANY MEASUREMENTS IS USED IN AVERAGE CALCULATION
int readings[2 * numReadings];
int index = 0;
int Ltotal = 0; // uses readings list indexes from 0 to numreadings
int Rtotal = 0; // uses readings list indexes from numreadings - 2*numreadings

//Specify the links and initial tuning parameters
PID distPID(&idist, &odist, &sdist, 35.0, 20.0, 2.0, REVERSE); //Ku=4.0

//************************************************************//
//SETUP
void setup(){
  
  //initialization of dc motor (ESC) and steering servo
  motor.attach(9);
  steering.attach(11);
  
  //initialization of the ir sensors
  pinMode(pinIrLeft, INPUT);
  pinMode(pinIrRight, INPUT);
  pinMode(pinIrDistance, INPUT);
  
  //Set initial position for motor and steering servo
  motor.writeMicroseconds(fullStop);
  steering.writeMicroseconds(SteeringCenter);
  
  //initialize the variables we're linked to
  idist = 10650.08 * pow(analogRead(pinIrDistance), -0.935) - 10;
  sdist = 45;
  
  //turn the PID on
  distPID.SetMode(AUTOMATIC);
  distPID.SetOutputLimits(30, 900); 
  
  
  //debugging
  Serial.begin(9600);
  Serial.print("Starting\n");
}
//************************************************************//
//MAIN LOOP
void loop(){
  RestartLoop:
  
 
  //READING ANALOG VALUES
  float RightRead = 10650.08 * pow(analogRead(pinIrRight), -0.935) - 10;
  float LeftRead = 10650.08 * pow(analogRead(pinIrLeft), -0.935) - 10;
  float DistanceValue = 10650.08 * pow(analogRead(pinIrDistance), -0.935) - 10;
  
  //STEERING SENSORS MAX MEASUREMENT VALUE CUTOFF 
  if (RightRead > 150)
  {
    RightRead = 150;
  }
  if (LeftRead > 150)
  {
    LeftRead = 150;
  }
  //CALCULATING MEASUREMENT AVERAGE OF LAST numReadings MEASUREMENTS FOR STEERING
  
  //Remove oldest measurement from total sum of measurements
  Ltotal = Ltotal - readings[index];
  Rtotal = Rtotal - readings[index + numReadings];
  //Replace oldest measurement
  readings[index] = LeftRead;
  readings[index + numReadings] = RightRead;
  //New total sum of measurements
  Ltotal = Ltotal + readings[index];
  Rtotal = Rtotal + readings[index + numReadings];
  //Next index and rollback at the end of the list
  index++;
  if (!(index % numReadings)) {index = 0;}
  //Average values of measurements
  LeftValue = Ltotal / numReadings;
  RightValue = Rtotal / numReadings;
 
  //CALCULATING STEERINGVALUE
  if (LeftRead > 55 && RightRead > 55)  //When at distance turn wheels to center
  {
    SteeringValue = 0;
  }
  else
  {
    SteeringValue = (RightValue - LeftValue) * 70 * (40 / (RightValue + LeftValue)); 
  }
    
 
 // GUARDS FOR STEERING SERVO OPERATION
  if (SteeringValue > 300)
    SteeringValue = 300;
  else if (SteeringValue < -300)
    SteeringValue = -300;
  
  steering.writeMicroseconds(SteeringCenter - SteeringValue);
  
  //SPEED CONTROL
  
  idistOld = idist;
  idist = 10650.08 * pow(analogRead(pinIrDistance), -0.935) - 10;
  distPID.Compute();
  // MIDDLE IR LOST TRACK OF THE CAR
  if ( ((idist + idistOld) / 2) > 100)
  {
	// SIDE IR IS STILL TRACKING THE CAR
	if ( abs(SteeringValue) == 300)
	{
		//slow forward
		motor.writeMicroseconds(fullStop + 70);
		Serial.print("SlowTurn\n");
		goto RestartLoop;
	}
    Serial.print("LoopReset\n");
    motor.writeMicroseconds(fullStop);
    goto RestartLoop;
  }
  // NORMAL PID CONTROLLED FORWARD DRIVING
  motor.writeMicroseconds(fullStop + odist * 0.09);
  
  Serial.print(odist);
  Serial.print("\n");
}

 

Circuit diagram

1 Comment

  1. Hello,


    I am interested in this car and its mechanics but I am not sure how to rebuild it. Having trouble in understanding the code and how to build the car together.

    It would be nice if you could help me with it.

    Please send a mail to caesarmathias@gmail.com

  • No labels
  File Modified
PNG File image2013-5-20 18:0:31.png May 20, 2013 by Teemu Niippa
PNG File ir_sensor_value_graph.png May 15, 2013 by Teemu Niippa
Microsoft Excel Spreadsheet Liite1_ProjektiAikataulu.xlsx May 20, 2013 by Teemu Niippa
PDF File PCB.pdf May 15, 2013 by Teemu Niippa
JPEG File Photo 17.4.2013 11.54.04.jpg May 15, 2013 by Teemu Niippa
JPEG File Photo 17.4.2013 15.11.34.jpg May 15, 2013 by Teemu Niippa
Microsoft Word Document Projektisuunnitelma_RC_CAR_FOLLOWER.docx May 20, 2013 by Teemu Niippa
PDF File RcCarPCB_schema.pdf May 15, 2013 by Teemu Niippa
PDF File RcCarPoster.pdf May 15, 2013 by Teemu Niippa
PNG File TurningAngleCalculation.PNG May 20, 2013 by Teemu Niippa