Autonomous Power Wheel

Problem

edit

Motor vehicle accidents are the leading cause of death for young adults in the United States. Google has developed full-sized self-driving vehicles that are street-legal in Nevada. Stanford's autonomous vehicle won the DARPA Grand Challenge in 2005.
Project Goal: Design and implement the electro-mechanical systems and software required to control a Power Wheel. The autonomous vehicle should be able to travel outdoor on specified paths while avoiding obstacles.

Conceive

edit

The Power Wheel (electric ride-on toy) must be able to autonomously drive around the campus of Howard Community College in Columbia, MD. Initially, the car will be confined to a flat open space (e.g. parking lot). The final design should be able to navigate to specified waypoints while avoiding obstacles.

 
Design Requirements for each Component or Subsystem

The goal of the project is to materials, designs, and data gathered by past groups to create a design for steering controls, pedal controls, and to have them controlled and powered by an Arduino and a Monster Motor Sheild.

Steering:
• needs to use a Firgelli Miniture Linear Actuator L16 Series with 140mm stroke and 150:1 gear ratio
• steering controls cannot modify the Power Wheel structurally
• must be controled by an Arduino and a Monster Motor Sheild
• capable of turning the steering wheel 40° in either direction
• must be removable

Pedal:
• must use 12VDC, 78RPM Motor with Right Angle Leadscrew
• must be able to depress the pedal with 3 N of force
• be able to mount to the power wheel with only the use of the 4 wing nuts on mounting platform
• must be removable


Design

edit

The design phase involves designing subsystems in order to make the power wheel autonomous. It is obvious that these subsystems have to be able to work together with ease. In doing so, we anticipate that at some stage, the vehicle will be able to drive autonomously without any operator instructions. However, as it stands now, several subsystems must first be designed in order to replace the interactions a human driver would have. These subsystems must be both simple to build, simple to repair and improve upon.

Design Concepts for Subsystems

edit
Steering actuation concepts

There were four initial designs for the steering mechanism: linear actuator pulling and pushing a chain, linear actuator attached to steering wheel, lever with the linear actuator, and direct rotary actuation from a high-torque motor.

Steering Concept #1 This concept would use a track built around the perimeter of the Power Wheel's steering wheel. Inside the track will be a bicycle chain that was attached at one end to the steering wheel and to the other end the linear actuator. As the linear actuator would extend the chain would move forward in the track and push on the steering wheel and cause the steering wheel to turn. As the actuator retracts it would pull on the chain and that would turn the steering wheel in the opposite direction. This concept would provide the greatest movement of the steering wheel and have the tightest turning radius. The design would also be compact and not add much bulk to the overall design. The fault with the design was the complexity of the construction, the complexity of installation and removal, and overall cost. To make a track and use the chain, there needs to be metal work done, which the engineering workshop is not equipped. The design would be hard to install and remove, and one of the criteria be it could easily be removed from the Power Wheel. Since the workshop is not equipped with the equipment or materials for a prototype to be built, the cost was more than what our budget allowed.


Steering Concept #2 This concept was to have the linear actuator attached directly to the steering wheel. It would attach with the use of a metal pipe bracket, on the right side of the steering wheel, going around the steering and connect to the linear actuator. As the actuator extends it would cause the steering wheel to turn counter-clockwise and steer the Power Wheel to the left. As the linear actuator retracts it will turn the steering wheel clockwise and steer the Power Wheel to the right. The construction of the design will also be easy and not complex with only the use of one bracket and one screw. The design would be easily installed and removed, and will not alter the structure of the Power Wheel. The faults of the design are the weak connection points and the lack of power from the linear actuator as the steering wheel turns. Using only one connection point and being unable to alter the structure of the Power Wheel will impede on the strength of the connection. Also as the steering wheel turns the angle changes in which the force is being applied to the steering wheel, when the angle reaches a certain point, the linear actuator will not have enough force to provide enough torque to turn the steering wheel.


Steering Concept #3 The third design will use a lever arm attached to the steering wheel, from which the linear actuator is attached. The lever will be attached at two points along the steering wheel using U brackets with screws. The lever will extend to the right of the steering wheel and at the end of lever the linear actuator will be attached. As the actuator extends it would cause the steering wheel to turn counter-clockwise and steer the Power Wheel to the left. As the linear actuator retracts it will turn the steering wheel clockwise and steer the Power Wheel to the right. The lever arm needs to be at an adequate length to allow for enough torque to turn the steering wheel, but not long enough to impede on the movements and function of linear actuator.

Steering Concept #4 The fourth design turns the steering wheel using a direct attachment to a high-torque. The power window motor from a standard automobile is one option for the actuating motor.

 
Power Steering Motor

Gas Pedal actuation concepts

There was the original design of the pedal pusher, form past groups, utilizing a pedal pusher with side brackets attached. An alternative design was made using a rectangular pedal piston and a square bracket.

Pedal Concept #1 The original design was a pedal pusher with side brackets built on to the pusher. The brackets were on either side of the pedal pusher and was made to go on each side of the pedal. The pedal pusher will have hollow center to allow the screw from the motor to fit inside the pusher. There will also be a cut out on the side to allow access for a nut that will attach to the screw mechanism of the motor. As the motor turns the screw, the nut will extend and move the pedal pusher. The brackets were used as a way to stop the pedal pusher from spinning. The Concept with the use of a pusher and the screw motor worked properly, but the brackets caused the design to fail. Parts of the concept was used to build the second design, the pedal piston and bracket.

Pedal Concept #2 The new design was a pedal piston. It was shaped as a rectangular cube and was hollow to allow the screw mechanism form the motor to be inserted into the piston. There was also a cut out on the side, similar to the cutout from the original design, that allowed access for the nut to be attached to the screw mechanism. To resolve the issues the last design had with the built on brackets, the new design uses a separate square mounting bracket. The bracket will have the piston inserted and will prevent the piston from spinning and not extending, secure the bracket to the mounting platform, and guide the piston to the pedal.

Ultrasonic Sensor Mounting

There were three choices for the mounting platform: 1) wooden mount, 2) rotating mounting bracket, and 3) the mounting plate.

  • Wooden Mount:

The wooden mount design will be a wooden stand that would attach to the floor of the lower platform in the Power Wheel. It will extend over the front of the Power Wheel to allow the Ultrasonic Sensor HC-SR04 Distance Measuring Module to have an unobstructed view of what is in front of the Power Wheel. At the top of the wooden mount the Ultrasonic Sensor HC-SR04 Distance Measuring Module will be attached with small wood screws to secure it and prevent it from moving while the Power Wheel is driving.

  • Rotating Mounting Bracket:

This concept uses a rotating mounting bracket for the Ultrasonic Sensor HC-SR04 Distance Measuring Module. The sensor will be forward facing while the Power Wheel is driving. When the sensor encounters an obstacle it will stop the Power Wheel and put it in reverse, as the Power Wheel reverses the sensor will sweep back and forth 180° and determine which direction the Power Wheel will need to go to navigate around the obstacle. The whole setup, with the rotating mounting bracket and the Ultrasonic Sensor HC-SR04 Distance Measuring Module, will be mounted on a wooden stand on the lower platform of the Power Wheel.

  • Wooden Plate:

The mounting plate will extend down under the Power Wheel and allow room to attach the ultrasonic sensor. The mounting plate will be mounted using the bolt pattern of front bumper on the Power Wheel. The front bumper will be removed and a piece of plywood will be attached, as a mounting plate, using the same bolt pattern as the bumper. The bumper will be reattached on top of the mounting plate with the longer bolts.At this mounting position it will be able to sense curbs and other low lying obstacles. The mounting plate will also need to protect the ultrasonic sensor from collisions. The mounting plate will have brackets on either side of the ultrasonic sensor, that will extend further than the sensor. Decision Matrix

Design Concept
a Wooden Mount
b Rotating Mounting Bracket
c Wooden Plate
Ease of Construction Cost Range of Sensor Durability Ease of Use Overall Capabilities Total Score
a 4 4 2 3 4 2 19
b 2 2 5 3 3 5 20
c 4 4 4 4 4 3 23

For the final choice for the design concept was the Wooden Plate, it had the best range of sensor and function and be able to have future groups to add more capabilities of the rotating mounting bracket to platform.

Experimental prototypes and testing

edit
  • Video of power window motor turning steering wheel. Testing was successful, but the power window motor was inadvertently damaged and this concept was abandoned.
  • Steering Wheel Mock-up for Testing
  • Gas Pedal Prototype

Gas Pedal Presser Test Video http://youtu.be/gIV6zhy3gRI

  • Base Prototype

The final design

edit
Steering actuation

The finalized design will be used for the steering will be Steering Concept #3. It will use only three parts: the lever, mounting brackets, and the linear actuator. The use of the lever will allow for adequate torque as the angle changes between the lever and the linear actuator.

Pedal actuation

The finalized design will be used for the project will be Pedal Concept #2. This will use the pedal piston and the square mounting bracket. This will allow for piston to move back and forth by the turning of the screw and nut, and with the use of the square bracket it will be secured, guided to the pedal, and prevented from spinning.

The initial design for the bracket was modified to include extensions of the bracket that will be drilled and screwed in. These extensions allow for the easy removal of the bracket on the platform.

Support structure

Utilization of Knowledge in Design

edit
Technical details and scientific principles
edit
Torque/Force Calculation for Steering Actuation

The steering controls will need to use the Firgelli Miniature Linear Actuator and must fall within the constraints of the linear actuator. The stroke length of the actuator is 140 mm and to steer in both directions with restricting the actuator to using half the stroke length in each direction, 70 mm. The steering wheel itself in the power wheel, measured by the past groups, is 86.6 N at 8.3 cm to turn the steering wheel. Using the equation
τ = F x r
Torque = Force x Length of Lever

 
Torque animation
 
Torque, position, and force

The amount of torque can be calculated to find the actuator was capable of pulling back the steering wheel at that length. But further research into the design and the options how to mount the actuator on the steering wheel we need to have two pivot points, one at the base of the actuator and one at the point where the actuator and the lever connect. With that, the actuator will not be always perpendicular with the lever to apply the force. We need to account for the loss of torque at different angles as the steering wheel is turned by the actuator. To find the correct length of the lever and the angles that the lever will be with the actuator I will use the equation:
τ = F x r x Sin θ
Torque = Force x Radius x Sin θ
θ will be the angle in which the force is being applied. Doing this we can see much force is lost in changing the angle in which the force is applied. When the force is applied at 90° the full amount of the force is applied to the lever, but when the force is being applied at an angle, the force that is applied in the direction in which you want the lever to go is a fraction of the overall force being applied. To find that new force we need to find the component vectors and to do that we need the force times Sin θ to get the amount of force being applied perpendicular to the lever.

Ultrasonic Distance Sensing

The Ultrasonic Sensor HC-SR04 Distance Measuring Module is an ultrasonic range sensor for an arduiono. It detects the distance of the closest object in front of the sensor, from 2 centimeters up to 3 meters. It works by sending out a burst of ultrasound, from one "ear", and listening for the echo when it bounces off of an object, with the other "ear". The Arduino board sends a short pulse to trigger the detection, then listens for a pulse on the same pin using the "pulseIn()" function. The duration of this second pulse is equal to the time taken by the ultrasound to travel to the object and back to the sensor. Using the speed of sound, this time can be converted to the distance that can be used to stop the Autonomous Power Wheel when approaching an obstacle.

Prior work in the field, reverse engineering and redesign
edit

Sparkfun Electronics provides an example Arduino code for controlling two motors simultaneously using the Monster Moto Shield. This sketch was the basis for the vehicle control code:

MonsterMoto Shield Example Arduino Sketch
/*  MonsterMoto Shield Example Sketch
  date: 5/24/11
  code by: Jim Lindblom
  hardware by: Nate Bernstein
  SparkFun Electronics
 
 License: CC-SA 3.0, feel free to use this code however you'd like.
 Please improve upon it! Let me know how you've made it better.
 
 This is really simple example code to get you some basic
 functionality with the MonsterMoto Shield. The MonsterMote uses
 two VNH2SP30 high-current full-bridge motor drivers.
 
 Use the motorGo(uint8_t motor, uint8_t direct, uint8_t pwm) 
 function to get motors going in either CW, CCW, BRAKEVCC, or 
 BRAKEGND. Use motorOff(int motor) to turn a specific motor off.
 
 The motor variable in each function should be either a 0 or a 1.
 pwm in the motorGo function should be a value between 0 and 255.
 */
#define BRAKEVCC 0
#define CW   1
#define CCW  2
#define BRAKEGND 3
#define CS_THRESHOLD 100

/*  VNH2SP30 pin definitions
 xxx[0] controls '1' outputs
 xxx[1] controls '2' outputs */
int inApin[2] = {7, 4};  // INA: Clockwise input
int inBpin[2] = {8, 9}; // INB: Counter-clockwise input
int pwmpin[2] = {5, 6}; // PWM input
int cspin[2] = {2, 3}; // CS: Current sense ANALOG input
int enpin[2] = {0, 1}; // EN: Status of switches output (Analog pin)

int statpin = 13;

void setup()
{
  Serial.begin(9600);
  
  pinMode(statpin, OUTPUT);

  // Initialize digital pins as outputs
  for (int i=0; i<2; i++)
  {
    pinMode(inApin[i], OUTPUT);
    pinMode(inBpin[i], OUTPUT);
    pinMode(pwmpin[i], OUTPUT);
  }
  // Initialize braked
  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
  // motorGo(0, CW, 1023);
  // motorGo(1, CCW, 1023);
}

void loop()
{

 // Push the gas pedal for 6 seconds
  motorGo(1, CW, 1023);
  delay(6000);//time required to push the pedal

// Stop motor to leave the pushed pedal 
  motorGo(1, CW, 0);
  delay(5000);//time required for the drive

////turn all the way left
//  motorGo(1, CW, 1023);
//  delay(500); //time required for half stroke length
//  
////keep turning for 20 seconds
//  motorGo(1, CW, 0);
//  delay(20000);//time required for the turn
//  
////turn all the way right
//  motorGo(1, CCW, 1023);
//  delay(500); //time required for half stroke length
// 
////keep turning for 20 seconds
//  motorGo(1, CCW, 0);
//  delay(20000);//time required for the turn
  
 // Receed from the gas pedal for 6 seconds
  motorGo(1, CCW, 1023);
  delay(5500);//time required to stop the actuator from pushing
  
  if ((analogRead(cspin[0]) < CS_THRESHOLD) && (analogRead(cspin[1]) < CS_THRESHOLD))
    digitalWrite(statpin, HIGH);
}

void motorOff(int motor)
{
  // Initialize braked
  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
  analogWrite(pwmpin[motor], 0);
}

/* motorGo() will set a motor going in a specific direction
 the motor will continue going in that direction, at that speed
 until told to do otherwise.
 
 motor: this should be either 0 or 1, will selet which of the two
 motors to be controlled
 
 direct: Should be between 0 and 3, with the following result
 0: Brake to VCC
 1: Clockwise
 2: CounterClockwise
 3: Brake to GND
 
 pwm: should be a value between ? and 1023, higher the number, the faster
 it'll go
 */
void motorGo(uint8_t motor, uint8_t direct, uint8_t pwm)
{
  if (motor <= 1)
  {
    if (direct <=4)
    {
      // Set inA[motor]
      if (direct <=1)
        digitalWrite(inApin[motor], HIGH);
      else
        digitalWrite(inApin[motor], LOW);

      // Set inB[motor]
      if ((direct==0)||(direct==2))
        digitalWrite(inBpin[motor], HIGH);
      else
        digitalWrite(inBpin[motor], LOW);

      analogWrite(pwmpin[motor], pwm);
    }
  }
}


Implement

edit
Implementation Goals

1. Finish design and building the table top platform.

  • Acquire new miniature linear actuator and calculate the angles of force to determine steering wheel lever length. Make the lever arm long enough to allow for adequate force to be applied to turn the steering wheel.
  • Determine the height for the wooden wedge to mount the miniature linear actuator to the table top platform.
  • Build the wooden wedge for the tabletop platform and install onto the Power Wheel.


2. Finalize the design features for Power Wheel Platform.

  • Measure the interior of the Power Wheel.
  • Design the platform for the Power Wheel.
  • Calculate the height of the wooden wedge for the Power Wheel Platform.
  • Design attachment points for the screw motor, steering components, Arduino, and the battery.


3. Finish and adjust the code for the Arduino to allow Power Wheel to drive in a pattern.

  • Calculate the time to extend the miniature linear actuator.
  • Measure time amount of time to make 360 degree turn in Power Wheel.
  • Calculate time for the Power Wheel to make a 90 degree turn.
  • Edit the Arduino code for the Power Wheel to follow predetermined path.


4. Improve drive capabilities of Power Wheel.

  • Do more measurements of time to make turns.
  • Determine the driving speed of the Power Wheel in high and low gear
  • Adjust code to allow for turning the steering wheel as the Power Wheel is in motion.
  • Adjust code to incorporate turns and driving straight to follow path.


5. Add sensor based obstacle avoidance system.

  • Research the Ultrasonic Sensor for Arduino. Understand the limitations and capabilities of the sensor.
  • Build mount for Ultrasonic Sensor on the Power Wheel. Mount must be able to protect the Ultrasonic Sensor from collisions with obstacles in cases of failure.
  • Create Arduino code to use with Ultrasonic sensor, stop the Power Wheel when faced with an obstacle and re-engage the code once the obstacle is removed.

Overview of Implementation Steps

edit
Acquire and test linear actuator for steering

The first task was to acquire a small linear actuator. The linear actuator needed to be strong enough so that it is capable of turning right and left when it retracts and extends, respectively. It takes 86.6 newtons at 8.3 centimeters, 721.27 newtons per centimeter, to turn the power wheel both ways, which means that we needed a linear actuator that can retract and extend with the same or more amount of force. As the steering wheel turns the amount of force that was applied by the miniature linear steering wheel would change, further away from 90°, the less force was being transferred to the steering lever. The linear actuator that was purchased for this project can hold up to 200 newtons, which completes the requirement for the linear actuator.
Using the length of the miniature linear actuator, the height of the wooden wedge could be calculated. With all the information gathered and a lever length selected, the steering components could be installed on the table top platform. Then using the table-top platform test bed, correct operation was confirmed.

Finalize platform design

The next step was to finish designing the platform in the Power Wheel. Measurements were taken from the Power Wheel and used to design the platform in the Power Wheel. When the design was finalized, the platform was constructed and installed on the Power Wheel.

Mechanical assembly of driving system

The next step was to install all the components on the Power Wheel. After the steering and the pedal components were installed on the Power Wheel platform, the battery and the Arduino were installed. The pedal pusher assembly need to be adjusted to accommodate the wooden block that attached the lower platform to the upper platform.

Programming for navigating predefined path

The Arduino code was adjusted to make the Power Wheel drive in a predetermined pattern. The Power Wheel was taken outside and timed on how long it took to make turns and the speed driving in a straight line. The code was changed to make the Power Wheel to drive straight, make a right turn, drive straight again, make another right turn, and finally come to a stop with minimal interaction by the operator.

The path the Power Wheel was to drive was decided to be make a right turn from side entrance of the Nursing Building and drive straight till it reached the Science and Technology Building, then make a left, and then come to a stop in front of the James Clark Jr. Library Building.

Mounting Ultrasonic Sensor

The goal was to build the mounting plate for the Ultrasonic Sensor, attach the sensor the mounting plate, and to attach the sensor to the Arduino.

The designs for the wooden plate were made for the Power Wheel to allow for 4.5 inch of clearance under the wooden plate. This was changed and the wooden plate was raised 1 inch to allow for maximum clearance under the wooden plate, the same clearance as the axles of the Power Wheel. This is done to allow the most clearance possible, and to avoid taller objects, like grass, that could have possible obstruct the sensor and are not obstacles that would be required to avoid. This will prevent unnecessary damage to the sensor and unnecessary stops for the Power Wheel.

The ultrasonic sensor needs to be attached to the Arduino to work. To attach the ultrasonic sensor, a 4-pin plug is used. The wires for the plug were not long enough to attach to the Arduino from the mounting point of the ultrasonic sensor on the wooden plate. To solve the problem longer wires were soldered on to reach the Arduino. After the wires were attached , heat shrink was used to protect the soldering. The extension wires that were used were all the same color, so the wires needed to be labeled to denote which wire was which.

Modify Code to Incorporate Single Fixed Distance Sensor

The code needed to be changed to allow for the use of the ultrasonic sensor. The Arduino needs to be able to run both the original code to drive and the code for the sensor at the same time. The code for the sensor should be constantly checking if there is any obstacles in the path of the Power Wheel. When an obstacle is detected it needs to pause the driving code at the point it detects the obstacle and be able to restart the code from the same point when the obstacle has been cleared.

Hardware Manufacturing

edit

Parts List

edit
  • Power Wheel, Fisher-Price Power Wheels Dune Racer 12-Volt Battery-Powered Ride-on, Green, $229.00 from walmart.com
  • Miniature linear actuator, a Firgelli Miniature Linear Actuator L16 purchased for $70.00 from firgilli.com
  • Screw motor, 12VDC, 78RPM Motor with Right Angle Leadscrew, purchased for $14.95 from mpja.com
  • Ultrasonic Sensor, Ultrasonic Sensor HC-SR04 Distance Measuring Module, purchased from miniinthebox.com, for $1.98
  • Arduino UNO
  • Monster MotoShield, Sparkfun Electronics
  • Plywood, batteries, and hardware for assembly acquired from the engineering workshop

Hardware Assembly Details

edit

The plywood was cut to make the platform that would sit in the power wheel. The plywood is built to place the other functioning parts, such as the linear actuator, the battery, the Arduino, the wires, and the gas pedal piston. The platform, as well as the other parts, was engineered to ensure that it was easy to remove and re-install if needed. The Power Wheel platform was constructed in two parts, the upper platform to attach to the mounting plate, and a lower platform for the pedal pusher assembly. The two parts were cut from ½” plywood and attached with a section of 2x4 wood stud and attached with 1 ¼” wood screws.
After the platform was built, the steering assembly needed to be constructed. It consisted of three parts: the miniature linear actuator, the steering lever, and the wooden wedge. The steering lever was made from the same material as the platform, ½” plywood, it was attached on either side of the steering will with U-brackets, 3” bolts, and nuts. The height of the wooden wedge was calculated using measurements taken with the aid of the miniature linear actuator. The actuator was extended for seven seconds, half the stroke length, and then attached to the steering wheel lever. The distance was measured from the bottom of the miniature linear actuator to the floor of the mounting platform was measured, that distance was used to measure and construct the wooden wedge. The wooden wedge was constructed from a 2x4 wood stud, and was cut at 50° to match the angle of the steering wheel.
Finally, the last part that needed to be attached was the bracket and the pedal piston to the platform. The pedal pusher assembly was constructed from three parts: the pedal piston, the screw motor, and the mounting bracket. Both the pedal piston and the mounting bracket was constructed from PLA and printed using the MakerBot.
The mount for the Ultrasonic Sensor was added to the front of the Power Wheel. It was attached using the same bolt pattern as the front bumper, with the front bumper reattached back on top. This was done to help protect the Power Wheel and the components from collisions. The mounting plate extended under the front bumper of the Power Wheel and had wooden bumpers attached. The wooden bumpers were added to prevent damage to the Ultrasonic Sensor in case of a collision if the sensor based avoidance system failed.
The last thing that needed to go in the power wheel is the Arduino, battery, and the wires, that can make the power wheel to function as a whole.

Software Implementation

edit

An Arduino Duemilanove and Monster MotoShield were used to control the actuators. Starting with example code (see above) for the motor shield, modifications were made to control vehicle steering and forward motion. In order to drive along a predetermined path along a sidewalk on the campus of Howard Community College, the following code was developed.

Arduino code for Quad Sidewalk Driving Demo
/* 
//*  MonsterMoto Shield Example Sketch
//  date: 5/24/11
//  code by: Jim Lindblom
//  hardware by: Nate Bernstein
//  SparkFun Electronics
// 
// License: CC-SA 3.0, feel free to use this code however you'd like.
// Please improve upon it! Let me know how you've made it better.
// 
// This is really simple example code to get you some basic
// functionality with the MonsterMoto Shield. The MonsterMote uses
// two VNH2SP30 high-current full-bridge motor drivers.
// 
// Use the motorGo(uint8_t motor, uint8_t direct, uint8_t pwm) 
// function to get motors going in either CW, CCW, BRAKEVCC, or 
// BRAKEGND. Use motorOff(int motor) to turn a specific motor off.
// 
// The motor variable in each function should be either a 0 or a 1.
// pwm in the motorGo function should be a value between 0 and 255.
// */
#define BRAKEVCC 0
#define CW   1
#define CCW  2
#define BRAKEGND 3
#define CS_THRESHOLD 100
// 
/*  VNH2SP30 pin definitions
 xxx[0] controls '1' outputs
 xxx[1] controls '2' outputs */
int inApin[2] = {7, 4};  // INA: Clockwise input
int inBpin[2] = {8, 9}; // INB: Counter-clockwise input
int pwmpin[2] = {5, 6}; // PWM input
int cspin[2] = {2, 3}; // CS: Current sense ANALOG input
int enpin[2] = {0, 1}; // EN: Status of switches output (Analog pin)
 
int statpin = 13;
 
void setup()
{
  Serial.begin(9600);
 
  pinMode(statpin, OUTPUT);
 
  // Initialize digital pins as outputs
  for (int i=0; i<2; i++)
  {
    pinMode(inApin[i], OUTPUT);
    pinMode(inBpin[i], OUTPUT);
    pinMode(pwmpin[i], OUTPUT);
  }
  // Initialize braked
  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
  // motorGo(0, CW, 1023);
  // motorGo(1, CCW, 1023);
}
 
void loop()
{
 //1=piston
 //0=pedal
 //CW press
 //actuator is in the middle/halfway

//turn all the way left
motorGo(0, CCW, 1023);
delay(7000); //time required for half stroke length
//// Stop motor to leave the pushed pedal 
motorGo(0, CCW, 0);
delay(100);//time required for the drive
//Push the gas pedal for 1.35 seconds

motorGo(1, CW, 1023);
delay(1350);//time required to push the pedal
//// Stop motor to leave the pushed pedal 
motorGo(1, CCW, 0);
delay(5000);//time required for the drive
//DEPRESS
motorGo(1, CCW, 1023);
delay(1350);//time required to push the pedal
//// Stop motor to leave the pushed pedal 
motorGo(1, CCW, 0);
delay(100);//time required for the drive
//DEPRESS

//turn to neutral position
motorGo(0, CW, 1023);
delay(7000); //time required for half stroke length

//// Stop motor to leave the pushed pedal 
motorGo(0, CCW, 0);
delay(100);//time required for the drive
//Push the gas pedal for 1.35 seconds

//// Stop motor to leave the pushed pedal 
motorGo(1, CW, 0);
delay(40000);//stop
 
 
  if ((analogRead(cspin[0]) < CS_THRESHOLD) && (analogRead(cspin[1]) < CS_THRESHOLD))
    digitalWrite(statpin, HIGH);
}
 
void motorOff(int motor)
{
  // Initialize braked
  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
  analogWrite(pwmpin[motor], 0);
}
 
/* motorGo() will set a motor going in a specific direction
 the motor will continue going in that direction, at that speed
 until told to do otherwise.
 
 motor: this should be either 0 or 1, will selet which of the two
 motors to be controlled
 
 direct: Should be between 0 and 3, with the following result
 0: Brake to VCC
 1: Clockwise
 2: CounterClockwise
 3: Brake to GND
 
 pwm: should be a value between ? and 1023, higher the number, the faster
 it'll go
 */
void motorGo(uint8_t motor, uint8_t direct, uint8_t pwm)
{
  if (motor <= 1)
  {
    if (direct <=4)
    {
      // Set inA[motor]
      if (direct <=1)
        digitalWrite(inApin[motor], HIGH);
      else
        digitalWrite(inApin[motor], LOW);
 
      // Set inB[motor]
      if ((direct==0)||(direct==2))
        digitalWrite(inBpin[motor], HIGH);
      else
        digitalWrite(inBpin[motor], LOW);
 
      analogWrite(pwmpin[motor], pwm);
    }
  }
}

The second phase of software development was the incorporation of sensor data for simple obstacle avoidance. The following tutorial (https://www.youtube.com/watch?v=PG2VhpkPqoA) shows code to work the ultrasonic sensor, resulting in the serial monitor displaying numbers after the code was uploaded.

The following algorithm was implemented to pause normal program execution when an obstacles exists in front of the vehicle.

Flowchart of algorithm for sensor-based pause of Arduino code  

The algorithm shown above was then implemented in a simple Arduino program, separate from the vehicle control program.

Arduino Code to Test Sensor-Based Pausing of Program Execution
#define trigPin 12
#define echoPin 11
   int duration, distance;
   int led = 13;
   int starttime, elapsedtime, pausestart, pauseend, pauseduration;
void setup(){
  Serial.begin (9600);
  pinMode(led, OUTPUT); 
  pinMode (trigPin, OUTPUT);
  pinMode (echoPin, INPUT);
}
void loop(){
  elapsedtime=0;
  pauseduration=0;
  digitalWrite(led, LOW);//led off
  Serial.println("Start of main loop");//debugging
  starttime=millis();// starts counting 
    while (elapsedtime<7000){//while time is under 5 sec (i.etime required foro drive)
      digitalWrite(led, LOW);//led off
      digitalWrite(trigPin, HIGH);//sensor
      delayMicroseconds(1000); //sensor
      digitalWrite(trigPin, LOW);//sensor 
      duration = pulseIn(echoPin, HIGH); //sensor 
      distance = (duration/2) / 29.1;//sensor output
      delay(50);
       if (distance<10){//if distance is below 100 cm
           digitalWrite(led, HIGH);//turn led on
           pausestart=millis();//starts obstruction timing
         //  Serial.print(pausestart);//debugging
          // Serial.println(" pause start");//debugging
           while (distance<100){
              delay (100);//do nothing
              digitalWrite(trigPin, HIGH);//sensor
              delayMicroseconds(1000);//sensor
              digitalWrite(trigPin, LOW);//sensor
              duration = pulseIn(echoPin, HIGH);//sensor
              distance = (duration/2) / 29.1;//sensor output
              Serial.print(distance);//debugging
              Serial.println(" cm from while loop");//debugging
           }
           pauseend=millis();// ends obstruction timing
           pauseduration=pauseend-pausestart;//total wait time for obstruction
         //  Serial.print(pauseend);//debugging
         //  Serial.println(" pause end");//debugging
 
       }
   Serial.print(pauseduration);
   Serial.println(" wait time");//debugging
   elapsedtime=(millis()-starttime)-pauseduration; //subtract wait time from time before osbtruction
   Serial.print(elapsedtime);//debugging
   Serial.println(" elapsed");//debugging
 
  }
}


After troubleshooting, the above code was incorporated with the vehicle control code. The power wheel simply drives straight and stops before hitting an obstacle.

Arduino Code for Sensor-Based Stopping Test
/* 
//*  MonsterMoto Shield Example Sketch
//  date: 5/24/11
//  code by: Jim Lindblom
//  hardware by: Nate Bernstein
//  SparkFun Electronics
// 
// License: CC-SA 3.0, feel free to use this code however you'd like.
// Please improve upon it! Let me know how you've made it better.
// 
// This is really simple example code to get you some basic
// functionality with the MonsterMoto Shield. The MonsterMote uses
// two VNH2SP30 high-current full-bridge motor drivers.
// 
// Use the motorGo(uint8_t motor, uint8_t direct, uint8_t pwm) 
// function to get motors going in either CW, CCW, BRAKEVCC, or 
// BRAKEGND. Use motorOff(int motor) to turn a specific motor off.
// 
// The motor variable in each function should be either a 0 or a 1.
// pwm in the motorGo function should be a value between 0 and 255.
// */
#define BRAKEVCC 0
#define CW   1
#define CCW  2
#define BRAKEGND 3
#define CS_THRESHOLD 100
#define trigPin 12
#define echoPin 11
// 
/*  VNH2SP30 pin definitions
 xxx[0] controls '1' outputs
 xxx[1] controls '2' outputs */
int inApin[2] = {7, 4};  // INA: Clockwise input
int inBpin[2] = {8, 9}; // INB: Counter-clockwise input
int pwmpin[2] = {5, 6}; // PWM input
int cspin[2] = {2, 3}; // CS: Current sense ANALOG input
int enpin[2] = {0, 1}; // EN: Status of switches output (Analog pin)
int statpin = 4;
int duration, distance;
int led = 13;//
int starttime, elapsedtime, pausestart, pauseend, pauseduration;//
 
void setup()
{
  Serial.begin(9600);
  pinMode(statpin, OUTPUT);
  pinMode (led, OUTPUT); //
  pinMode (trigPin, OUTPUT);//
  pinMode (echoPin, INPUT);//
  // Initialize digital pins as outputs
  for (int i=0; i<2; i++)
  {
    pinMode(inApin[i], OUTPUT);
    pinMode(inBpin[i], OUTPUT);
    pinMode(pwmpin[i], OUTPUT);
  }
  // Initialize braked
  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
  // motorGo(0, CW, 1023);
  // motorGo(1, CCW, 1023);
}
 
void loop()
{
 //1=piston
 //0=pedal
 //CW press
 //actuator is in the middle/halfway
 //straight drive while checking for obstacle
// right drive turn 
// press
motorGo(1, CW, 1023);//added
delay(1350);//time required to push the pedal 1.35 secs
motorGo(1, CCW, 0);//stop
  
   elapsedtime=0;
  pauseduration=0;
  digitalWrite(led, LOW);//led off
  Serial.println("Start of main loop");//debugging
  starttime=millis();// starts counting 
    while (elapsedtime<5000){//while time is under 5 sec (i.etime required foro drive)
      digitalWrite(led, LOW);//led off
      digitalWrite(trigPin, HIGH);//sensor sends beam
      delayMicroseconds(1000); //sensor wait
      digitalWrite(trigPin, LOW);//sensor stops beam
      duration = pulseIn(echoPin, HIGH); //sensor receives beam
      distance = (duration/2) / 29.1;//sensor output
      delay(50);
       if (distance<250){//if distance is below 100 cm
           digitalWrite(led, HIGH);//turn led on
           motorGo(1, CCW, 1023);//added
           delay(1350);//time required to push the pedal
           motorGo(1, CCW, 0);//added 
           pausestart=millis();//starts obstruction timing
         //  Serial.print(pausestart);//debugging
          // Serial.println(" pause start");//debugging
           while (distance<250){
              delay (200);//do nothing
              digitalWrite(trigPin, HIGH);//sensor
              delayMicroseconds(1000);//sensor
              digitalWrite(trigPin, LOW);//sensor
              duration = pulseIn(echoPin, HIGH);//sensor
              distance = (duration/2) / 29.1;//sensor output
              Serial.print(distance);//debugging
              Serial.println(" cm from while loop");//debugging
           }
           pauseend=millis();// ends obstruction timing
           pauseduration=pauseend-pausestart;//total wait time for obstruction
         //  Serial.print(pauseend);//debugging
         //  Serial.println(" pause end");//debugging
 
       }
   Serial.print(pauseduration);
   Serial.println(" wait time");//debugging
   elapsedtime=(millis()-starttime)-pauseduration; //subtract wait time from time before osbtruction
   Serial.print(elapsedtime);//debugging
   Serial.println(" elapsed");//debugging
 
  }

 
  if ((analogRead(cspin[0]) < CS_THRESHOLD) && (analogRead(cspin[1]) < CS_THRESHOLD))
    digitalWrite(statpin, HIGH);
}
 
void motorOff(int motor)
{
  // Initialize braked
  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
  analogWrite(pwmpin[motor], 0);
}
 
/* motorGo() will set a motor going in a specific direction
 the motor will continue going in that direction, at that speed
 until told to do otherwise.
 
 motor: this should be either 0 or 1, will selet which of the two
 motors to be controlled
 
 direct: Should be between 0 and 3, with the following result
 0: Brake to VCC
 1: Clockwise
 2: CounterClockwise
 3: Brake to GND
 
 pwm: should be a value between ? and 1023, higher the number, the faster
 it'll go
 */
void motorGo(uint8_t motor, uint8_t direct, uint8_t pwm)
{
  if (motor <= 1)
  {
    if (direct <=4)
    {
      // Set inA[motor]
      if (direct <=1)
        digitalWrite(inApin[motor], HIGH);
      else
        digitalWrite(inApin[motor], LOW);
 
      // Set inB[motor]
      if ((direct==0)||(direct==2))
        digitalWrite(inBpin[motor], HIGH);
      else
        digitalWrite(inBpin[motor], LOW);
 
      analogWrite(pwmpin[motor], pwm);
    }
  }
}

Testing and Performance Verification

edit

Testing and analysis

edit

The most basic test of functionality includes turning right or left independently. This functionality is demonstrated in the following preliminary tests.

Left turn test video
Right turn test video

After getting the power wheel to just drive left and then right, we designed a path on which we can prove that the power wheel can turn right, go straight, and turn left all in one drive.

Right, Straight, and Left test video

Many changes were made to the code during testing. Actuation times were determined via trial-and-error. To minimize the strain on the Power Wheel and the steering components, steering wheel actuation only occurs when the vehicle is moving.

The Power Wheel initially was set to high gear, this was allowing for to much wheel spin resulting in poor traction and inconsistent drive times. To alleviate these the Power Wheel was put in low gear. This reduced wheel spin, but did not completely resolve the issue. The Power Wheel was making a turn as its initial movement and this was not consistent with even the minimal wheel spin, to solve the issue a floor mat was placed under the rear wheels to provide better traction.

After implementing the Ultrasonic Sensor HC-SR04, we decided to test the reliability of the sensor and the stopping time for the power wheel. In these videos we had the range set at 250cm, in other words if an object is less than 250 cm, the pedal actuator will retract and stop the car.

Distance Sensor Testing Video Compilation

The verification of performance to system requirements

edit

According to the videos, the power wheel does pass the basic requirements that we hoped the power wheel would accomplish. The power wheel does turn right and it does turn left, the only issue the power wheel faces is that it takes the power wheel a wider circle to turn both ways. This results in the power wheel taking a longer time to drive and also takes up a lot of space to drive.

Operate

edit

Develop content related to conducting public demonstrations, competitions, or extended tests of navigation, path planning, and/or obstacle avoidance.

Demo

edit

Video of vehicle driving on campus

 
Presentation Slides

Next Steps

edit
  • Improve and document design of the electrical system.
  • Add a gear shift actuator. A gear shift assembly will allow the Power Wheel to go between high and low gear, and to go in reverse. As of now the Power Wheel is set in low gear, to stop wheel spin and to have constant results, engaging high gear once in motion will allow for the Power Wheel to traverse the path at a much quicker time. This will also be helpful when the Power Wheel encounters a steep incline, it can switch to low gear and have more torque to ascend the incline. Reverse will be helpful to avoid obstacles and to change driving paths.
  • Design capability for greater field of view for sensing obstacles. For complete autonomy, obstacle detection will be required in multiple directions, including behind the vehicle.
  • Add a wireless kill switch. The kill switch will allow for the Power Wheel to stop at any given moment if the human operator determines operation is unsafe. This will allow for the operator to stop the Power Wheel without having to chase down the Power Wheel while in motion, to avoid obstacles, or from driving into unsafe situations.
  • Develop software for obstacle avoidance.
  • Develop software for navigation. Enable travel between two points on campus, using GPS, waypoints, landmarks, internal map, etc.
  • Combine navigation, path planning, and obstacle avoidance behaviors into one control algorithm.