physics124.barreiro.ucsd.eduphysics124.barreiro.ucsd.edu/.../41/2016/12/atfliv.docx · web...
TRANSCRIPT
Robinson/Phillips 1
University of California San Diego
Final Project
Tridar Laser Range Finder
Lee Robinson, John Phillips
Physics 124: Laboratory Projects
Professor Julio Barreiro
03/24/2017
Robinson/Phillips 2
Motivation
Laser detection and ranging has many important applications such as terrain surveying,
target detection, and light imaging. With the influx of programming capabilities and
improvements of sensors, processing information is no longer strictly a job performed only by
the human brain. In the weapons development field laser detection and ranging gives the
operator a massive margin for safety removing him from the eyes of his enemy. Light imaging,
gives the operator a passive sensing system to collect data about a target while preventing
detection as compared to an intrusive radar system. Surveying in the field allows for
industrialists to simplify their measuring processes saving both time and money with
trigonometric triangulations and minimal equipment requirements. This project seeks to mimic a
system that may be useful in object of interest ranging while transmitting sensed information to
an operator. Further motivations are to explore simple programming with the Arduino and
printing processes with a 3D printer. Specifically, the input is from the user aligning two laser
spots on a target of interest using a joystick to control the motion. The processing of information
is performed by code written in C by the Arduino compiler and the output is some displayed
distance while aligning what could be a projectile launcher on a trajectory to hit the target of
interest.
Functional Definition
Three lasers will be mounted on three dual servo systems while two are controlled by a
joystick. A calculation with the known distance between the laser turrets and the interior angles
will provide a distance to the object. The two servos will control the azimuth and the elevation to
point in the direction of the object. The distance information will then be displayed on and LED
display.
Robinson/Phillips 3
Sensors
The two lasers are TTL Laser Diodes with a power of 5 mW that are red in color and run
at a wavelength of 650nm. The main sensors will be the joysticks themselves sensing motion
from the user. The joysticks are basic two axis potentiometers and their position dictates some
motion of the laser turrets based upon their variable resistance. The Arduino takes the input from
the joysticks, transmits it to the turrets, and calculates the distance where the lasers spots
converge. That information is also manipulated to calculate the azimuth and elevation
information for a third turret that sits directly in between them.
Mechanical Considerations
Due to the importance of laser alignment the turrets were 3D printed using parts designed
in Autodesk Inventor. Initially many measurements had to be taken to ensure the parts
manufacturing process went as smooth as possible to prevent wasted time on the printers. Each
turret took about three and a half hours and printing incorrectly sized parts was hotly avoided.
Some problems encountered were the automatic scaling that occurred when the files were
imported. The MakerBot software that takes the 3D modeled part and prepares it for printing was
automatically scaling the parts to about one percent of their original sizes. The first series of
parts were a success but the second print job was of an awkwardly shaped part and mistakes
were made in ensuring it was scaled correctly in the MakerBot software. The second print came
out scaled too small and was useless but due to the lessons learned all the rest of the print jobs
were performed flawlessly. There was a large amount of wiring coming from the lasers and
servos so attention was paid to how they were routed as to prevent binding allowing the servos to
articulate through their full range of motion. The wiring ran from the turrets to a breadboard to
help organize and to prevent having to solder. An Inventor version of the turret is shown.
Robinson/Phillips 4
Electrical Considerations
The servos each needed ground, communication, and plus five volts for power that the
Arduino was more than capable to supply. The servos initially proved to not provide small
enough increments to allow properly coded accuracies. The laser turrets were then separated at a
greater distance to assist in this issue but writing in microseconds helped to divide each degree
into nine more increments providing more accuracy. The lasers each needed voltage that
required a power supply separate from the 5 volts provided by the Arduino. The TTL laser
diodes produced 5 mW of power putting them in the class 3b laser range and under prolonged
eye exposer can be harmful. Resistors were installed in line with the power wires to bring the
power down to about a class 2 which made them more eye safe. A basic schematic is provided.
Robinson/Phillips 5
Wiring Diagram
Robinson/Phillips 6
Interface
The interface will be two joysticks and a liquid Chrystal display. The joysticks are
mounted to two handheld controllers with long wiring harnesses to give the user freedom to hold
the joysticks in any orientation. The turrets are mounted to a large piece of wood and leaving the
controllers to move with the operator will provide convenient ergonomics. Pictures of the LCD
screen and joysticks are provided.
Software
Libraries for the operation of the servos were utilized. Commands such as analogRead
and analogWrite were useful in the servo control and joystick position reading. The
trigonometric equations required meticulous coding and troubleshooting to perform the functions
required. Step by step checking of the output from each step of the code provided a streamline
troubleshooting process. Functions such as the law of sins and the law of cosines were
manipulated accordingly to acquire the range information and the interior angle of the third
turret.
sin(α )A
= sin( β)B
R2=A2+B2−ABCos (θ)
Robinson/Phillips 7
Code
#include <LiquidCrystal.h>//Adds the library required to run the LCD Shield#include <Servo.h>//Adds library required to control the servos.
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);//Sets up with LCD with the pin configuration used by the LCD ShieldServo hitech1;//Joy1(y)/////////// This declares the name of the servo as hitech1. Joy1(y) represents turret 1's vertical control servo.Servo hitech2;//Joy1(x)/////////// This declares the name of the servo as hitech2. Joy1(x) represents turret 1's horizontal control servo.Servo hitech3;//Joy2(y)/////////// Same as above for vertical except now turret 2.Servo hitech4;//Joy2(x)/////////// Same as above for horizontal except now turret 2.Servo hitech5;//Tar(y)//////////// This declares the name of the servo as hitech5. Tar(y) represents the center turret's vertical control servo.Servo hitech6;//Tar(x)//////////// Same as above for center turret except now the servo is for horzontal control.int involt1;//joy1x///////This variable will be used to measure voltage for joystick 1's horizontal range.int involt2;//joy1y///////Used for joystick 1's vertical range.int involt3;//joy2x///////This variable will be used to measure voltage for joystick 2's horizontal range.int involt4;//joy2y///////Used for joystick 2's vertical range.float i = 90.0;//joy1x////////////Main variable for the angle. Also the variable used for the math resposible for the distance give on the LCD screen.float j = 90.0;//joy1y////////////Same as abovefloat k = 90.0;//joy2x////////////Same as abovefloat l = 90.0;//joy2y////////////Same as abovefloat m = 90.0;//tarx/////////////Same as abovefloat n = 90.0;//tary/////////////Same as abovefloat si;//Angle for top of trianglefloat sir;//Radian version of sifloat theta;//Angle for bottom right of trianglefloat thetar;//Radian version of thetafloat phi;////Angle for elavationfloat phir;//Radian version of phifloat b;//This is used the find the lenght of one side of the trianglefloat a = 94.6625;//This is the measured distance between the lasersfloat r;//This is the distance from our center laser to the target, without elevation factored infloat d;//This will be the actual distance with elavation factored in.float ii;//////////Just the (i) variable above except this will actually write to the servo. This variable has been calibrated to write in microseconds instead of degrees.float jj;//////////Just the (j) variable above except this will actually write to the servo. This variable has been calibrated to write in microseconds instead of degrees.float kk;//////////Just the (k) variable above except this will actually write to the servo. This variable has been calibrated to write in microseconds instead of degrees.float ll;//////////Just the (l) variable above except this will actually write to the servo. This variable has been calibrated to write in microseconds instead of degrees.float mm;//////////Just the (m) variable above except this will actually write to the servo. This variable has been calibrated to write in microseconds instead of degrees.float nn;//////////Just the (n) variable above except this will actually write to the servo. This variable has been calibrated to write in microseconds instead of degrees.float kr;////This is just like the (k) above except this will be converted to radians for use with our math below.
void setup() {
cal(i, j, k, l, m, n);//Calls the calibration function lcd.begin(16, 2);//Tells the computer that our LCD has 16 columns and 2 rows lcd.setCursor(0, 0);//Begin writing on the first row and column lcd.print("Distance in cm");//Write the quoted text the left hitech1.attach(10, 630, 2380);//Designates the pin 10 as control for hitech1,joy1y hitech2.attach(2, 660, 2380);//Designates the pin 2 as control for hitech2,joy1x hitech3.attach(3, 660, 2380);//Designates the pin 3 as control for hitech3,joy2y hitech4.attach(11, 650, 2380);//Designates the pin 11 as control for hitech4,joy2x hitech5.attach(12, 750, 2380);//Designates the pin 12 as control for hitech5,tary hitech6.attach(13, 670, 2380);//Designates the pin 13 as control for hitech6,tarx
hitech1.writeMicroseconds(jj); //right top servo (joy1y)/////////////////////////////////////////////////////////////////Begin delay(10); hitech2.writeMicroseconds(ii); //right bottom servo (joy1x) delay(10); hitech3.writeMicroseconds(ll); //left top servo (joy2y) delay(10);/////////////////////////////////////////This region of code sets all turrets at 90 degrees with small delays. hitech4.writeMicroseconds(kk); //left bottom servo (joy2x) delay(10); hitech5.writeMicroseconds(nn); //middle top servo (tary) delay(10); hitech6.writeMicroseconds(mm); // middle bottom servo (tarx)///////////////////////////////////////////////////////////////End delay(10);}
void cal(float i, float j, float k, float l, float m, float n) {
ii = i * (9.611) + 670.0; //joy1x/////////////////////////////////////////////////////////////////////////////////////////////////////////////////Begin jj = j * (9.75) + 635.0; //joy1y kk = k * (9.5) + 660.0; //joy2x////////This section of code translates the math which is performed in degrees into microseconds for beter servo control. ll = l * (9.556) + 660.0; //joy2y mm = m * (9.833) + 660.0 ; //tarx nn = n * (9.0) + 763.0; //tary//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////End}
void joy1x() {
if (involt1 > 950) { ////x joy1///This if statement, checks to see if the required voltage is met and then tells the servo to move in that direction cal(i, j, k, l, m, n); hitech2.writeMicroseconds(ii); i -= 0.5; delay(10); } else if (involt1 > 600) {///This does the same as above, but now moves the servo more slowly. This indicates that the joystick is not at full throw.
Robinson/Phillips 8
cal(i, j, k, l, m, n); hitech2.writeMicroseconds(ii); i -= 0.1; delay(30); } if (i > 172) { i = 173; } if (involt1 < 80) { ////-x joy1///Same as above except moving the opposite direction cal(i, j, k, l, m, n); hitech2.writeMicroseconds(ii); i += 0.5; delay(10); } else if (involt1 < 400) {//Same as above except moving the opposite direction cal(i, j, k, l, m, n); hitech2.writeMicroseconds(ii); i += 0.1; delay(30); } if (i < 8) { i = 7; }}
void joy1y() {/////////////////////////////////Same as joy1x() except now controlling the horizontal servo
if (involt2 > 950) { ////y joy1 cal(i, j, k, l, m, n); hitech1.writeMicroseconds(jj); j += 0.5; delay(10); } else if (involt2 > 600) { cal(i, j, k, l, m, n); hitech1.writeMicroseconds(jj); j += 0.1; delay(30); } if (j > 172) { j = 173; } if (involt2 < 80) { ////-y joy1 cal(i, j, k, l, m, n); hitech1.writeMicroseconds(jj); j -= 0.5; delay(10); } else if (involt2 < 400) { cal(i, j, k, l, m, n); hitech1.writeMicroseconds(jj); j -= 0.1; delay(30); } if (j < 8) { j = 7; }}
void joy2x() {///Same as joy1x() except now we are using the other joystick to control the other turret.
if (involt3 > 950) { ////x joy2 cal(i, j, k, l, m, n); hitech4.writeMicroseconds(kk); k -= 0.5;
delay(10); } else if (involt3 > 600) { cal(i, j, k, l, m, n); hitech4.writeMicroseconds(kk); k -= 0.1; delay(30); } if (k > 172) { k = 173; } if (involt3 < 80) { ////-x joy2 cal(i, j, k, l, m, n); hitech4.writeMicroseconds(kk); k += 0.5; delay(10); } else if (involt3 < 400) { cal(i, j, k, l, m, n); hitech4.writeMicroseconds(kk); k += 0.1; delay(30); } if (k < 8) { k = 7; }}
void joy2y() {//Same as joy1y() except controlling other outside turret.
if (involt4 > 950) { ////y joy2 cal(i, j, k, l, m, n); hitech3.writeMicroseconds(ll); l += 0.5; delay(10); } else if (involt4 > 600) { cal(i, j, k, l, m, n); hitech3.writeMicroseconds(ll); l += 0.1; delay(30); } if (l > 172) { l = 173; } if (involt4 < 80) { ////-y joy2 cal(i, j, k, l, m, n); hitech3.writeMicroseconds(ll); l -= 0.5; delay(10); } else if (involt4 < 400) { cal(i, j, k, l, m, n); hitech3.writeMicroseconds(ll); l -= 0.1; delay(30); } if (l < 8) { l = 7; }}
void joy3x(float k, float i, float l, float j, float a) { /////////////////////////////////////////This controls the horizontal position of the middle servo
Robinson/Phillips 9
/////////////////////////////////////////This is also responsible for the distance displayed theta = 180.0 - i; thetar = theta * PI / 180.0; si = i - k; sir = si * PI / 180.0; kr = k * PI / 180.0; m = 180.0 - theta - (si / 2.0); b = a * sin(kr) / sin(sir); r = sqrt((b * b) + (a * a / 4) - a * b * cos(thetar)); phi = 90.0 - n; phir = phi * PI / 180.0; d = (r / cos(phir)); cal(i, j, k, l, m, n); hitech6.writeMicroseconds(mm); lcd.setCursor(0, 1);/////Print on second line of LCD Shield lcd.print(d);//////////Print the distance}////////////////////////////////////////////////////////////////////////////////////////////////////End
void joy3y() {/////////////////////////////Responsible for the position of the center laser's horizontal controll
n = (l + j) / 2.0; cal(i, j, k, l, m, n); hitech5.writeMicroseconds(nn);}//////////////////////////////////////////End
void loop() {
involt1 = analogRead(1);//Takes the analog signal strength and assigns it to a varible ease involt2 = analogRead(2);//Same as above involt3 = analogRead(3);//Same as above involt4 = analogRead(4);//Same as above
if (involt1 > 600 || involt1 < 450) {////If the joystick moves a certain amount in x move that servo and adjust the middle servo joy1x(); joy3x(k, i, l, j, a); }///////////////////////////////////////End if (involt2 > 600 || involt2 < 450) {///////If the joystick moves in the y move that servo and adjust the middle servo joy1y(); joy3y(); joy3x(k, i, l, j, a);////This is only here to rerun the distance calculation. Horizontal postion is not affected. } if (involt3 > 600 || involt3 < 450) {////////////Same as above joy2x(); joy3x(k, i, l, j, a); } if (involt4 > 600 || involt4 < 450) {////////////Same as above joy2y(); joy3y(); joy3x(k, i, l, j, a); }}
Testing
For the testing the calculations were performed by the Arduino in C and manual
measurements were taken. After testing it was discovered the accuracy of the distance was
limited by the zeroing capabilities with a protractor and a ruler. The initial angles had to be set
and reset many times to get acceptable accuracies. It was realized the laser alignment capabilities
available were not enough to get the distance measurements under a ten percent error. The servos
provided fine enough angle placement and the calculations acceptable accuracies but our initial
angle zero could not. Measuring anything smaller than a degree with a protractor provided to be
quite difficult.
Safety
Robinson/Phillips 10
Since laser light can be harmful to the human eye the operators will ensure that no light
directly ends up an any person’s eyes. Coating of the targets will be considered to prevent
reflections of laser light from causing any ocular damage. The laser direction will constantly be
under control as not to bounce the laser of any polished surfaces causing reflected exposures.
Expansion/Descope
The original expansion idea was to build a projectile launcher that would hit a target
using calculations from Newton’s equations in addition to the distance and elevation information
form the laser turret apparatus. Unfortunately, the inaccuracies introduced into the calculations
from the inability to get an acceptable zero of the laser turrets would have produced a projectile
launcher that would be too inaccurate to fire during a presentation. Safety concerns began to
arise during the projectile launcher construction and the inability to safely zero the laser system.
List of parts
1. Six servos
2. Three lasers
3. Three laser brackets
4. Arduino Mega board
5. Three 3D printed mounting systems
6. Two joysticks
7. Liquid Chrystal display
Things that could have been done differently
Generally, the project was a success. The accuracy of measurement over long distances
became an issue when we realized we could not calibrate our positions with ease. We realized
Robinson/Phillips 11
using steppers instead of servos would have provided a more accurate platform for getting the
perfect angle measurement. One degree across a 30-foot room comes out to about 6 inches in
elevation or azimuth. When you combine error from multiple information gathering sources and
perform calculations with it the error grows ever larger. Spending more time on the zeroing
process along with using more precise stepper motors should have been higher priorities.
Who Did What
The turrets were designed with Autodesk Inventor and 3D printed in the UCSD Library
by Lee Robinson. The primary wiring was performed by John Phillips and longer wiring
harnesses were installed by Lee. John was the writer of the code and the testing and
troubleshooting of the code and alignment process was performed by both Lee and John.