Traffic Control

download Traffic Control

of 29

description

tyco manual

Transcript of Traffic Control

  • Autonomous Automac AutomobilesSenior Capstone Design

    David TretheweyMichael Jones

    Adviser: Dr. Christopher Rose

    May 12, 2011

    1

  • AbstractOverview of project.

    1 Movaon and ObjecveIn the modern world technology plays an ever-increasing role in all of our lives. Cars are no dif-ferent; all cars today are controlled by sophiscated computers, and have yet more sophiscatedcomputers for comforts and amenies. One car, the Mercedes-Benz S-Class, is considered to be atechnology preview for what will appear commonplace in average cars in ten to twenty years. Forinstance, it was the rst to use seatbelt pretensioners, the devices that lock the seatbelt when itis pulled too hard. The technology currently in this car inspired the idea for this project. The car isequipped with a RADAR guidance system, which monitors the environment and can apply brakingto avoid an accident if the driver isnt pushing down hard enough, or even if the driver is doingnothing at all. There are also lane sensors, which alert the driver if the vehicle starts to leave itslanewithout the use of a turn signal, so all the driver has to do is put the car into cruise control andlisten for the beeps. There is also sophiscated body tracking technology to monitor the alertnessof the driver to keep the driver from falling asleep behind the wheel, and a n infrared camera thatcan allow the driver to see far ahead of where headlights at nighme normally can. But this extratechnology to tailor specically to the driver begs the queson: Why do we need a driver at all?The car contains much of the technology needed to drive itself, plus a lot of wasted technologyon the user controlling it. It has a GPS Unit, so why can it not just take and address and go thereitself? This queson is the fundamental queson behind this design project.

    Our objecve was to develop and test both autonomous vehicle control methods and wirelessvehicle communicaons that would allow mulple cars to negoate the same space. That is, ourgoal was to develop a way for roboc automobiles to share the road. The ideal way to build thiswould be to build a roboc interface to our real cars, aachwireless transmiers and drive the carsaround on real roads. Owing to insurance concerns this is an infeasible construct, so we chose tomodel the system with R/C Cars. They are smalla foot to two feet longso we can use a closedo area to create a road. We alsomade some simplied assumpons in the environment. The realcars have thousands of dollars of advanced RADAR systems and video sensors tomonitor the road.For our simulacrum we built an inducve guidance system to keep the car in the lane, and usedseveral cheap(er) ultrasonic rangenders to locate nearby obstacles. The brain of the cars is theParallax Propeller Proto Board, an eight core microprocessor, while wireless communicaons arehandled by the XBee Wireless Radio device. These are actually realisc components in a real-lifeautomobile control system, though not in proto board form. Using these parts we create amovingwireless mesh network.

    2 Roboc Vehicle DesignAll of the vehicles were once normal R/C Cars, but have been torn down to just the chassis, mo-tor(s) andwheels. Each car has amotor controller, baery pack, and a plaormonwhich tomount

    2

  • the electronics.

    2.1 R/C RetrotTwo of the cars happened to be repurposed from an older project, so these already had a plaormfor the electronics, and even breadboards and Electronic Speed Controllers. These have a drivemotor to the rear wheels and a servo for steering up front. Baery holders are aached on top ofthe main chassis support of the vehicle. Both the ESC and the steering servo are controlled usingservo input commands. The controller available was the Futaba MC230CR FET Speed Controller.It can go in forward and reverse, with the width of the servo pulse determining how fast or slowit should go. The ESC is programmable by the following direcons:

    1. Send the servo command corresponding to neutral to the ESC

    The main power should be OFF.

    2. Press and Hold the Buon on the ESC for at least half a second

    You will hear a conrmaon beep, and the LEDwill start to blink at a regular interval.

    3. Send the servo command corresponding to Full Speed (Forward) to the ESC

    4. Press and Hold the Buon on the ESC for at least half a second

    You will hear a conrmaon beep, and the LED will start to double blink.

    5. Send the servo command corresponding to Full Brake to the ESC

    6. Press and Hold the Buon on the ESC for at least half a second

    You will hear a conrmaon beep, and the LED will turn o.

    Since servos normally use a range of 1ms-2ms peak, 50Hz PWM signal with 1.5ms as the middlepoint, these are what we used. The reverse funcon can be used aer the ESC is brought back toneutral; then the brake range is the revere range, with a 1ms-wide pulse signifying full reverse.These cars have a sophiscated rack-and-pinion steering system, so the servo in the front only hasa limited range, about 90 degrees. Through tesng we calibrated the rounes to each steeringservo so we didnt try to oversteer the servo. This process is described as part of the PID Coltrollersecon. Below are images of the two cars; the top image is of the clear, and the boom is offrost.

    3

  • 4

  • 2.2 RoboTycoThe fourth car was a Tyco R/C Car in its former life, and it had a slightly dierent drive mechanism;each pair of wheels on either side are aached to a motor via a series of gears, so each side isdriven by a separate motor. It is four-wheel drive, similar to the four-wheel drive system of apickup truck where it usually has to be locked on. This is great for o-roading, and in our caseit greatly simplies steering since the wheels themselves dont turn to steer. In this car to turnle, just run the le motor slightly slower than the right. Since the right wheels now are coveringmore ground than the le, the car has no choice but to turn le. A lile breadboard contains thenew speed controller for the Tyco, the L293 Quadruple Half-H Motor Driver. This controller uses aMOSFET network to turn the motors on and o and segregate the motor power supply from thelogic supply.

    Figure 1: Quadruple Half-H Driver for two motors.

    The drive for eachmotor requires two inputs: A and B. The ENx pins shown in 1 are always highif our system is on, since that is the equivalent of pung the car in Drive. whereas when ENx islow the system is in Neutral, the wheels can spin more or less freely, although they are, in fact,sll aached to the motor1. For each motor, when A is high and B is low the motor rotatesat fullspeedin one direcon, and does the reverse when B is high and A is low. If both are high or bothare low the motor is in a BRAKE mode, where it locks the rotor into posion. This is because thetwo terminals are essenally ed together, causing the inducve load of the motor to be turnedback on itself. In this mode the vehicle comes to a stop very quickly. So this can turn the motorin both direcons at full speed and stop it. In order to get a specic speed we will have to rely onPulse Width Modulaon.

    Below is an image from above of RoboTyco.1Although note that this parcular controller, in the parcular operaon it is in, cannot be in neutral unless the

    power to the Quad Half-H is removed. This is due to the way the outputs behave and interact in high-impedancemode.

    5

  • 2.3 Propeller MicrocontrollerThe propeller microcontroller from Parallax, Inc, is an interesng beast. It really is like every otherhobbyist robocs microcontroller, except for one thing: it has eight cores, referred to as cogs.This is ideal for the robocs applicaon, as there are many things on a robot that need constantaenon. In a convenonal microcontroller multasking is prey dicult. There are sensors andmotors and transceivers that all need clock cycles in order to maintain the robot. But, any meyou need to do something on the propeller, you just put it in a cog and it runs in parallel. Inthe case of the motor controls, the speed values can be put into registers of common ram, to bechanged whenever an external aconsuch as a reading from a sensor, or an immediate HALTsignalneeds control. In this setup there is no need for interrupts, and indeed, they do not ac-tually exist in the propeller assembly language. Just pass a value by reference and messages caneasily be passed between cogs.

    The design is meant to be simple, but powerful. The internal ALUs in each cog do not evensupport mulplicaon or divisionthey do, however, contain log and sine look-up tables to dothe math anyway. The cogs all share the 32 I/O pins. Each cog is serviced in sequence by the hub,so that every eight clock cycles a cog gets to perform a task. Some care does have to be takenso as to not use the same pin in clashing contexts, but the overall simplicity of everything elsemakes this easier. There are also no Analog-to-Digital converters on the device, so we added anMCP3202 to the proto board. It provides two 12-bit analog inputs in a serial interface using four

    6

  • Figure 2: Propeller Proto Board USB Layout

    I/O pins. These analog inputs are used in the inducve wire guidance system described in detailin Secon 2.4. For the vehicles with ESCs and a steering servo, two pins are required for the drivesystem. Since the H-Bridge needs two inputs per motor, four in all are needed for that car.

    This microprocessor is a prey novel concept, but it is dierent than other designs and thattakes some geng used to. Luckily, the propeller has a secret weapon: The Propeller ObjectExchange at hp://obex.parallax.com/. The exchange is a place where the propeller communitycan share their objects with others, and where anyone can get an object to use. There are manyobjects, and we made use of the OBEX for many of the hardware components we had selected.

    The parcularmicrocontrollerwepurchasedwas the Parallax Propeller Proto BoardUSB,whichcontains an on-board USB-to-serial converter that can be used to program the propeller as wellas control another USB device. The board contains the propeller chip itself, an external crystaland oscillator circuit, a 5Volt and 3.3Volt regulator, and is covered everywhere else with platedthrough holes. Some are ed to specic pins, while some are for ground and posive voltages,and others are for special purposes or anything at all.

    1. I/O Pin Headers Around the propeller chip are through holes for each of the propellersI/O pins, as well as pins for VDD(+3.3V) and VSS(Ground). We soldered in header pins toeach pin so we could jumper to the various inputs and outputs.

    2. SERVO Controls The pins in the top-right are for Servo Controls or for anything thatneeds +5V source, Ground and signal connecons. These pins are connected to pins 0-3on the propeller. The jumper to the le selects the servo power supply, here selecng theregulated 5V supply. The baery input itself is selected if the jumper is ipped2.

    2Not recommended when running o of 9 Volt baeries. This seng is for running o of 6 Volt baeries.

    7

  • 3. Keyboard/Mouse and VGA The propeller supports VGA (and NTSC) video as well as P/S2keyboard and mouse connecons. The resistors in the boom-le and the through holesare shaped for these connecons, although they are unused. The propeller contains theability to transmit those signals through the USB, so your computer acts as a terminal. Thiswas used for exploratory purposes, but not in the actual design of the project.

    Since the propeller does not have a nave ADC, we used anMCP3202 Analog-to-Digital Converter.The ADC comes in an 8-pin DIP, and it is interfaced with a standard known as SPI, Serial Pro-grammable Interface. The device has two inputs, and the 12-bit value sent over the SPI is

    ADV = 4096 VSIG VSSVDD VSS

    where ADV = 0 if VSIG VSS and ADV = 4095 when VSIG VDD. The OBEX contains anextensive object that allowed us to easily ulize the device.

    2.4 Wire Guidance SystemIn the cars of the future, all sorts of fancy systems are in use to monitor the environment, most ofwhich are very expensive and physically large. So for our system our roadways consist of a 24AWGenamel-coated magnet wire. The vehicles will then follow this wire using a system referred to asInducve Wire Guidance. The wire is laid out in loops, and hooked up to the generator. The gen-erator then sends an AC signal at around 50kHz down the wire. The signal is generated using a 555mer and a tuned LC circuit. The 555 mer creates a square-wave signal at the frequency desired,and the inductor-capacitor circuit shapes it into a sinusoid. According to Ampres circuital law,a change in current through a wire generates a magnec eld around the wire. In normal mag-nec eld convenon, it is said that the eld curls around the wire, perpendicular to the direconof current ow. So by sending a sinusoidal current down the wire we generate a magnec eldwhose strength changes as a sinusoid. Inductors are just coils of wire, and the specic inductorswe used hereand are necessary for this type of operaon are cylindrical, with a ferromagneccore to amplify the magnec eld. A magnec eld induces a current in the coil that is propor-onal to the eld strength. Therefore, the sinusoid induced in the inductor is the same sinusoidas the current owing through the guidance wire. Magnec eld strength falls o proporonallyas it gets further from the source, so the induced voltage across the coil can be used to tell howfar it is from the wire.

    Now that we have this, we can follow the wire with the cars. One inductor is posioned to thele of the right wheel, and the other mounted just to the right of the le wheel. By pung theproper capacitor in parallel a specic frequency can be selected easily. From here, an operaonalamplier is used to amplify the signal. Noce that the signal is now vS(t) = A sin (!t), and Ais proporonal to the inverse of the distance the sensor is from the wire. This is an AmplitudeModulated (AM) signal. Using a simple envelope detector the signal is demodulated, and thissignal can be fed into the ADC. The general design of the circuitry is taken from a circuit postedby a Lego Mindstorm hobbyist and adapted for our use. We had to take calibraon readings and

    8

  • Figure 3: An inducve guidance system and the generated magnec eld.

    tune the ampliers to give approximately equal inputs to the propeller. Then we could use thevalues as part of the controller to steer the robot over the wire.

    2.5 Collision Detecon SystemThe full-sized cars use millimeter-wave RADAR systems. While they work very well for full-sizedcars, on our small scale and for our budget ultrasonic rangenders are more appropriate. Fortracking the cars or obstacles in front of the car one PING))) Ultrasonic Rangender. In order totell if another vehicle is behind the car, we also ed a rangender in the rear. This acts as therear-view mirror for the system.

    The ultrasonic sensors are very simple, and use only one I/O pin. To use the rangender, thefollowing steps are taken:

    1. Send a pulse down the signal line to the PING))) This pulse tells the ping to start its roune.Aer a short delay the PING))) emits an ultrasonic chirp at 40kHz.

    2. Wait for the signal line to go high the rangender pulls the signal line high when the pulseis sent out. It stays high unl the signal is received back.

    3. Measure the me it takes for the signal line to go low When the PING))) hears its echo itde-asserts the signal line, or it mes out.

    Since sound travels through air at approximately 343meters per second, the distance to the objectis

    distance = speed time = 343m/s t ms

    9

  • distance mm = 343 t ms

    It is convenient (because the propeller object returns it) to talk about me in milliseconds anddistance in millimeters. Note that the speed of sound is aected by temperature, barometricpressure and humidity, but it will aect all rangenders equally, so we can safely ignore it.

    2.6 Wireless CommunicaonWireless Communicaon is essenal to bridging the gap to autonomous roadways. Informaonsent among the cars will let them know of each others intenons. The XBee RF Module by DigiInternaonal ts the bill nicely. The devices use the (admiedly crowded) 2.54GHz wireless spec-trum and the same channels used by WiFi networks. However, these are not 802.11 devices;they use the 802.15.4 standard. This standard was designed to be used for low data-rate, high-eciency communicaons in mobile embedded devices, which is perfect for our needs. The802.15.4 standard consists of a Media Access Control layer on top of a hardware layer, and isdesigned to be bare-metal, but also provide essenal services of a modern protocol. The stan-dard supports collision detecon and avoidance and real-me data transfer through guaranteedme slots. There are many other great features of 802.15.4, but this project does not interfacewith it directly, so it is sucient to note that it is used by the XBee devices.

    The XBee devices actually present themselves to the user as a simple serial data interface. Intransparent mode, two paired XBees act as a drop-in replacement for an RS-232 line. The devicessupport a more advanced mode, API Mode, which is what we used for the wireless communica-on between vehicles. In API mode all data is framed with essenal informaon and transmiedas a packet. In this mode the XBees support both broadcast and point-to-point communicaon.The structure of the data frame is shown in gure 4. The frame is simple: the byte 0x7E is sent,

    Figure 4: Generic Data Frame Structure

    indicang the start of the frame, then the length of the frame is sent, telling the receiver how farto read. All of the data is checksummed for added integrity. Every me a transmit or receive isperformed this data has to be parsed, adding complexity over the transparent mode. However,the advantages far outweigh the complexity issues. Now the network can be fully Ad-hoc. Whentwo cars get close, they nofy each other of their presence. They can then send data directly toeach other in order to nofy the other vehicle of various statuses. When they get too far apartthey terminate the link, which really means not sending data anymore, because there is nothingto build up or tear down. Each XBeeand by extension each vehiclehas a unique address whichcan be found in packets received from the radio and can be used to send messages only to thatradio. The two specic packets we deal with are the transmit (TX) and receive (RX) packets, shownin 5. When transming, the XBee sends a frame ID with the data to the address specied in the

    10

  • Figure 5: TX/RX Packet Data Frame StructureTX Packet

    RX Packet

    desnaon address block. If received the remote XBee will send an acknowledgment3 using theframe ID. On the receiving end the packet contains the data being sent, along with who sent it andthe received strength of the signal. Using these data we designed the communicaons logic forthe devices shown in 4.3

    3 Designing the TrackFor our test track we wanted to test specic features. We did not want to test how well thehardware in our second-hand R/C cars worked, and this included turning radius. So when layingout the wire we were careful not to make the turns that ght. We did, however, want to test thecollision avoidance system. We seled on a gure-eight design, with the track crossing itself inthe middle to form an intersecon.

    The notches in the track are there so that the car knows it is in the intersecon. When theinducve sensors go over the locaon neither one will read high. Because they are both low thealgorithmwill aempt to drive straight, and it will pick up the line on the other side, but for a smallamount of me the car will get the (no) signal it needs. Having an intersecon allows us to testmore condions than with a simple loop. We will be able to nd out if the cars can negoate itthemselves, or if an intersecon requires a third party to be a gatekeeper.

    4 Programming The PropellerAsmenoned above the propeller has a vast collecon of objects at the object exchange. Wewereable to nd objects for controlling the MCP3202 ADC, the XBee radios, the servo controllers andthe PWM generator needed for the H-Bridge driver4. Using these parts the code in the appendixwas wrien. At its heart, the system is controlled by a PID-derived controller that follows the wire,and the behavior is altered based upon the wireless communicaons and the readings from the

    3For this specic project ACKs are ignored.4ADC_Input_Driver.spin, XBee_Object_2.spin, Servo32v7.spin and pwmAsm, respecvely

    11

  • Figure 6: Rough Sketch of Track (Not to scale)

    rangenders. Specic examples in this secon are for the ESC R/C cars, but the concept is verysimilar for the H-Bridge controller. Most parts are completely unchanged, in fact.

    4.1 PID ControllerA PID Controller is a type of feedback system that has a Proporonal part, an Integral part and aDerivave part. The error is measured, and based upon that error the system adjusts to correct forit. With just proporonal control the system can only react to the instantaneous error, leading toa jiery system that is constantly overshoong the ideal. By adding in the integral part the systemcan react to an accumulaon of error. If the system is consistently o in one direcon the integralpart of the feedback can correct for this. The integral feedback is especially useful while goingstraight, as it prevents the wobble of a proporonal system that is constantly moving from oneside of the wire to the other. The derivave part responds to chances in the error. The system canrespond more quickly to larger changes in error, and slower when the error isnt changing much,allowing the proporonal and integral controls to bemore prominent. The derivave control helpswhen turning, because of the large change of the wire veering away from the vehicle.

    f (t) = Kpe (t) +Kp

    e (t) dt+Kd

    e (t)

    dt

    Of course, in our system this exact controller would be dicult to implement. To get the be-haviors of a PID controller the following code was used:

    repeat

    12

  • pre_cnt := cnterror := chanval[0] - chanval[1] * chanmax[0] / chan-max[1] 'channel 0: Right, channel 1: Left

    P := Kp * errorI += Ki * errorD := Kd * (error - pre_error)cur_pos := -1000 #> (cur_pos + cur_speed * (P + I + D) / 1_000_000) 0)servo.set(steer_pin, cur_pos * (max_left -center) / 1_000 + center)

    elseservo.set(steer_pin, cur_pos * (center -max_right) / 1_000 + center)

    pre_error := error

    waitcnt(pre_cnt + clkfreq / 50)

    This code runs once every 50th of a second, or 20milliseconds. This is the period of the servopulse,so it gives the steering servo me to align itself. First the error is calculated as the dierence of thereadings from the ADC, corresponding to how far to the right of center the vehicle has dried. theP term is proporonal to this error. The I term is an accumulaon of this error. This behaves likethe integral control, because integraon is just a sumwith very small change in me. The D term isproporonal to the change in error from the previous me. Again, this acts like the real derivavecontrol. the current steering posion, cur_pos, is then changed by the sum of the three parts,scaled by the current speed. This is to prevent the car from over-steering at lower speeds. Thatposion is then mapped to real servo pulsed to drive the steering servo in the opposite direconof the error. This is not a PID controller, but it is in the PID family. This modied PID controllerallows the cars to follow the wire system.

    4.2 Collision avoidanceThe controller for steering above is great if there is only one vehicle on the road. But since wehave three, we need to be mindful of collisions. Here we use the front mounted rangender.

    if (ping_ranges[0] > 2 * f_dist)cur_speed := (cur_speed + accel) f_dist)

    cur_speed := (cur_speed + (ping_ranges[0] -f_dist) * accel / f_dist) f_dist / 2)cur_speed += (cur_speed - (f_dist -ping_ranges[0]) * 2 * accel / f_dist) #> -1000

    13

  • elsecur_speed := -500servo.set(esc_pin, cur_speed * (max_forward -neutral) / 1_000 + center)

    A following distance, f_dist, is specied in the constants denion block. This corresponds toour two-second rule. When the vehicle is clear of the following distance (range is greater thantwice the following distance) the car accelerates up to its maximum speed. When the vehiclestarts to get close to the vehicle in front it accelerates more slowly to avoid running down amuch slower vehicle by accelerang too quickly. If the vehicle gets inside the following distance itslows, decelerang twice as fast as it accelerates on the other side of the following distance. Thisshould keep it right around the following distance. The next term relates to the panic state. If avehicle gets within half the following distance it applies the brake, stopping as fast as possible. Ifa staonary object is in the road the vehicle will come to a complete stop, and when it is removedit will keep going. The two parts together represent the autonomous control of the vehicle. Morecomplex behavior is exhibited in the wireless communicaon code, which allows the cars to reactto what other cars are doing, or are going to do.

    4.3 XBee WirelessWith the controllers above running the vehicles can react tomost things, but not everything. Withwireless communicaon, however, extra scenarios can be accounted for. For example, when onecar is following another the gap can be maintained without communicaon, but if one car slowsrapidly, say, for an exit ramp that gap will shrink quickly before expanding again. Intersecons arealso dicult, because there are complex interacons that need to take place, and sensing the carscoming in the other direcon can be dicult. However, if the cars can announce their intenonsto each other the process can become much simpler. The XBee Object from the OBEX also takescare of API mode packet parsing, so the essenal features of the packetsthe data and who sentitare the only things we needed to deal with. The rst part of the main loop is copied below:

    if ( ctr < cnt -clkfreq ) ' don't try to pair more than every second

    if ( ping_ranges[0] >= clr_rng_f )front_addr := -1if ( ping_ranges[1] >= clr_rng_f )

    rear_addr := -1if ( front_addr == -1 or rear_addr == -1 )

    xb.API_Str(BC_addr, string("seeking"))ctr := cntseeking := ( front_addr == -1 or rear_addr == -1 )

    In this part, the vehicle disassociates paired vehicles if they have moved out of range of thePING)))s. This housekeeping is required so that it can pair with another vehicle that may come

    14

  • up from behind or that it might catch up to5. It then checks if it should search for other cars topair with. If it is not paired wither in the front or back then it iniates pairing by broadcasng themessage seeking. When other cars receive this message they will reply in a manner outlined inthe message recepon part of the loop. The next part of the loop, below, is a check for enteringthe intersecon.

    if ( chanval[0] < chanthresh and chanval[1] < chanthresh )if ( in_intersection )

    in_intersection~else

    in_intersection~~xb.API_Str(BC_addr, string("intersection"))

    As described in secon about the track, there are notches built into the track just before andjust aer the intersecon. Here the inducve sensors will not see much at all. The threshold(chanthresh) is measured beforehand so that as long as the vehicle is over thewire at least onesensor will be above that value. When the car enters the intersecon it announces to everyonenearby that it does so. Again, the handling for this is in themessage recepon part, which is wherewe are now.

    xb.API_RxTime(20)if ( xb.RxIdent == $81 )

    case xb.RxDatastring("seeking"):

    if ( front_addr == -1 and ping_ranges[0] < clr_rng_f )neg_addr := xb.srcAddrxb.API_Str(neg_addr, string("front"))elseif ( rear_addr == -1 and ping_ranges[1] < clr_rng_f )

    neg_addr := xb.srcAddrxb.API_Str(neg_addr, string("rear"))string("front"):

    if ( seeking )if ( rear_addr == -1 and ping_ranges[1] < clr_rng_f )

    rear_addr := xb.srcAddrxb.API_Str(rear_addr, string("pair_front"))string("rear"):

    if ( seeking )if ( front_addr == -1 and ping_ranges[0] < clr_rng_f )

    front_addr := xb.srcAddr

    5In our parcular test setup this cannot happen because there is only one lane, but for a more roust implementa-on and for clarity it is here.

    15

  • xb.API_Str(rear_addr, string("pair_rear"))string("pair_front"):

    if ( xb.srcAddr == neg_addr )front_addr := neg_addr~~string("pair_rear"):

    if ( xb.srcAddr == neg_addr )rear_addr := neg_addr~~string("intersection"):if ( xb.srcAddr rear_addr and xb.srcAddr front_addr and (not in_intersection) )

    cur_speed -= 100if ( rear_addr -1 )

    xb.API_Str(rear_addr, string("slowdown"))string("slowdown"):

    if ( xb.srcAddr == front_addr )cur_speed -= 100if ( rear_addr -1 )

    xb.API_Str(rear_addr, string("slowdown"))

    The rst thing to do is actually receive the message. This is done with a 20ms meout so that theloop doesnt get stuck innitely. For this exercise we only want to parse receive packets, whichare denoted by the hex value 0x81 in the API idener block. The seeking message starts apairing process. The vehicle makes its best guess as to whether it is in front of or behind thebroadcasng car, and sends that back to the car. If the originang car agrees with the decision itsends back a pairingmessage. Then both cars take note of the address of the car in front of/behindthem. Now the cars can send each other important informaon. In this case that informaon isslowdown. This allows the car to nofy the following vehicle that it is slowing down. When aslowdown message is received the vehicle slows down, and sends the same message to the carbehind it. This will negate at least some of the rubber-banding that would happen without suchpreempve acon. The only message le, then, in the intersecon message. Receiving thismessage means someone near you has entered the intersecon. A check is made to see if the carin front (or behind) is the one who sent it, because there is no need to yield to that car. If not,then a slowdown message is sent to keep from colliding in the center. These methods create acomplete system of autonomous vehicles.

    5 Future WorkThis system is just the start of the testbed. More complex behaviors can be programmed, andspecic scenarios can be constructed to test various aspects of driving. In our test trials we usedone lane and modeled an intersecon. For the future, an expansion to mulple lanes in order tosimulate a highway is a clear area of interest. With mulple lanes, dierent frequencies can beused for each wire, allowing the cars to lock onto the lane they want. Mulple lanes also opens

    16

  • the door for much more complex behavior and trac analysis. Hand-in-hand with this is a morecomplex wireless protocol with more commands and more sophiscated pairing procedures.

    Adding in staonary transceivers is also an area of future expansion. These can act as au-tonomous signposts, warning of trac or weather condions at an exit, for instance. More im-portantly, they can act as gatekeepers. They canmoderate heavy intersecons, or any interseconat all, allowing the vehicles to pass through without crashing.

    6 ConclusionThe overall goal was to create a test environment for exploring concepts of autonomous vehiclesand trac control. Our system involves magnec roadways created by a signal generator andmagnet wire, vehicles with sensors for the roadway and for detecng other vehicles/obstacles,and a wireless point-to-point ad-hoc network that allows the vehicles to communicate with eachother. Using these parts as the test bed many concepts of trac control can be carried out, andmore can be learned about how to build a completely autonomous road network. The futureof driving is in this type of technology, and designing the test bed provided insight into just howdicult it is to drive a car amongst other cars.

    7 Cost BreakdownItem Cost Per Item Quanty Total

    Propeller Proto Board $25 3 (one per car) $75XBee Wireless Modem $23 3 (one per car) $69PING))) Rangender $32 6 (two per car) $192

    Solderless Breadboard and electrical components $25 (approx) 3 (one per car) $75Magnet Wire for Track $27 1 (2000) $27

    Signal Generator Electrical Components $12 (approx) 1 $12Total $450

    We got our R/C car plaorms second-hand, so they cost us nothing. Searching around eBaywould get similar plaorms for around $35 each, bringing the total to around $555.

    8 Work Responsibility BreakdownMichael Jones

    Wire Guidance Track Design

    Signal Generator Circuit design and tuning Inducve Sensor Circuit design and tuning Track Feature Design (How to test features of the autonomous network)

    17

  • Small Car (H-drive) drive train

    Opmal Chassis Sensor Layout and PING sensor calibraon

    XBee radio sengs for simulaon

    David Trethewey

    Propeller Proto Board Design

    ESC-Based Drive Train

    Propeller programming

    XBee packet state machine design

    Shared

    Overall design and construcon of vehicles

    Non-wireless algorithms (sensors and drive control)

    Feature Tesng

    ReferencesLego Wire Guidance Sensor Page - Phil Hurbain

    hp://www.philohome.com/sensors/loguide.htmInducve Guidance - AGV Electronicshp://www.agve.se/page/by_desc/inducve-guidanceXBee Manual - Digi Electronicshp://p1.digi.com/support/documentaon/90000982_B.pdfXBee Parallax Tutorial - Parallax, Inc.hp://forums.parallax.com/showthread.php?124213-Wireless-indexPropeller Manual v1.1 - Parallax, Inchp://www.parallax.com/Portals/0/Downloads/docs/prod/prop/WebPM-v1.1.pdfPropeller Chip forums - Parallax, Inc.hp://forums.parallax.com/forumdisplay.php?65-Propeller-ChipMCP3202 Datasheet - Microchip, Inc.ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdfNE555 Datasheet - Fairchild Semiwww.fairchildsemi.com/ds/LM/LM555.pdfFutaba MC230CR ESC Manual - Futaba, Inc.hp://manuals.hobbico.com/fut/futm0922-manual.pdfL293Ne - Texas Instrumentshp://focus..com/general/docs/lit/getliterature.tsp?genericPartNumber=l293&leType=pdf&track=no

    18

  • Appendix - Propeller CodeThe objects from the object exchange used are:

    XBee_Object_2 XBee Transciever AT-API Object : hp://obex.parallax.com/objects/146/Servo32v7 Servo32v7 : hp://obex.parallax.com/objects/51/pwmAsm [modied] Dedicated pwm generator : hp://obex.parallax.com/objects/216ADC_INPUT_DRIVER ADC Input Driver : hp://obex.parallax.com/objects/488

    Modied pwmAsmModied to use both counters so two pwm signals come from one cog.

    {A simple pwm object based on code from AN001 -propeller counters

    Author: Jev Kuznetsovdate : 16 Oktober 2007Modified by David Trethewey, 24 Apr 2011usageOBJ

    pwm : pwmAsm....pwm.start( Pin) ' start pwmpwm.SetPeriod( period ) ' set pwm pe-riod in clock cycles

    pwm.SetDuty( duty) ' set duty in %pwm.Stop}VAR

    long cogon, coglong aDuty ' order impor-tant (the variables are read from memory in this order)

    long aPinOutlong aCtrVallong sPeriodlong bDuty ' order impor-tant (the variables are read from memory in this order)

    long bPinOutlong bCtrVal

    PUB Start(aPin, bPin) : okay'start pwm on Pin @ 80 kHz

    longfill(@aDuty, 0, 8)

    19

  • aDuty := 0 ' default dutyaPinOut := |< aPinaCtrVal := %00100 1000)

    counts := 1000aDuty :=counts*sPeriod/1000PUB SetDuty_b(counts)

    if (counts < 0)counts := 0if (counts > 1000)

    counts := 1000bDuty :=counts*sPeriod/1000DAT'assembly cog which updates the PWM cycle on APIN'for audio PWM, fundamental freq which must be out of au-ditory range (period < 50S)

    orgentry mov t1, par 'get first parameter

    rdlong valuea, t1

    add t1, #4rdlong pinOuta, t1or dira, pinOuta ' set pinOut to output

    20

  • add t1, #4rdlong ctraval, t1mov ctra, ctraval 'estab-lish counter A mode and APIN

    add t1, #4rdlong period, t1add t1, #4mov par1, t1rdlong valueb, t1

    add t1, #4rdlong pinOutb, t1or dira, pinOutb ' set pinOut to output

    add t1, #4rdlong ctrbval, t1mov ctrb, ctrbval 'estab-lish counter B mode and APIN

    mov frqa, #1 'set counter to in-crement 1 each cycle

    mov frqb, #1 'set counter to in-crement 1 each cycle

    mov time, cnt 'record current timeadd time, period 'establish next period:loop rdlong val-uea, par 'get an up to date pulse width

    rdlong valueb, par1waitcnt time, period 'wait until next period

    neg phsa, val-uea 'back up phsa so that it trips "value" cy-cles from now

    neg phsb, valuebjmp #:loop 'loop for next cycleperiod res 1time res 1valuea res 1t1 res 1pinOuta res 1ctraval res 1par1 res 1valueb res 1pinOutb res 1ctrbval res 1

    21

  • Watch_All_Pings' Watch_All_Pings.spin' David Trethewey'' Object to ask each PING))) rangefinder what its cur-rent reading is' asks each one in succession, accord-ing to the pins listed in pins[].' Code does all of its work sequen-tially, and runs in one cog. Does not' support more than eight rangefinders, be-cause each reading could take' up to 20ms, and it was easier to code that way.

    VARbyte cog ' Keep track of started coglong pins ' Which pins to read (address)long ranges ' ranges of said pins (address)long mask ' Enables/Disables pins (address)

    long stack[32] ' stack space for new cogOBJ

    ping : "Ping"PUB start(pins_ptr, ranges_ptr, mask_ptr)

    stopcog := cognew(monitor(pins_ptr, ranges_ptr, mask_ptr) , @stack)

    return cogPUB stop

    if (cog > -1)cogstop(cog)cog := -1PUB monitor(pins_ptr, ranges_ptr, mask_ptr)| loop

    pins := pins_ptrranges := ranges_ptrlongfill(@ranges, 0, 8)mask := mask_ptrrepeat

    repeat loop from 0 to 7if (byte[mask] >> loop // 2)long[ranges][loop] := ping.millimeters(long[pins][loop])

    elselong[ranges][loop] := 0

    22

  • Wire_Follow_hWire following code with collision detecon for the h-bridge, no communicaon. There is alsoone for the esc, but the changes are idencal to the changes found in Wire_Follow_Xbee.

    ' Wire_Follow_H.spin' David Trethewey' powers the R/C car with the H-Bridge and makes it fol-low the wire, with collision detectionCON

    _clkmode = xtal1 + pll16x_xin-freq = 5_000_000 'Note Clock Speed for your setup!!

    max_forward = 2_000neutral = 1_500max_reverse = 1_000max_left = 1_500max_right = 1_000center = 1_250

    left_a = 0left_b = 1right_a = 2right_b = 3accel = 20DTPin = 19INPin = 18ClkPin = 17RSPin = 16

    Ping_f = 24Ping_r = 25f_dist = 500 'Dis-tance in mm to stay behind vehicle

    Kp = 500Ki = 50Kd = 10OBJ

    pwm : "pwmAsm"adc : "ADC_INPUT_DRIVER"pings : "Watch_All_Pings"VAR

    long chanstate[2]

    23

  • long chanval[2]long chanmax[2]long chanmin[2]

    long ping_pins[8]long ping_ranges[8]byte ping_masklong cur_poslong cur_speedlong stack[32]

    PUB Mainping_pins[0] := ping_fping_pins[1] := ping_rping_mask := %0001pings.start(@ping_pins, @ping_ranges, @ping_mask)adc.start_pointed(DTPin, IN-Pin, ClkPin, RSPin, 2, 2, 12, 1, @chanstate, @chan-val, @chanmax, @chanmin)

    dira[left_b]~~dira[right_b]~~outa[left_b]~outa[right_b]~pwm.start(left_a, right_a)

    cognew(WireFollow, @stack)PRI WireFollow | pre_cnt, error, pre_error, P, I, D

    cur_pos := 0cur_speed := 0pre_error := 0

    repeatpre_cnt := cntif (ping_ranges[0] > 2 * f_dist)

    cur_speed := (cur_speed + accel) f_dist)

    cur_speed := (cur_speed + (ping_ranges[0] -f_dist) * accel / f_dist) f_dist / 2)cur_speed += (cur_speed - (f_dist -ping_ranges[0]) * 2 * accel / f_dist) #> -1000

    else

    24

  • cur_speed := 0error := chanval[0] - chanval[1] * chanmax[0] / chan-max[1] 'channel 0: Right, channel 1: Left

    P := Kp * errorI += Ki * errorD := Kd * (error - pre_error)cur_pos := -1000 #> (cur_pos + cur_speed * (P + I + D) / 1_000_000) 0)outa[left_b]~outa[right_b]~pwm.SetDuty_a((cur_speed * max_forward + cur_pos * max_left) / 1000)pwm.SetDuty_b((cur_speed * max_forward + cur_pos * max_right) / 1000)else

    outa[left_b]~~outa[right_b]~~pwm.SetDuty_a(1000 -(cur_speed * max_forward + cur_pos * max_left) / 1000)

    pwm.SetDuty_b(1000 -(cur_speed * max_forward + cur_pos * max_right) / 1000)

    pre_error := error

    waitcnt(pre_cnt + clkfreq / 50)

    Wire_Follow_XbeeIdencal Wire_Follow_h_Xbee with changes as noted above.

    ' Wire_Follow_Xbee' David Trethewey' Uses servo controls to drive the esc con-trolled cars, and uses XBee to communicate with other cars.CON

    _clkmode = xtal1 + pll16x_xin-freq = 5_000_000 'Note Clock Speed for your setup!!

    max_forward = 2_000neutral = 1_500max_reverse = 1_000max_left = 1_500max_right = 1_000center = 1_250

    25

  • esc_pin = 7steer_pin = 6accel = 20DTPin = 19INPin = 18ClkPin = 17RSPin = 16chanthresh = 50

    Ping_f = 24Ping_r = 25clr_rng_f = 3000clr_rng_r = 3000f_dist = 500 'Dis-tance in mm to stay behind vehicle

    XB_Rx = 0 ' XBee DOUT (pin 2)XB_Tx = 1 ' XBee DIN (pin 3)XB_RS = 2 ' XBee RS (pin 5)XB_Baud = 38400 ' Communication SpeedBC_addr = $FFFFKp = 500Ki = 50Kd = 10OBJ

    servo : "Servo32v7"adc : "ADC_INPUT_DRIVER"pings : "Watch_All_Pings"xb : "XBee_Object_2"VAR

    long chanstate[2]long chanval[2]long chanmax[2]long chanmin[2]

    long ping_pins[8]long ping_ranges[8]byte ping_masklong cur_poslong cur_speedlong stack[32]long front_addr

    26

  • long rear_addrlong neg_addrbyte in_intersection

    PUB Mainping_pins[0] := ping_fping_pins[1] := ping_rping_mask := %0011pings.start(@ping_pins, @ping_ranges, @ping_mask)adc.start_pointed(DTPin, IN-Pin, ClkPin, RSPin, 2, 2, 12, 1, @chanstate, @chan-val, @chanmax, @chanmin)

    xb.start(XB_Rx, XB_Tx, 0, XB_Baud)front_addr := -1rear_addr := -1neg_addr := -1in_intersection~cognew(transceive, @stack)

    servo.startservo.set(esc_pin, neutral)servo.set(steer_pin, cen-ter)

    cognew(WireFollow, @stack)PRI WireFollow | pre_cnt, error, pre_error, P, I, D

    cur_pos := 0cur_speed := 0pre_error := 0

    repeatpre_cnt := cntif (ping_ranges[0] > 2 * f_dist)

    cur_speed := (cur_speed + accel) f_dist)

    cur_speed := (cur_speed + (ping_ranges[0] -f_dist) * accel / f_dist) f_dist / 2)cur_speed += (cur_speed - (f_dist -ping_ranges[0]) * 2 * accel / f_dist) #> -1000

    elsecur_speed := -500servo.set(esc_pin, cur_speed * (max_forward -

    27

  • neutral) / 1_000 + center)error := chanval[0] - chanval[1] * chanmax[0] / chan-max[1] 'channel 0: Right, channel 1: Left

    P := Kp * errorI += Ki * errorD := Kd * (error - pre_error)cur_pos := -1000 #> (cur_pos + cur_speed * (P + I + D) / 1_000_000) 0)servo.set(steer_pin, cur_pos * (max_left -center) / 1_000 + center)

    elseservo.set(steer_pin, cur_pos * (center -max_right) / 1_000 + center)

    pre_error := error

    waitcnt(pre_cnt + clkfreq / 50)PRI Transceive | seeking, ctr

    repeatif ( ctr < cnt -clkfreq ) ' don't try to pair more than every second

    if ( ping_ranges[0] >= clr_rng_f )front_addr := -1if ( ping_ranges[1] >= clr_rng_f )

    rear_addr := -1if ( front_addr == -1 or rear_addr == -1 )

    xb.API_Str(BC_addr, string("seeking"))ctr := cnt

    seeking := ( front_addr == -1 or rear_addr == -1 )if ( chanval[0] < chanthresh and chanval[1] < chan-thresh )

    if ( in_intersection )in_intersection~else

    in_intersection~~xb.API_Str(BC_addr, string("intersection"))

    xb.API_RxTime(20)if ( xb.RxIdent == $81 )

    case xb.RxDatastring("seeking"):

    28

  • if ( front_addr == -1 and ping_ranges[0] < clr_rng_f )

    neg_addr := xb.srcAddrxb.API_Str(neg_addr, string("front"))elseif ( rear_addr == -1 and ping_ranges[1] < clr_rng_f )

    neg_addr := xb.srcAddrxb.API_Str(neg_addr, string("rear"))string("front"):

    if ( seeking )if ( rear_addr == -1 and ping_ranges[1] < clr_rng_f )

    rear_addr := xb.srcAddrxb.API_Str(rear_addr, string("pair_front"))string("rear"):

    if ( seeking )if ( front_addr == -1 and ping_ranges[0] < clr_rng_f )

    front_addr := xb.srcAddrxb.API_Str(rear_addr, string("pair_rear"))string("pair_front"):

    if ( xb.srcAddr == neg_addr )front_addr := neg_addr~~string("pair_rear"):

    if ( xb.srcAddr == neg_addr )rear_addr := neg_addr~~string("intersection"):if ( xb.srcAddr rear_addr and xb.srcAddr front_addr \

    and (not in_intersection) )cur_speed -= 100if ( rear_addr -1 )

    xb.API_Str(rear_addr, string("slowdown"))string("slowdown"):

    if ( xb.srcAddr == front_addr )cur_speed -= 100if ( rear_addr -1 )

    xb.API_Str(rear_addr, string("slowdown"))

    29

    Motivation and ObjectiveRobotic Vehicle DesignR/C RetrofitRoboTycoPropeller MicrocontrollerWire Guidance SystemCollision Detection SystemWireless Communication

    Designing the TrackProgramming The PropellerPID ControllerCollision avoidanceXBee Wireless

    Future WorkConclusionCost BreakdownWork Responsibility Breakdown