Project 3: Trailer Control

Documentation (description, images, video, code, etc) due to website by Wed (2/7) at 9pm

Blackboard pictures from class:

Using the Gyro: be sure to check out this help for reading and resetting the gyro sensor.

Trailer Control

Our robot has two front wheels driven by two motors and an omnidirectional wheel at the back of the robot body for easy turning. A trailer with a gyro-sensor is attached to the back. The trailer was placed far away from the motors to allow the motors to correct the direction of the trailer more quickly. The motor speeds of the two front wheels were adjusted with a proportional control.

Driving in a straight line:

The robot drives forward for a few seconds to straighten out the trailer and calibrate the gyro-sensor before backing up in a straight line. The trailer was tapped and kicked off course to demonstrate how the robot can adjust.

Code for reversing in a straight line:

Backing up in a circle:

We programmed our robot to drive backward in a small circle in an angle of 40 degrees and a large circle with an angle of 10 degrees. Once again, we programmed our robot to drive forward to calibrate the gyro-sensors before it starts circling. The ratio between the speeds of the two wheels needed to move at a certain angle was calculated and used as the motor speeds for when the angle error equaled zero. From there, the motor speeds were adjusted with a proportional control.

Code - Backing Up in a Circle

The Design

Project 3 involved designing a system that would allow a "semi truck" with a trailer attached to drive in reverse without jackknifing. The first step was putting together the Lego hardware in a way that would optimize the build for this challenge. We used two large motors for the left and right front wheel power and we put them relatively close together in an effort to keep the turning radius small. We mounted the truck's sensor directly on top of the wheels facing backwards so that there would be as little friction as possible from the cable. We used a roller ball instead of rear wheels for the truck so that there would be less friction with the ground as the vehicle turned.

Because of the placement of our ev3, the truck body had to be somewhat longer than we would have liked. This proved to be a slight problem when it was time to attempt challenge 2--the extra truck length meant we were limited in how small of a turning radius the vehicle could manuever.

Challenge 1: Straight Back

Our code for the first test was simple. The vehicle would drive forwards for a short amount of time to position the trailer in line with the truck. Next, we set the gyro mode to "RATE" and then to"ANG" so that it would zero itself before backing up. We then put both motors in reverse and used a proportional control to read the gyro movement and adjust speed variables for the left and right motor accordingly. The vehicle starts at a slow speed and then speeds up to show that this system is robust at a wide range of speeds. We also kicked the trailer to demonstrate how it can react to unexpected changes in angle.

Challenge 2a: Big Circle

For part two we had to get the trailer to reverse in a circle. We added a variable theta that would get the difference between the readings from the two gyro sensors and then subtract the desired turn angle c. We would then modify the speed of each motor by that value times a proportional coefficient k, adding k*theta to the left motor and subtracting it from the right motor. This technique worked for circles with a sufficiently large turning radius.

Challenge 2b: Small Circle

When it was time to test on a smaller turning radius we had to slightly modify the code. Originally when we had the trailer driving straight back or in a large circle, the wheels would run at the same power when the desired angle was observed. This worked when the turning radius of the inner and outer wheels were sufficiently close (turning radius was on the order of meters and the distance between motors was ~2in.) But for tighter maneuvers we needed to make the left and right motors run at different speeds when the desired angle was observed.

This correction was necessary because it stabilized the equilibrium of the system. Consider a situation in which the code from Challenge 2a was used to turn around a tight circle using a reference of 25 degrees. When the difference in the gyro readings was 25 degrees, the two motors would run at the same speed. This would result in the truck driving straight back for a moment and causing the trailer to drift too far inside. In order to correct this, the truck would then have to overcompensate by straightening out. This would result in a very shaky circle or, even worse, jackknifing.

With the correction implemented in the Challenge 2b code, the outside wheel is set to run slightly faster than the outside wheel at all times. This will help keep the trailer system close to equilibrium by ensuring that the truck would drive in a circle, even without any feedback from the trailer.

In the second test of part two we changed the turning angle from 10 to 15 deg which shrunk the turning radius considerably. The change in the code from Challenge 2a to Challenge 2b can be found on line 48.

A final note

One issue we noticed for Challenge 2 that we had difficulty fixing was that, when the trailer was nudged, one motor would be instructed to run in reverse to correct the angle. This was either because the nudge was too much for the system to handle or the proportional constant was too large. We found that decreasing the constant, however, meant that the system was really unstable and could only run at low speeds. In the end, we found a set of values for angle, baseline speed, and proportional constant that worked and was somewhat robust when it came to nudging, but by no means did we have enough time to find ideal values.

Challenge 1: Maintaining constant position (aka “drive straight”)

Description

To maintain constant position and make the whole car move straight, the program keeps adjusting the direction when car is deviated. The gyro sensor can provide angle of the trailer. When the trailer is off correct direction, program will adjust direction of truck based on proportional control, and then the trailer can be back to normal direction.

Code:

```#!/usr/bin/env python3
def main(): ev3 = Device('this') #Connect the #1 motor to port A #Connect 1the #2 motor to port B m1 = ev3.LargeMotor('outA') m2 = ev3.LargeMotor('outD') sensor = ev3.GyroSensor('in2') sensor.mode='GYRO-ANG' kp = 10; bass = -200; loop = 1; while loop == 1: angle = sensor.value(); print(sensor.value()) error = angle-2; vb = bass + error * kp; va = bass - error * kp; if va < -1000: va = -1000 if va > 1000: va = 1000 if vb < -1000: vb = -1000 if vb > 1000: vb = 1000 m1.run_forever(speed_sp = va); m2.run_forever(speed_sp = vb);
if __name__ == '__main__': main()```

Challenge 2: Following a curve/path (aka “drive in a circle”)

Description

To achieve the goal of following a curve, the program keeps a certain angle between truck and trailer. Based on what we have in part in, we add another gyro sensor to measure angle of truck. With two gyro sensors, the program calculates difference between two angle values, keep the difference to a certain value with the proportional control in first part. We can change the radius by changing the setting difference between two angles.

Code:

```#!/usr/bin/env python3
def main(): ev3 = Device('this') #Connect the #1 motor to port A #Connect 1the #2 motor to port B m1 = ev3.LargeMotor('outA') m2 = ev3.LargeMotor('outD') #the trailer sensor sensor1 = ev3.GyroSensor('in2') #the cub sensor sensor2 = ev3.GyroSensor('in2') sensor1.mode='GYRO-ANG’ sensor2.mode='GYRO-ANG' kp = 10; bass = -200; loop = 1; # prevent the error comes from the origin angle of two sensors are not 0 angle_origin1 = sensor1.value(); angle_origin2 = sensor2.value(); while loop == 1: angle1 = sensor1.value() - angle_origin1; angle2 = sensor2.value() - angle_origin2; diff = angle1 - angle2; error = diff - 30; #for smaller circle: error = diff - 60; vb = bass + error * kp; va = bass - error * kp; if va < -1000: va = -1000 if va > 1000: va = 1000 if vb < -1000: vb = -1000 if vb > 1000: vb = 1000 m1.run_forever(speed_sp = va); m2.run_forever(speed_sp = vb);
if __name__ == '__main__': main()2
```

Images of Our Car

Optimus by Martin Majkut and Omar Sanchez

The goal for project 3, was to create a two motor truck/cab that would have a trailer attached at a joint  with a gyro sensor attached to the top of the joint and a second gyro sensor mounted on on to the actual cab.  The code that we developed would drive the trailer in reverse and maintain a constant control of the system. This first challenge had to be done with only the gyro sensor attached to the joint.  The second challenge required the truck/cab to maintain a circular path in reverse. For this portion of the project, the second gyroscope would come in to play.

Gallery:

Straight Back:

Round and Round:

Swamp Fox: By Sahana and Alex

Description

Swamp Fox, or at least that's her call sign when she speaks over her favorite trucker radio frequency, has implemented gyro sensors into her truck and trailer in order to better control her orientation when backing up and driving.

The cab of Swamp Fox's truck was constructed very similarly to the ultrasonic car of project 1, with one small deviation -- a pin on the back that allows the trailer to connect to one point on the cab, becoming a full fledged tractor trailer. This design features two gyro sensors: one on the trailer bed and one on the cab. We only used the values from one gyro sensor (on trailer bed) for part 1 but in part 2, we used the values from both the sensors to control our system.

The first part of this project was to have the truck move backwards in a straight line. Using proportional control, the truck would adjust itself when its path skewed off a straight line. Our initial approach was simple--when the gyro sensor detected that the trailer was going off course, have one wheel speed up and the other slow down accordingly to return to proper orientation. In practice, this was much harder than anticipated, and required implementation of various "if" and "elif" statements.

First, we saw that even tiny changes in the orientation of the trailer bed, when multiplied by Kp and applied to the speed of each wheel, eventually compounded and made the difference in wheel speeds too great. To combat this we decided that, while our goal was of course to have the sensor read 0 degrees, we would not have the wheels change speeds unless the trailer was off by more than 3 degrees. This actually gave the trailer a bit more flexibility, and more time to right itself as it approached the desired orientation.

Second, we saw that if the angle of offset became too great, it became extremely difficult for the motors to overcome the mass of the truck and its momentum. Additionally, due to our control equation, the motors moved at very high speeds. This was very hard to recover from. We decided to instill an "anglelimit" variable. When the gyro sensor sensed that it was at an angle greater than the allowed "anglelimit," the speeds of the motors would become constant. This allowed for much more control and better recovery after catastrophic collisions.

Last, we realized that we needed the motors to behave differently based on whether or not the angle of offset was getting worse, or actually improving. This brings us to the if statements inside the "else" statement at the end of the code. If the reading on the gyro sensor is increasing, one wheel gets faster and the other gets slower to try and reorient the trailer. Once the gyro reading begins to decrease, indicating that the trailer is righting itself, the wheels switch - the one that was speeding up now slowed down, and vice versa. This helped the truck better ease into the correct orientation.

In the end, we were successful in getting the truck to repeatedly reorient itself when its path was interrupted, and eventually return to a straight path. You can see that while it is slow going, each time the truck over corrects itself, it is by a smaller and smaller margin, until finally the truck is pretty much going straight in its original direction, showing a successful implementation of proportional control.

The second part involved the truck travelling in a curved path, that it would return to if there was noise in the system. Given the work in part 1, it was very easy to write this code. First, there is a while loop which involves the car pivoting along one wheel in order to get to the desired orientation between the two gyro sensors. Then, it was as simple as replacing the single angle measurement in part 1 with a comparison of both of the gyro sensor readings. You can see in the video that the motion is a bit choppy and this is due to friction with the floor and the inherent instability in the trailer. But it is also evident that the truck is continuously fixing itself as the trailer goes askew, and then returning to the circular path, even when the trailer is hit with an external force.

In the end, Swamp Fox was successful in righting itself to follow a straight path as it backs up, and righting itself to follow a curved or circular path, using proportional control.

Pictures

Front view of Swamp Fox, showing the connections between the motors and the brick.

Pin set up that connects the trailer to the cab.

How the two gyro sensors are affixed and connected to the brick.

Full side view of Swamp Fox. She is magnificent.

Videos

Swamp Fox moving backwards in a straight line

Swamp Fox readjusting itself if there is a "obstruction"

Swamp Fox moving around in a circle (small)

Swamp Fox moving around in a circle (big)

Code

Part 1: Code for Swamp Fox to back up

Part 2: Code to have Swamp Fox move in a small circle

Project 3: Trailer Control

Annalisa DeBari & Raven Fournier

Description: We created a car and trailer using the provided acrylic cut piece and attaching it to the EV3 brick using a hinge that allows low friction rotation. For Challenge 1, the our goal is to drive straight (angle = 0) so the error is equal to the angle minus zero. To adjust the direction of the main part of the car, we added or subtracted values from the left and right motors labeled powerA and powerB. For challenge 2, the goal was to follow a set curved line. In this case, the error is the difference in the two gyro sensor readings minus the desired angle. In one test, we set the angle to 20. In test two, the angle was set to 40. These two constants control the radius of the arc.

Reset Gyro Code: (From Website) We used this separately for both gyro sensors before running our code.

```#!/usr/bin/python3
from time import sleep def main(): print('Program: Reset Gyro') # create EV3 device ev3 = Device('this') print('Step 1\. Setup and Configure Gyro') # define gyro sensor gyro_sensor = ev3.GyroSensor('in4') # set gyro mode to angle gyro_sensor.mode = 'GYRO-ANG' # read two base values (second apart) print('Step 2\. Read Base Values') sleep(1) print('- value 1: ' + str(gyro_sensor.value())) sleep(1) print('- value 2: ' + str(gyro_sensor.value())) sleep(1) # calibrate/reset gyro (by changing modes) print('Step 3\. Calibrate/Reset Gyro') gyro_sensor.mode = 'GYRO-RATE' gyro_sensor.mode = 'GYRO-ANG' # read new values (second apart) print('Step 4\. Read New Values') sleep(1) print('- value 3: ' + str(gyro_sensor.value())) sleep(1) print('- value 4: ' + str(gyro_sensor.value())) print('Step 5\. Done') if __name__ == '__main__': main():```

Challenge 1: Drive Straight

```#!/usr/bin/python3
from time import sleep
def manageRange(n): return max(min(n,1050),-1050) def main(): # define variables distance = None kp = None error = None power = None powerA = None powerB = None # base is negative to make the motors drive in the correct direction base = -80 print('Program: Read Gyro') # create EV3 device ev3 = Device('this') print('Step 1\. Setup and Configure Gyro') # define gyro sensor gyro_sensor = ev3.GyroSensor('in4') # set gyro mode to angle gyro_sensor.mode = 'GYRO-ANG' print('Step 2\. Read 10 Gyro Sensor Values') while True: # read the gyro value (angle) angle = gyro_sensor.value() # print the gyro value (with some formatting) print(str(angle)) # set prop control value and define error kp = 1.5 error = angle - 0 print('error is') print(str(error)) # if angle is zero, drive both motors at the same time to stay straight if error == 0: print('error is zero') outA = ev3.LargeMotor('outA') outA.run_forever(speed_sp= manageRange(base* 1)) outB = ev3.LargeMotor('outB') outB.run_forever(speed_sp= manageRange(base* 1)) # if turning, adjust motors to realign elif error > 0: print('error is') print(str(error)) # using same addition and subtraction for both positive and negative error # for motor A and B because when error is negative, # the double negative removes the need to change the sign powerA = base+ angle* kp powerB = base- angle* kp outA = ev3.LargeMotor('outA') outA.run_forever(speed_sp= manageRange(powerA* 1)) outB = ev3.LargeMotor('outB') outB.run_forever(speed_sp= manageRange(powerB* 1)) elif error < 0: print('error is') print(str(error)) powerA = base+ angle* kp powerB = base- angle* kp outA = ev3.LargeMotor('outA') outA.run_forever(speed_sp= manageRange(powerA* 1)) outB = ev3.LargeMotor('outB') outB.run_forever(speed_sp= manageRange(powerB* 1)) else: break print('Step 3\. Done') if __name__ == '__main__': main()```

Challenge 2: Drive in a curved path set by the different in angle readings

```#!/usr/bin/python3
from time import sleep
def manageRange(n): return max(min(n,1050),-1050) def main(): distance = None kp = None error = None power = None powerA = None powerB = None base = -80 print('Program: Read Gyro One and Two') # create EV3 device ev3 = Device('this') print('Step 1\. Setup and Configure Gyro') # define gyro sensors - same code as before but new sensor added gyro_sensor1 = ev3.GyroSensor('in4') gyro_sensor2 = ev3.GyroSensor('in2') # set gyro mode to angle gyro_sensor1.mode = 'GYRO-ANG' gyro_sensor2.mode = 'GYRO-ANG' print('Step 2\. Read Gyro Sensor Values') while True: # read the gyro value (angle) angle1 = gyro_sensor1.value() angle2 = gyro_sensor2.value() # print the gyro value (with some formatting) print('angle1:' + str(angle1)) print('angle2:' + str(angle2)) kp = 1.2 # for smaller curve, the fixed difference in angle readings is 40 # for the larger curve, we made the constant = 20 # changing the constant changes the radius of the arc error = (angle1 - angle2) - 40 print('error is') print(str(error)) if error == 0: print('error is zero') outA = ev3.LargeMotor('outA') outA.run_forever(speed_sp= manageRange(base* 1)) outB = ev3.LargeMotor('outB') outB.run_forever(speed_sp= manageRange(base* 1)) elif error > 0: print('error is') print(str(error)) powerA = base+ error* kp powerB = base- error* kp outA = ev3.LargeMotor('outA') outA.run_forever(speed_sp= manageRange(powerA* 1)) outB = ev3.LargeMotor('outB') outB.run_forever(speed_sp= manageRange(powerB* 1)) elif error < 0: print('error is') print(str(error)) powerA = base+ error* kp powerB = base- error* kp outA = ev3.LargeMotor('outA') outA.run_forever(speed_sp= manageRange(powerA* 1)) outB = ev3.LargeMotor('outB') outB.run_forever(speed_sp= manageRange(powerB* 1)) else: break print('Step 3\. Done') if __name__ == '__main__': main()```

:

:

:Challenge 1

Challenge 2a.

Challenge 2b.

Trailer Back Up

Here you can see our truck backing up and making adjustments to the trailer angle as it moves. The code adjusts the trailer even when given a bit of a kick. However we also have code such that if the angle diverges too much (greater than 60 degrees), the truck will stop and back up to straighten the trailer, and then continue forward.

Big Circle

Similar to above, except now the angle we want is around while keeping the difference between the truck gyro and the trailer gyro at  20 degrees to drive in a large circle (although we didn't show the entire circle in the video).

Small Circle

Here we just adjusted the angle difference to be 40 degrees to make a small circle.

Code

Trailer Backup Code

Circle Code

This code is identical for both big and small circles, except we change the value of the angle (i.e. it is 20 in this code for the big circle, but 40 for the small circle.

Project 3: Trailer Control

Robot Construction

The car was constructed using the same design as Project 1. At the rear of the car, the trailer consisting of acrylic board and wheels was attached. For the first challenge, the gyro sensor was attached at the connection point between the trailer and the car. The gyro sensor was attached in alignment with the trailer, so that it measured the angle between the imaginary straight line drawn across the trailer, when it initially begins moving, and the sensor. For the second challenge, additional gyro sensor was attached above the car, also in alignment with the trailer.

(Above) Gyro sensor placement (Below) Trailer

Challenge 1: Drive Straight

Challenge 1 required the car to drive backward in straight line. Since the challenge only required the orientation to be straight rather than keeping the initial straight path, we only needed to consider the angle that the trailer makes with the initial orientation of the sensor. Speed was set to be -400. After experimenting with several trials, we determined the ideal kp of our proportional control to be 10. At kp that is too small, the car could not adjust its position when struck by large noise (kick). At kp that is too big, the car essentially ran out of control since it overshot its motor speeds every time it tried to adjust its orientation. Video and code are shown below.

Challenge 2: Drive in Circle

Challenge 2 required the truck and trailer to simultaneously move in a circular path. Since we wanted to hold the same angle throughout the movement, 2 gyroscopic sensors were used. They were both calibrated by being in the same plane, or both having the same angle of zero. In order to initiate and hold the rotation, a displacement angle was added to the difference of the angles (theta3) obtained from the sensor. Changing this displacement value resulted in a change of the the circular path (larger displacement value resulted in larger circle, and vice versa). Theta3 in our code was sent to the motors to actuate. It was very important to break down the system and obtain the proper orientation for each angle. Incorrect orientations (adding or subtracting something incorrectly) resulted in the wheels spinning in opposite directions, or the vehicle simply becoming stuck. The Kp value, and our theta3 value allowed the vehicle to sustain the circular path.

[Video 1: angle = 10, speed -200]

[Video 2: angle = 50, speed -200]

[video 3: angle 50, speed = -400]

Code

The Bat-tractor

Intro

The goal of this project was to construct a tractor capable of pulling and pushing a provided trailer, using proportional control to allow a robot to correct itself in unstable equilibrium. Three challenges were provided, of which two were required: 1) driving in reverse in a straight line, and 2) driving in reverse at a given angle; i.e., driving in reverse on a circular path.

The tractor

The tractor is of a fairly simple design, consisting of two independent motors and a single omnidrectional roller, allowing the vehicle to turn stably. The trailer is connected to the tractor on the motor side, since this side is closer to the center of rotation and is therefore easier to control.

Maintaining a Constant Position:

The goal of the first challenge was to maintain the trailer’s straight path. For this, we used a single gyro sensor. The robot first drives forward for 3 seconds to ensure that the starting position of the gyro is straight. The sensor calibrates to 0, and then the robot begins driving backwards. The program continually reads the gyro sensor position to adjust the robot’s trajectory. If the angle is nonzero, the robot corrects by adding 1.5 times the gyro angle to the right motor speed, and subtracting this from the left. The robot turns left to correct a positive angle, and right to correct a negative angle, and the correction is more significant for larger angles.

One issue we ran into was that the robot would correct for differences in the trailer angle, but would correct regardless of the tractor angle. For example, if the robot corrects the trailer but the tractor is on an angle, the tractor will then drive straight on that angle. This is due to the constraint of the challenge, for which we could only use one gyro sensor placed on the trailer. This could be corrected by fixing a second gyro sensor to the tractor, so that the robot could correct for both angle changes.

Code:

Following a Curved Path:

The goal of the second challenge was to follow an arc of a certain degree. The beginning of the code is similar to the first challenge, while calibrating a second gyro sensor fixed to the robot. The desired arc angle is set as a variable. When the robot begins driving forward, the code functions similarly to the first: however, instead of correcting for the angle of the gyro sensor on the trailer, it corrects for the difference between the desired arc angle and the actual difference in the angles of the tractor and trailer. The code worked at both small (20 degrees) and large (50 degrees) angles.

Code:

Photos and videos

Side view. Main drive wheels, front omnidirectional "wheel", gyro sensors, aesthetic elements all visible.

Front view. Motor connections to EV3 visible.

Rear view.

Undercarriage view. Tractor/trailer interface visible.

Top view.

Isometric view. Flag in better focus.

Robot moving in reverse in a straight line. Good demonstration on how hardware requirements actually interfere with software requirements.

Robot moving in reverse at a set angle, resulting in a circle.

Robot moving in reverse at a different angle, resulting in a circle of a different radius.

Overview:

The goal of this project was to use proportional control techniques to push a trailer mounted to our car base along different driving patterns. We succeeded in pushing our trailer to drive straight, to drive in a circle, and to parallel park inside of a parking spot.

Construction:

The “tractor” of our truck has 2 wheels each attached to their own motor and well as a castor wheel in the front of the truck for balance. The truck gyro is mounted above the center of the EV3 controller and the axle it is attached to is also used for cable management.

The hitch consists of a beam mounted to the trailer which connects to a beam on the back of the tractor with 1 pin, which allows for free rotation and easy separation of the two pieces for transport. The trailer gyro is mounted on the beam offset several inches from the point of rotation, but along the centerline of the trailer.

Code:

All three challenges involved using a gyro and proportional control to drive a truck in reverse. An error is calculated from the gyro angle and then that error is multiplied by a proportionality constant, Kp, to get a speed difference. This speed difference is then added to one motor’s speed and subtracted from the other. This causes the robot to turn and push the trailer back on course.

Challenge 1: Drive Straight

For this challenge, the code only utilizes data from 1 gyro mounted on the trailer. The error is simply the trailer angle.

Challenge 2: Drive in a Circle

This challenge utilizes data from both the truck gyro and the trailer gyro. The error is calculated by taking the difference between the 2 gyro angles and then subtracting the target turn angle.

Challenge 3: Parallel Parking

This challenge uses very similar code to driving in a circle. The motion of parallel parking can be done by drive 2 opposite direction arcs. The robot simply drives a 15 degree arc counter-clockwise and then another 15 degree arc clockwise. The exact angle and duration of these arcs were determined experimentally and since the robot was built very compactly, these arcs did not have to be very precise to fulfil the challenge requirements.

Technical Drawbacks:

One of the main difficulties we ran into during this project was with the EV3 gyro sensors. During initial testing, the robot would steer off course repeatedly. This problem was caused by drift issues with the gyro sensor. We swapped the truck and trailer gyro which fixed issues for driving straight, since that program only uses the trailer gyro. However, we continued to have issues with driving in a circle, since we only had 1 good gyro. This resulted in the angle between the trailer and truck gradually increasing until the trailer hit the hard stop on the hitch and could rotate any further.

Code Files:

drive_straight.py

drive_circle.py

parallel_park.py

Robert Hrabchak

Riley Kolus

2/7/18

The Autonomous Trailer

Intro

The goal for this project was to create a truck that was capable of hauling a premade trailer. Using gyroscopic sensors, the truck had to be capable of driving itself in reverse along a straight path, along a circle, and parallel parking itself. This is small demonstration of what the future of autonomous trucking looks like!

The Vehicle

To construct this truck, first two independently powered wheels were attached via motors to the front of the vehicle. To make the truck stable, a rolling wheel was placed at the back of the cab. The truck was then attached via a simple hinge to the trailer. Next the sensors were attached to the vehicle so that the truck could be made autonomous. One gyroscope was placed above the joint connecting the trailer to the truck. The other gyroscope was placed above the EV3 controller on the truck. Lastly, a simple pushbutton was added to the side of the vehicle to allow the desired program to be stopped more simply than running back to a laptop after the vehicle crashes.

The Code

Part 1: Backing up in a straight line

To make the vehicle reverse in a straight line, the code employed had to follow a simple command structure: REDA. That, of course, stands for Read the sensor, calculate the Error, Decide what to do, and Actuate. Reading the sensor meant initializing the gyroscope and reading it every time through the infinite loop. After a reading was output from the gyroscope, the controller would determine how far and in which direction the trailer was moving away from 0 degrees, with a straight line being perfectly lined up at 0 degrees. Depending on the error, motor speeds for each of the front two wheels would be decided on to realign the trailer. Lastly, the commands were sent to the motors to be implemented. The loop then checks to see if the stop button was hit, and otherwise repeats this process continuously.

This part of the project was straightforward and worked extremely well - the trailer could reverse in a straight line easily. Even when the trailer was “disturbed,” or kicked off course, the truck was able to quickly recover from the situation and realign itself.

Part 2: Backing up in a circle

Reversing in a circle required the same basic logic structure as implemented above, with a few added parameters. First of all, the second gyroscope was used this time. When calculating the error, the two gyroscope readings were subtracted from each other and compared to a reference angle. We found that we could set this reference angle between roughly -35 degrees and + 35 degrees while still having a stable system. The closer this reference angle is to 0, the larger the circle would be. Setting the reference angle close to either limit would result in a tighter turning radius. Otherwise, a similar Read, compute Error, Decide, Actuate control setup was used.

This part of the project took more time to perfect because the gain factor “k” had to be tested at various different levels to make the system stable. This gain factor was directly related to the drive speed, and the reference angle, so all three parameters had to be tuned to work well with each other. This resulted in a few crashes into sofas, but ultimately a suitable of values was arrived upon that allowed the system to remain in a stable circle, even after the trailer was kicked out of the correct direction.

Part 3: Parallel parking

To parallel park the truck, we first researched how real truck drivers parallel park. After observing their methods, the team hardcoded motor speed values to simulate the same actions. A test course was setup with the correct dimensions, and a number of trials were conducted to determine the optimum motors speeds and timing delays. With enough practice, the truck was able to flawlessly park itself. The future of trucking is finally here!