Autonomous Vehicle - Part 5 - Race Day

Spent a fantastic weekend in Boulder for the 2nd annual Sparkfun Autonomous Vehicle Competition 2010. We went to the 2009 AVC and had a blast, but this year we entered a vehicle and saw a whole new dimension of the event through a competitor’s perspective. We were “Team Buzzcut” and my wife named our vehicle “Roscoe”.
DSCF5057
“Roscoe” - the ESawdust Team Buzzcut autonomous vehicle

We came in 6th for ground vehicles out of 13 ground vehicle teams which actually started the race. Numerous teams dropped out at the last minute as they were debugging right up to the first heat - there were 30 entrants including ground vehicles and UAVs.

Think of the Sparkfun AVC as the DARPA Grand Challenge on a mini (affordable) scale. Sparkfun AVC has two categories, ground vehicles and UAVs.  I have to say the UAVs stole the show this year with some picture perfect autonomous landings and one even performed a vertical autonomous takeoff with some autonomous aerobatics.   It's really quite a spectacle for the geek-minded.

There were vehicles built on all kinds of physical platforms including a beer cooler, an electric wheelchair, kiddy cars, and some truly dangerous looking stuff that had no name and probably should have been in battle-bots instead.   There was one team who entered but for some reason couldn't come, but they had built their autonomous vehicle based on a riding lawn mower. That would have been a hoot to see - too bad they couldn’t come.

Teams came from all over, including Great Britain.  The best UAV team was from the University of Arizona engineering school...they were simply awesome but all the UAV teams were really fantastic.

My son, Nakoa, helped me out with Roscoe and this is a shot of Nakoa taken by my friend, Oleg Mazurov (circuitsathome.com), on race day. Nakoa’s setting the vehicle down on the starting line for heat #2:
cox01
Here’s another shot taken by Oleg of the vehicle, Roscoe, just after launch:
cox02
We were on the standby list of competitors until after the first of April as some teams couldn’t produce the requisite video showing their vehicle in autonomous motion or dropped out for other reasons. So, fortunately, we got moved up and into the competition but rather a late start for serious development - especially for the navigation code.

I’ve been writing this series on autonomous cars and even a week before the competition thought we’d be going with an 1/18 scale R/C car but changed horses mid-stream and it’s been a frenetic pace to try to get everything running for the competition - not much blogging about it, just heads down trying to get it done.

The horse we changed to was a 1/10th scale Losi Rock Crawler (model “Night Crawler”). The reasons were several-fold. 1) the 1/18th scale only had about a 1/4” of clearance once I had everything installed on it. 2) even the slowest speed I could make the car go was too fast for getting things debugged. We were so close to the event I didn’t have time to mod the car, so I looked for a naturally low-geared vehicle and thought about the crawler. It was the fast way to a robust mechanical platform for the race and had the added benefit of handling some curbs.

I had to move the autonomous electronics platform from the Team Associated car to the Rock Crawler. Found out first thing that the Losi signals for forward and backward were reverse from the Team Associated. It was an easy fix in my firmware, and after that it wasn’t long before I had the new vehicle moving.

Ours was about the only vehicle that didn't have wires and poles poking out of it like a porcupine - turned out to be a good thing because the 3rd heat was ran in the rain so we had a good lid. All the firmware was written in C.  Was up late every night last week trying to cram it all together...felt like a senior design project in engineering school.

Here's a shot of me in the team pit area inside Sparkfun:
DSCF5073
The vehicle communicates diagnostic data and also takes the start and kill commands from the MacBook via an XBee Pro 900. I wasn’t sure if I was going to see interference from other XBee users and had the system live for about 45 minutes before the start of the race when I saw my first evidence of someone on my channel. I quickly reprogrammed the XBee radios for a different channel and did not see any further interference.

Here’s a shot of the general pit area inside Sparkfun before it got completely filled up:
DSCF5071
Our second heat on the 2nd leg, Roscoe headed for a curb, climbed the curb with its front right, then back right wheel and drove half the length of the building with two wheels on the asphalt and two wheels on the curb.   The second milestone was at the end of the drive along this curb, so I thought maybe he'd gotten lucky and would ride the rail all the way to the 2nd checkpoint. Here’s a video of Roscoe riding the curb until he dumped on his lid:



The electronics sat on top of the aluminum cage that houses the motor and transmission.  Not sure if you can see it in this picture, but I put a piece of black non-conductive foam layered between the board and the battery.  Then, on each corner of the board I attached a spring to the cage.  So, the board could move around, but was pretty secure.  
DSCF5066
(I only noticed later after taking this picture the “Fresh Step” in the background. Thought it actually fit this picture pretty well :-)
The picture below you can make out the springs that fastened the electronics to the metal cage.
DSCF5069DSCF5053
Because the board added extra height to the chassis, we punched new holes in the body to lift the body above and protect the electronics.  So, when the vehicle rolls, the electronics aren't touched.  You can see the cotter pins in the body in the new holes with the old holes about an inch above them.
DSCF5056DSCF5055
DSCF5049
I think he looked pretty handsome on race day - one of the few bots that didn’t look like Jetson’s Rosie: - We were not bristling with sensors (to a fault - we only had GPS.)
cox02
I spent at least two nights working on two different Sparkfun digital compass modules, but unless I mounted them very high, the motors perturbed them so much I couldn’t use them. I had all my navigation code written to use headings and GPS waypoints. The digital compass wasn’t accurate when it was attached so closely to the vehicle, the crawler goes slow enough that GPS heading isn’t accurate, and I simply ran out of time, so I ended up ripping all my heading based compass code out and going with a very simple steering algorithm.

Each leg of the journey had a different rule set for steering. It more or less worked but it was 1am of the morning of the competition and I ran out of gas trying to refine it further. I was in my brother’s garage near Sparkfun the night before doing mission after mission refining an algorithm based on relatively inaccurate GPS data.

I’ll go into the steering algorithm in a different blog post as well as present code for communicating with at least two of the Sparkfun digital compass modules.

It was a blast - stressful fun, actually - to come up with something that wouldn’t flop in front of a couple hundred spectators.

We’ll definitely be back next year - wiser, smarter, and possibly more Rosie-looking.

Team Buzzcut Rosoe the Rock Crawler on Heat #1:

Heat #2

Heat #3


Landon Cox
www.ESawdust.com

Other articles in this series:
Building Bots with Kids
Autonomous R/C Car - Part 1 - Reverse Engineering Signals
Autonomous R/C Car - Part 2 - Taking Control
Autonomous R/C Car - Part 3 - GPS
Autonomous Vehicle - Part 4 - Mechanical, Firmware

Autonomous R/C Car - Part 2 - Taking Control

Synopsis: This is Part 2 in a series of turning an R/C car into an autonomous vehicle and presents how to generate pulse width modulation signals (PWM) required to control a steering servo and motor controller of a typical R/C car. The purpose is to replace the manual radio control mechanism with a microcontroller which can ultimately control the vehicle autonomously. Example code and tests are presented with video showing the motor and steering under microcontroller control. Navigation algorithms will be covered in future articles. The focus of this article is how to make the car turn and change speed using an ATMega128 AVR microcontroller.

Below is a video of the example test code exercising the R/C car on the workbench. I have the car propped up on a small pedestal, a Sparkfun enclosure lid, so it won’t run away (handy enclosure :-) After the video are extensive details of implementing PWM for servo control on ATMega128 AVR.



R/C car showing PWM waves on scope

The photo above shows the car under test with the scope showing the PWM waves generated by the micro - yellow for steering and blue for motor. The test setup is being driven by an ESawdust designed AVR development board.

In Part 1 of this series, we reverse engineered the signals coming from the R/C radio receiver in the car and learned how the speed and steering signals controlled the stock vehicle. This confirmed the typical servo PWM wave form for both steering and motor control.

Our next task is to emulate these signals with our own microcontroller so we can start working up the stack of tasks needed to take autonomous control of the vehicle. That’s what this article is about.

Why Not Use Existing Servo Libraries for the AVR?



There are many servo libraries out there which we could use, but one of the main objectives of this project is to learn autonomous control from the ground up, so deriving certain fundamental operations like steering and motor control is both part of the fun and a main objective.

ATMega128 Development Board - The ESawdust RAD-GPS



We chose an ATMega128 AVR micro instead of an Arduino (ATMega168 or 328) because ATMega128 has two serial ports and I expect to need both serial ports for the firmware as we get into the higher level navigation code. The serial ports will support the GPS data stream and also a data radio for diagnostics or external control.

The ATMega architecture also has builtin timing support and PWM functionality, so it was a natural choice for autonomous vehicle control. We could “bit-bang” a PWM wave if we wanted to but that would be a waste of processor cycles since the timing work can be handled by the micro directly in hardware, and we just need to figure out the setup and control. We need the processor cycles for navigation computation and situational awareness (obstacle detection and avoidance), not manually making a PWM wave.

Last fall, I designed a PCB which carries an ETT AVR (ATMega128) stamp board, has builtin in hardware support for a 4Hz Falcom FSA03 GPS and XBee data radio. The board is called a RAD-GPS (which stands for “radio-gps”) and I’m planning on making the board available on the ESawdust store shortly. The board has a builtin wide-range input power supply and regulator up to 1 amp, builtin 3.3-to-5V signal level conversion to safely interface the 5V AVR micro to the 3.3V GPS and 3.3V XBee. It also includes a prototyping area, status LEDs, breakouts for ATMega128 AVR, XBee and GPS and finally supplies a JTAG interface for programming and debugging. This article covers ATMega128, so any dev board for ATMega128, such as the ETT AVR dev board, could be easily adapted also.

Here’s a shot of the RAD-GPS we’re using as the AVR dev board for our autonomous r/c car:

ESawdust RAD-GPS

While the RAD-GPS is able to support any of the XBee modules because they are electrically pin compatible, I plan to use the XBee 900 Pro. From my experience in the great pumpkin launch last fall, I was impressed with the XBee 900 Pro and its great comms. I expect I’ll use the loose wire antenna version of the XBee 900 Pro rather than the rubber duck shown in the image above.

For very long range applications, the RAD-GPS PCB also supports the FreeWave MegaMini 2, a high-end, 1 watt, 902-928 MHz data radio capable of comms up to 60 miles line of sight ( directed RF ), but that’s total overkill for an autonomous R/C car, so we’ll stick with XBee.

Overview of PWM with ATMega128



Not surprisingly, it’s critical to sidle up to the ATMega128 datasheet at Atmel in order to understand how to set up PWM. ATMega128 is perfect for controlling up to 3 servos with one timer and 3 servos is more than we’ll need for this project.

In addition to one main timer for PWM set up, ATMega128 supplies 3 registers per timer which govern the duty cycle of up to 3 different PWM waves connected to 3 different pins on the micro. There are other convenient functions of the ATMega which allow the programmer to specify both inverted and non-inverted waves as well as pure 50% duty cycle waves. We’ll use the non-inverted wave form for servos since we mainly just want to specify how long the signal should be held high rather than how long the signal will be low.

There are various modes of PWM supported by ATMega128 which is both good because it’s flexible, but bad because it makes you have to dig a lot to find what you need. We’ll use what’s called Phase and Frequency Correct PWM which uses an up-down counter for the period and a variable threshold to adjust the duty cycle of the PWM wave. The data sheet has this to say about it:

The phase and frequency correct Pulse Width Modulation, or phase and frequency correct PWM mode (WGMn3:0 = 8 or 9) provides a high resolution phase and frequency correct PWM wave- form generation option. The phase and frequency correct PWM mode is, like the phase correct PWM mode, based on a dual-slope operation. The counter counts repeatedly from BOTTOM (0x0000) to TOP and then from TOP to BOTTOM. In non-inverting Compare Output mode, the output compare (OCnx) is cleared on the compare match between TCNTn and OCRnx while counting up, and set on the compare match while downcounting. In inverting Compare Output mode, the operation is inverted. The dual-slope operation gives a lower maximum operation fre- quency compared to the single-slope operation. However, due to the symmetric feature of the dual-slope PWM modes, these modes are preferred for motor control applications.



According to the datasheet, this is the “preferred for motor control” mode (motor being the servo) and generating a 20ms PWM wave is not pushing the limits whatsoever of this mode (as you’ll see from the calcuations we do below.) In fact, having it be relatively “slow” is just fine for us. For other applications, ATMega also has “fast PWM” modes where the counter is only up or down, but the up-down counter works better for PWM for servos.

You’ll see in a moment why an up-down timer counter works so well for generating a PWM wave.

It’s worth noting in an overview of ATMega PWM is that in order to get a PWM signal out of the micro, specific multi-function pins, must be set for a data direction of output. The multi-function pins on the ATMega128 that are internally wired for PWM output are OC1A, OC1B, and OC1C (port B, pins 5, 6 and 7.). We won’t need any interrupts from PWM - we just want to set it up to constantly drive PWM output and simply adjust the duty cycle of the waves to stop, start, speed up, slow down, and turn the car.

In an overview, it’s helpful to lay out the registers and terms involved in setting up PWM because it can get somewhat confusing when you get deeper into it. A summary follows, but these will be explained farther into the article.

  • ICR1 - input capture - the register that holds the TOP target counter value - essentially governs how long the PWM wave period is
  • OCR1A, OCR1B, OCR1C - 3 registers which can be used with 3 different output pins to support 3 different PWM duty cycles using the same timer, TIMER1 (hence the name, OCR1, a register). The A, B and C, correspond to ATMega128 output pins that will carry the PWM signal.
  • OCR1A, OCR1B, OCR1C - output pins on the micro connected to the internal PWM logic - these are the spigots for PWM where the servo signal wires will be connected. On an ATMega128, these are PORT B, Pins 5, 6, and 7.
  • TCNT1 - the counter register that holds the up-down count value of TIMER1

Calculating PWM Timer and Register Values



One of the main formulas for computing PWM register setup is given in the Atmel datasheet on page 130. It is:

OCnxPFCPWM = clk_IO / ( 2 x N x TOP )

Looks nasty, but it’s very easy.

N” is a timer prescale factor of 1, 8, 32, 64, 128, 256, or 1024. You can think of the timer prescale like gears in a car. A prescale of 1 causes the timer to run at the maximum possible clock speed. Each of the other prescalers is like gearing down the clock from the fastest possible speed to one that fits the conditions you need to match. First gear would be a prescale of 1024, second gear, 256 and so on until you get to a prescale of 1 which is the highest gear for the timer.

TOP is the ICR1 register value that the timer will count up to and then back down to 0 for each period. It’s the target count. The larger it is, the longer it takes the timer to count up and back down.

OCnxPFCPWM is the ATMega datasheet way of saying “frequency in hertz.”

Computing TOP



The larger the TOP value is, the longer it takes to count up and count down which has the effect of making a longer PWM wave period. So, we use TOP to help control the servo signal period. Keep in mind this only controls the full period of the wave and does not control the duty cycle. More on that later.

As a reminder, our objective is a 20ms PWM period (as measured in Part 1 of this series), and the steering and motor control duty cycles were in the range of 1ms to 2 ms of 20ms (5% to 10%.) The frequency, in Hz, of a 20ms period is:

1 cycle / 20ms == ? Hz

You can figure that out by converting to cycles per second (Hz) :

(1 cycle * 1000ms) / ( 20ms * 1sec ) == 1000 cycles / 20sec = 50 cycles / sec = 50Hz

We need this number to plug in to the Atmel PWM formula, the OCnxPFCPWM parameter, and figure out the other parameters.

The ETT AVR Stamp has a 16MHz system clock, so this will become the clk_IO parameter in the formula, and the ATMega fuses need to be set to use the external oscillator as the system clock source.

Lets do some sample computations and see how close we can get to a 20ms period.

If the system clock is 16MHz, then the timer clock can be prescaled 1, 8, 64, 128, 256, or 1024 which means the timer can run at any of these frequencies:

Prescale of 1: 16MHz / 1 = 16MHz
Prescale of 8: 16MHz / 8 = 2 MHz
Prescale of 64: 16MHz / 64 = 250 KHz
Prescale of 128: 16 MHz / 128 = 125 KHz
Prescale of 256: 16 MHz / 256 = 62.5 KHz
Prescale of 1024: 16 MHz / 1024 = 15.625 KHz

We’re trying to arrive at an appropriate prescale value and a TOP value that will generate a 50Hz signal. Using the Atmel formula, if we do a little algebra, solve for TOP, and make the formulate slightly more readable, we get:

TOP = clk_IO / (2 x N x Desired-Frequency )

Plugging in a few prescale values, we can see what values of TOP might be reasonable:

Prescale of 1: TOP = 16,000,000 / ( 2 X 1 x 50Hz) = 160,000
Prescale of 8: TOP = 16,000,000 / ( 2 X 8 X 50Hz) = 20,000
Prescale of 64: TOP = 16,000,000 / (2 X 64 X 50Hz ) = 2,500

Since TOP value needs to fit into ICR1, which is a 16 bit register, we can see that a top value of 160,000 will not fit, but 20,000 will fit in ICR1 and so we can use a prescaler of 8. A prescale of 64 would probably work for this application, but we can get better timer resolution using a prescale of 8 which will result in a more accurate clock period. That makes 20,000 for ICR1 (TOP) the better choice.

So, the critical values we need to set up to get a 50hz PWM signal are ICR1(TOP) == 20,000 and Timer1 prescale of 8. With a Timer1 prescale of 8, using a 16MHz system clock, the timer is cut to a 2MHz signal. We’re using the CodeVision compiler and wizard, so to set up the clock frequency for Timer 1, we choose what CodeVision calls the 2,000 KHz clock. 2,000 KHz == 2MHz.

ICR1, while it’s a 16-bit register can be addressed in bytes, so 20,000 is 0x4E20 and ICR can be initialized as ICR1H = 0x4e and ICR1L = 0x20.

The Forest from the Trees



We need to pull back a second because we’re really only half way to creating a PWM wave to control a servo. The only thing we have managed to do so far is derive the values needed to tell the micro how long the wave is. The period, 20 ms, is a 50Hz wave. We know from reverse engineering the signals in Part 1 of this series, that this wave needs to have a duty cycle (one part on, one part off) that varies. The varying duty cycle is the key to controlling the speed and direction via a servo or motor controller.

There’s another ATMega128 register that controls the duty cycle of a PWM wave and that is the OCR1 A, B, or C (for timer 1). As I mentioned earlier, one timer can control 3 servos and the way it does it is through these 3 registers, one for each servo / output pin. OCR1A is for the output pin OC1A, servo 1. OCR1B is for the output pin OC1B, servo 2. OCR1C is for OC1C, servo 3. Since all servos work on the same 20ms period, one timer, with the help of 3 registers, can generate independent control signals for 3 servos. Once I saw how this worked, I think it’s an ingenious design feature of the AVR (perhaps other micros use the same concept as well.)

Changing the PWM Duty Cycle - the Key to Controlling a Servo



The larger OCR1(abc) value is, the longer the PWM wave will be held high. For servo control, the two extreme ends of travel we found were 1 to 2ms with a neutral position being about 1.5ms. For the throttle, it was even slightly less outer range - 1.2ms to 1.8ms. Out of a 20ms wave, we need to make 1 to 2ms of it high in order to control the servos.

To understand why changing the OCR(abc) register changes the duty cycle, it’s helpful to draw what’s going on and visualize it (see the “pencast” below). OCR(abc) is a threshold value. The timer is a counter and we configured it as an up-down counter - the up-down counter is part of what PWM with phase and frequency correct mode does. So, the timer counter, TCNT1, will cross the OCR threshold twice. It crosses once as it’s going up and once as it’s coming down. When it gets back to 0, the timer period has ended, though that doesn’t mean the PWM edges start or finish there. They start or finish on the threshold cross-over.

The key to understanding the OCR threshold is knowing that the OC1 output pins will change state each time an OCR threshold value is passed by the TIMER1 counter, TCNT1 - passed either going up or coming down.

You can visualize the TCNT1 as a saw-tooth wave where the two cross over points where the timer counter is equal to the OCR threshold will define a time-span when the pulse is either high or low. The time span is the distance between two cross-over points on the saw-tooth.

Here’s a simulated hand-sketch of what’s going on - if you play this sketch, you’ll get a “chalk-talk” on the relationships between the timer counter and OCR threshold value. This basic diagram is available in the Atmel datasheet, but this treatment gives a slightly more dynamic view of what’s happening:



The final detail in setting up PWM on the ATMega128 is to enable PWM output pins. This is simple. There are 3 multi function pins on PORT B that are for PWM output of Timer 1. We’ll use two of them, Port B, Pin 5 (OC1A) and Port B, Pin 6 (OC1B). These correspond to the Timer1, OCR1A and Timer1, OCR1B registers. To enable these pins for PWM output, we simply set up the data direction registers for output on those pins. Internally, the ATMega makes the PWM logic connection with the output pins and you’re good to go.

Summary for PWM Servo Control



OCR1A is the register we’ll set to steer the car and we’ll use OCR1B to adjust the speed forward or backwards. The ICR1 register (TOP) is the way we adjust the period of the wave and it will never change after it’s set (it can change to make varying periods, but we don’t want it to change because the period is set at 20ms for servo control.) The other setup registers just tell the timer what mode to be in (Pulse Width Phase and Frequency Corrected) and what wave form to output (inverted or non-inverted.)

The image below shows a snippet of code in the test program that exercises the steering servo as seen in the video:

SampleSteeringTestCode

The full test code CodeVision AVR project can be downloaded if you’d like to look at the whole thing. The main file to study is autoveh.c. This is the exact code/project used to exercise the vehicle in the video at the start of the article.

Involving the Boy



I’m always looking for opportunities to involve my son in this project since I want to make this autonomous R/C vehicle a major learning opportunity for him. Obviously, this article shows that an easy concept such as PWM has more than a few considerations and a pretty deep section of a data sheet to wade through. I don’t expect my 11 year old to be able to derive all this so this is an area I got running first and then went over the explanations with him. Ultimately, this code will be encapsulated in methods like “turn_right( how_much )” and “throttle_forward( how_fast )” that will make more sense to a junior coder.

I really expect to have Nakoa much more involved in the next phase (roadmap outlined toward the end of this article.)

Even so, I found some tasks for him to do in this phase. For this article, his part was to solder the jumper board for the servo connections to the micro and also to solder a 25 pin header to the left of the ATMega128 socket so we could tap the PWM pins on the micro. Here’s the start of the servo jumper board - signal and power will come into these from the RAD-GPS controller board:

Servo jumper board

Nakoa soldering the 25 pin header to the side of the AVR:

DSCF4833

Testing



So, that’s all a lot of interesting PWM theory, but here’s how it looks in the real world, on the bench for testing:

DSCF4839

The two wires, Green and Yellow, coming out of the AVR micro are from Port B pins 5 and 6 which are the two PWM pins we discussed above.
AVR PWM pins
They connect to the servo jumper board we made along with power and ground. The two signal wires from the micro connect with the signal wires of the servo lines coming from the car - one for throttle and one for steering. Two 3-wire servo cables go from the jumper board to the car. There’s a common ground between the RAD-GPS dev board and the vehicle’s power supply which is created by connecting the RAD-GPS dev board ground to the ground wire coming from the servo on the car.

The movie at the beginning of the article shows it all together and working and shows in real-time the relationship between the length of duty cycle of the PWM wave and how the car will steer or move.

You can download the test code, written for the CodeVision AVR compiler, used to run the car through its paces and the test code that was running when the video above was shot.

Roadmap



We’re finished with Phase 1 and successfully completed our objective: gaining control of the vehicle with our microcontroller and bypassing the standard radio. We’re ready to move into Phase 2 with our autonomous R/C car: learning how to navigate and experiment with various algorithms to steer and move in real space.

The Phase 2 objective is simple to state: We want to create a waypoint, send it to the vehicle, have the vehicle drive straight to the waypoint. Doesn’t matter how fast, slow, ziggy, zaggy it is, the objective will be to just get it to drive autonomously to a single point and recognize when it gets there. I suspect we’ll need to implement a pickle switch in Phase 2.

Phase 3 is going to address obstacle detection and avoidance. I suspect this will be the most difficult phase and one that will never be complete, so the trick with this phase is to define what is “good enough.” Part of this objective will be to figure out the appropriate sensors as well as defining the test cases the vehicle will need to deal with and hope those cases will be sufficient for the live course.

Phase 4 objective will be to receive a list of waypoints that defines a course, optimizing speed around a course, and recognizing when it’s finished. I suspect this phase will stress our obstacle avoidance algorithms so we don’t outrun our sensors and end up with a spectacular crash.

Landon Cox
www.ESawdust.com

Other articles in this series:
Building Bots with Kids
Autonomous R/C Car - Part 1 - Reverse Engineering Signals
Autonomous R/C Car - Part 3 - GPS
Autonomous Vehicle - Part 4 - Mechanical, Firmware
Autonomous Vehicle - Part 5 - Race Day


Autonomous R/C Car testing

Autonomous R/C Car - Part 1 - Reverse Engineering Signals

Synopsis: This is the first part of a series of articles written to share the experience of my son and me hacking an R/C car into an autonomous vehicle. This article will focus general observations around picking an appropriate R/C vehicle and identifying the signals and characteristics of those signals needed to control the car.

Picking a Vehicle


The original impetus for this was the Sparkfun Autonomous Vehicle competition whose course is a parking lot loop around the Sparkfun building in Boulder. So, the vehicle didn’t need to be off-road or aqueous unless it really went off track like some did last year.

What Not to Use


When we first started thinking about an autonomous R/C vehicle, we thought we’d hack one of the 4x4 R/C trucks that we had sitting in the garage which we bought from RadioShack 10 years ago. What the heck? We haven’t run it for a long time and it was pretty beefy - if it got hacked beyond recognition, who cares?

One of our first observations after tearing it down is that RadioShack R/C vehicles are not good candidates for an autonomous vehicle. A couple reasons stood out:

  • They’re built too safe: RadioShack is bound and determined to be safe and therefore anything that could shock or burn is well protected. They’re so well protected, components like the motor and controller are effectively inaccessible without major disassembly. We would have had to remove the end and complete gearbox to get to the motor. That’s silly - not conducive to hacking.
  • After “liberating” the electronics, our R/C truck had a relay instead of an electronic speed controller. This makes the speed control finicky and jerky - and electrically noisy. It was also all on the same PCB as the radio, so we would have had to hack the board or substitute our own speed controller. Either way, it wasn’t the best choice and we had others.

What We’ll Use for an R/C Platform


Our second choice turned out to be much better. We own two, RC18R, 1/18th scale 4WD rally cars from Team Associated which look like this:
base_media5zne5h4

These little buggers are screamingly fast. They are so fast they could not be run top-speed at a competition without some serious unintended carnage. Nice features of these vehicles are:

  • Relatively inexpensive, though still a lot more money than a RadioShack toy - they’re “serious” R/C vehicles (as much as “serious” and “R/C” can be used in the same sentence.)
  • Electronic speed control
  • All the components are easily accessible and parts readily available via Team Associated (not that we would ever crash one, no.) There is an active aftermarket for components which was definitely not the case with RadioShack toys.
  • Very responsive and super maneuverable all wheel drive drivetrains
  • They can be hacked without ruining the vehicle for its designed purpose as everything is modular and pluggable.
  • The vehicle has both forward and reverse which would be required to potentially get out of a pickle

The final thing about this product is there are off-road versions of it as well, the RC18T series, so the same basic control and electronics we come up for the autonomous component could easily fit onto other types of vehicles if we wanted an offroad autonomous Grand Challenge.

base_media

While 1/18th scale vehicles are very small, they’re still large enough to fit microcontrollers, GPS, and sensors without overloading the platform and making them too top-heavy.

General Electronics of the RC18R


Our basic approach to taking control of the vehicle will be to bypass the stock radio control which is a 27MHz typical R/C transceiver system. Yet, we wanted to use as much of the existing car and electronics as possible to keep costs low.

That immediately implies that the signals which are sent to the motor controller and steering servo by the existing radio receiver are the signals our autonomous controller needs to emulate in order to make the car work under autonomous control.

So the first order of business is to figure out how to make the car move and how to control its steering by reverse engineering how it works as designed.

The receiver in the RC18R has two 3-wire plugs coming into it. One is connected to the motor controller which is, in turn, connected to the NiMH battery pack. The second is connected to the steering servo. There is no separate power to the receiver like some R/C cars which use a 9V battery to power the receiver and another large battery to power the motor.

DSCF4823

In the photo above, the receiver is the blue and silver component on the spine of the chassis. The motor controller is just above the receiver and has the toggle switch for powering on the vehicle. The motor is above and to the right. The battery pack is the blue and yellow rectangle running the length of the chassis. The main pinion gear of the motor is on the right side gear box and there’s a central drive shaft that runs down the middle of the chassis to drive the front gear box making it AWD.

The 3-wire plug going from the motor controller to the receiver carries 5V (red), GND (black), and signal (white) where the signal is one-way from the receiver to the motor controller. The other 3-wire plug is a standard 3-wire servo connection.

I knew that servos were controlled using pulse width modulation (PWM), but I wasn’t sure how the speed control worked. In either case, we wanted to look at the signals for steering and speed control even though the servo was likely standard.

Steering Servo Signal


We started with the servo signal because I knew to expect a PWM type signal. I made a 3-pin servo connector with a 3-wire pigtail that had bare ends. Unplugging the steering servo and plugging in the 3-wire pigtail, we had a simple “tap” we could use to put a scope on and view the signals.
DSCF4812

DSCF4808

The first thing was to bracket the servo signal and figure out its basic period and duty cycle (the % on vs % off time in one period.) You could look this up and be pretty sure this vehicle was identical, but part of this exercise is to go through the process of actually doing the work and seeing how it works. Here’s a o-scope waveform of the steering servo signal:

steering

A couple things to note. 1) I was using a nearly depleted battery in the car when I took the image above, so the signal amplitude is not full - it’s about 3V to 3.3V typically as you’ll see below. 2) The full period of the wave is slightly less than 20ms...something about 18ms. If you google PWM and servos you’ll quickly learn that most run at 20ms periods.

Next we needed to figure out the duty cycle of the wave so we zoomed in on one cycle above and then manipulated the steering control on the transmitter to see what neutral and full right and full left looked like.

With the transmitter wheel in a neutral position, hands-off, this is the signal we saw:

str0

Not quite 1600 microseconds (1.6ms) of the 20ms wave asserted high.

When the wheel was full left we saw:

strleft

A little over 1ms on full left.

and when the wheel was full right we saw:

strright

A little over 2ms when full right.

So, we measured and verified what is common knowledge amongst anyone who’s worked with servos before: the typical period is about 20ms and the neutral position is half way between 1 and 2 ms (1/20th and 1/10th duty cycles) or about 1.5ms for straight ahead steering. Finally, the servo signal level is just over 3V...call it 3.3V.

Speed Control Signal


The next order of business was to examine the speed control signal. We could not use the simple 3-wire pigtail for this signal because the power for the receiver and servo came in via the 3-wire strand with the signal I needed to measure. There was no choice but to cut the signal wire to tap it, leave the plug in place and then splice it back together later to keep the car intact so it could be used as a normal R/C car, too.

DSCF4810

After stripping the end coming from the receiver, we fired up the vehicle and measured the motor control signal. I don’t know why I was surprised by this, but the motor control signal had exactly the same characteristics as the steering servo just applied to speed. Instead of left, right and straight, it was forward, reverse and neutral.

Here’s neutral speed control wave form:

throttle

Here’s neutral, 0 speed from a duty cycle perspective:

spd0

Approximately 1500us asserted high.

Here’s full throttle forward:

spd9

A little over 1800us asserted high.

Here’s full throttle reverse:

spd_9

A little over 1200us asserted high.

So, the summary of the throttle signal is this: a period of about 18ms similar to the steering servo, a neutral duty cycle at around 1.5ms, full throttle about 1.8ms and full reverse 1.2ms. So, the band on either side of neutral is about 300us.

The throttle signal was just slightly different from steering in terms of duty cycle - it didn’t go through the 1 to 2ms range of steering, but it followed a similar pattern.

In the case of both the steering servo signal and throttle signal, as we turned the wheel or squeezed the throttle trigger on the transmitter we could see the wave form smoothly transition from longer or shorter duty cycles. That’s what we’ll need to emulate to make slight steering or throttle adjustments with our autonomous controller...it’s not all or nothing as these waves seem to imply - it’s a graduated duty cycle from end to end.

Our test setup was our kitchen table and it looked like this:

DSCF4807DSCF4809

Since I wanted Nakoa to be able to repair our intentional damage to the wiring for testing purposes, he needed to practice some soldering. He’d done some in prior years, but hadn’t done any for a time, so I gave him a perf board, a bunch of wire, some wire strippers, my good soldering iron and solder and he went to town on solder practice. It almost looked like a work of art when he got done:

DSCF4815
DSCF4814

DSCF4816

We call him “Harry”. I’m not sure why people buy soldering practice kits - this is a lot cheaper and just as fun for the kid.

So, he’s all tuned up to do the splice to put the single wire back together from the motor controller.

I think if Nakoa had his pick of autonomous vehicles, it would be this nitro buggy we saw at an R/C Hobbies store in Boulder. Maybe when he gets older...and a good job.

IMG_0081

Summary



This article has shown how to reverse engineer the internal motor control and steering signals needed to control an R/C car. While a specific R/C car was shown in the example, nearly any modern R/C car will work in a similar way. The next installment in this series will demonstrate how to emulate these signal wave forms using Pulse Width Modulation (PWM) features available on an ATMega AVR microcontroller.

Landon Cox
www.ESawdust.com

Other articles in this series:
Building Bots with Kids
Autonomous R/C Car - Part 1 - Reverse Engineering Signals
Autonomous R/C Car - Part 2 - Taking Control
Autonomous R/C Car - Part 3 - GPS
Autonomous Vehicle - Part 4 - Mechanical, Firmware
Autonomous Vehicle - Part 5 - Race Day
asdfasdf