This is an example program that actually allows the car to race using the FRDM-TFC library!

Dependencies:   FRDM-TFC

Fork of TFC-RACING-DEMO by Daniel Hadad

Overview

This is an example program that uses the FRDM-TFC library to actually permit a car using the FDRM-TFC shield + FRDM-KL25Z to race around a center line track.

Exercises designed for Mentoring Matters Car Summer Camp for Summer 2014 at Freescale, Inc. in Austin, Texas

Car MODES

5 MODES OR EXERCISES THAT WILL ALIGN WITH DIP SWITCH SETTINGS IN BINARY FASHION e.g. Mode 1 = 001 = switch 1 is on, switch 2 is off, switch 3 is off

0 = 000 = Garage Mode, button light test to see if car alive!!

  • PUSHBUTTON A - Light LEDs 0 and 1
  • PUSHBUTTON B - Light LEDs 2 and 3
  • (switch 4 does nothing)

1 = 001 = Garage Mode, forward/reverse adjust, no auto steer, terminal output

  • POT 1 - Controls speed of right wheel: CCW = reverse; CW = forward
  • POT 2 - Controls speed of left wheel: CCW = reverse; CW = forward
  • NOTE In this mode the high pitched whine heard is of the H-bridge being active. To disable whine, briefly put into demo mode 1 above.
  • (switch 4 does nothing)

2 = 010 = Garage Mode, steering adjust, no auto steer, terminal output

  • POT 1 - Controls Servo: CCW = left; CW = right
  • (switch 4 does nothing)

3 = 011 = Garage Mode, Camera test, some auto steer, terminal output

  • switch 4 : OFF = normal dec data, ON = o-scope mode

4 = 100 = Track Mode, Auto Steer, safe settings

  • LIGHT SPEED = 0.4 default
  • switch 4 = terminal output on/off
  • Pot0 = controls motor speed
  • Pot1 = controls value to multiply with Kp for proportional control

5 = 101 = Track Mode, Auto Steer, fast settings

  • LUDICROUS SPEED = 0.6 default
  • switch 4 = terminal output on/off
  • Pot0 = controls motor speed
  • Pot1 = controls value to multiply with Kp for proportional control

6 = 110 = future upgrades

7 = 111 = future upgrades

Car Hookup

Motors

  • Code written assuming left motor hooked to B1(red)/B2(black) and right motor hooked to A1(red)/A2(black).

Battery

  • Be sure to hook positive (red) to 'Vbat' and negative (black) to 'Gnd'

Steering Servo

  • Servo must be hooked up with black wire innermost (away from LEDs).
  • Also be sure to mount servo on chassis with wire coming out the right side of the car.

Camera

  • Camera must be hooked up with black wire towards LEDs on the shield board.
  • Be sure to mount camera on tower with connector down towards the bottom.

Potentiometers (Pots)

  • Pots by default should have arrows pointing toward battery/motor hookup (for demo mods default).

Car Calibration

Serial Terminal

  • Download your favorite Terminal application (I use TeraTerm. Set it for 115200 baud, 8bit, none, 1bit.
  • But first you have to be sure that Windows mbed serial driver has been installed: Windows serial config.

Camera

Servo/Steering

  • You will need to put the car into demo mode 1 and connect up a terminal to the serial port in order to get feedback on the values for your particular servo as hooked up. Then change MAX_STEER_LEFT and MAX_STEER_RIGHT in Spices.cpp with these values to tell the program how your servo is hooked up.

Speed Control

  • This program does not have proper speed control but does modify the speed slightly based on recent error results from the camera. It also modifies the differential speed to each wheel to have better control around curves.
  • While debugging your car you may want to lower the speed. See the constants LIGHT_SPEED and LUDICROUS_SPEED in Spices.cpp. There you can change the speeds used for Modes 4 and 5 above. Range of valid values are 0.4-0.7. Lower is better when debugging the car around the track (mainly to minimize crash forces!).

Strange Gotchas

Glitchy Motors

  • Apparently there is contention between TPM0_CH0 and OpenSDA micro that causes strange issues with Motors (PWM interference). This will cause glitches in motor activty when hooked up to USB only: Found contention

More Info

Spices/Spices.h

Committer:
simonchow
Date:
2014-06-25
Revision:
2:999ca57934bf
Parent:
1:87b28e8b9941

File content as of revision 2:999ca57934bf:

#include "mbed.h"

#ifndef _SPICES_H
#define _SPICES_H

// *******************************************
// MASTER CONTROL PROGRAM

// Loop at Servo cycle (currently 50Hz / 20mS)
// Camera gets updated at its own period
//   (currently 50Hz / 20mS)
// 
//   REQUIREMENTS:
//   - Control servos in response to track line position
//   - Gather as much camera data as possible between
//     servo update cycles to get best read on the line
//     (currently 1:1 though @ 50Hz)
//   - Ignore erronous signals:
//       - "mud" on track
//       - low contrast light situations
//       - track crossing itself (all black situation)
//   - Detects 'starting line' -- ignores first detect (START)
//     and stops after second detect (FINISH)
//
//   INPUTS:
//   - linescancamera data (0-127)
//   - maximum speed
//   - filter settings:
//       A = 15 (number of pixels at each end to ignore)
//       B = 20 (estimated width of line)(possible issue if line far away)
//       C = 2^12 (max value based on ADC sample rate of 12 bits)
//       D = Edge threshold of Derivative (max / 4 = 2^10)
//   - control parameters, KP and KD
//
//   CONTROL ALGORITHM:
//   1 - Get Line Position
//   2 - Compute Error from Line Position
//   3 - Set Servo position based on Error and Derivative of Error
//   4 - Store error for next cycle to perform derivative
//   
//
//   GET LINE POSITION
//     INPUTS: linescan data
//     RETURNS: either position or starting gate flag
//   ALGO:
//   - Find line edges:
//      - filter out first and last A number of pixels from left and right
//      - calculate derivative of data
//      - search for line edges in derivative data (search for either track line or starting gate)
//        - Search for all pixels with Value < -D, indicating negative edge (large negative means going from white to black)
//        - Search for all pixels with Value > D, indicating positive edge (large positive means going from black to white)
//        - Clean up adjacent line edges-- edges 1 pixel away from each other combined to be considered a single edge, average pixel value
//   - if starting gate then send up flag
//   - if track, calculate position
//
//
//   COMPUTE LINE ERROR
//   - take line position and target-- calculate error (negative or positive)
//
//   SET SERVO POSITION 
//      -  int servoPosition = KP * Error + KD * (Error - lastError);
//      -  lastError = Error;
//
//
//   TBD:
//   - store multiple edge positions in order to average prior to next servo update
//
// *******************************************
//
void TrackMode();

uint16_t getMode();
bool terminalMode();

// prints out line scan data for you
void printLineScanData(uint16_t *LineScanData);

// calculates derivative of line scan data
void derivativeLineScan(uint16_t* LineScanDataIn, float* DerivLineScanDataOut);

// prints out derivative of line scan data -- assumes deriv already calculated
void printDerivLineScanData(float* derivLineScanData);

// serves to grab a frame of camera data
void grabCameraFrame();

// find negative and positive edges in image data, store in array, combines edges found in adjacent pixels
void findEdges(float* derivLineScanData);

// improved algo to find negative and positive edges in image data, store in array, combines edges found in adjacent pixels
void findEdges_v2(float* derivLineScanData);

// prints out edge data found
void printEdgesFound();

// review edge data
//   - report line position if there
//   - set starting gate flag if there
//   - do nothing with position value otherwise
void reviewEdges();

// Decide new actions based on track status
void ActOnTrackStatus();

// Update Steering settings
void SteeringControl();

// Apply steering setting to servo!
void Steer();

// Update speed settings
void SpeedControl();

// Apply speed settings to motors!
void Drive();

// Adjust parameters based on max light measured value
void adjustLights();

// print out light adjust data
void printAdjustLightsData();

// Give user feedback as to detection state via LEDs
void feedbackLights();

void useMode();
     
// capture log data
void captureData();

// dump log data to terminal
void dumpData();
           
#endif