Motion Class Interface for controlling robot motion using the Handyboard



Theory of Operation


 

The two motors for the laptop robot are controlled by a dual 10-amp motor driver board that receives PWM (Pulse Width Modulated) speed control signals from the Handyboard.The Handyboard has four built in PWM motor control outputs and built in library function for controlling the speed of the motors.The Handyboard motor control output does not provide enough current to drive the laptop robot motors but the PWM signal generated by the Handyboard motors outputs can be applied to the motor enable input of the Maxi Dual 2 H-bridge motor driver board which has the capability of providing 10 amps to each motor.This arrangement allows the speed and direction of each motor to be controlled independently to provide control of laptop robot motion.It is not necessary to know the details of the motion control hardware to program motion control abilities of the laptop robot.A Visual C++ motion control class interface is available with functions that handle the communication details with the handyboard.All you need to know are the behaviors of a few of the motion control functions and the correct parameters to pass to each function.
 

Motion Control Interface


 

There are about twenty functions available in the motion control class but you only need a few basic functions to control robot motion.The remaining functions are primitives that are used to construct the higher level motion control functions.The function primitives are only needed if you want to create you own motion control functions otherwise you just need to combine the higher level functions to control robot motion.The speed and direction of each motor is controlled by the speed parameter passed to some of the motion control functions.The speed ranges from 0 to 200 with 0 being full reverse and 200 equal to full forward and 100 equal to stop.This system eliminates the need for negative numbers to specify reverse direction of the motors.
 

Communication Protocol (optional information)


 

In order to make the control system compatible with different computers and programming languages the serial port is used as the method to communicate and send motion control commands to the Handyboard and detailed knowledge of the Handyboard hardware or software is not necessary. The motion class interface handles the communications protocol and is invisible to the user of the class unless you want to write your own functions. If you do write your own functions then you must construct a motion command packet, send the start transmission character “STX” (0x02), wait for acknowledgement character “ACK” (0x06) signal from the handyboard, and then send the remainder of the packet.The format for the packet is:

Packet[0] = 0x02 (“STX” start transmission character)

Packet[1] = ‘L’ (Left motor speed delimiter character)

Packet[2 - 4] =(Left motor speed as a three digit short/int – 0 to 255)

Packet[5] = ‘R’ (Right motor speed delimiter character)

Packet[6 - 8] = (Right motor speed as a three digit short/int – 0 to 255)

Packet[9] = 0x03 (“ETX” end transmission character)

Packet[10] = 0x0D (Carriage return character)

Once you construct this packet you must send the first character (0x02) of the packet until you receive an “ACK” (0x06) character from the Handyboard.This indicates that the Handyboard is ready to receive the remainder of the packet.The Send_packet(char * speed_packet) function handles this process for you and all it needs is a pointer to the packet string passed as a parameter.IMPORTANT: If the handyboard is not turned on or has a bad connection to the serial port then the Send_packet function will hang up until it receives the “ACK” (0x06) character from the Handyboard.
 

Motion Control Functions


 

Although, there are many methods in motion control class only a few are needed to control the motion of the robot.It is also important to understand the meaning of the parameters each method requires.For additional information on each method read the comments provided for each method in the motion2p1.h class header file.The left and right motors are defined to be x and y respectively.Motor speed is defined from 0 to 200 with 0 representing full speed reverse and 200 representing full speed forward.Zero speed is defined as 100.The main high level motion control methods are: forward(), turnleft(), turnright(), steerCar(), IncreaseSpeedx, IncreaseSpeedy and stop().Each of these methods is described below.


 

void forward(short speed);// Move both x and y motors forward at constant absolute speed. Takes a short value from 0 to 200 (0 = full reverse, 200 = full forward) as forward absolute speed.This method is also used to make the robot move backwards by setting the speed parameter to < 100.

void steerCar(short turnspeed);// Turn right (+turnspeed = clockwise)) or left (-turnspeed = counterclockwise ) by given rate.This method adds the value turnspeed to the outside motor (outside radius of turn) and subtracts turnspeed from the inside motor (inside radius of turn) giving the robot a turn rate proportional to turnspeed.When this method returns, it restores the motor speeds to their original value before the call. For a fixed turn rate the total angle of turn is proportional to the frequency of calls to this method.Use this method for closed loop feedback type steering control.

void turnleft(short turnspeed);// Turn left (counterclockwise) relative to current forward speed. This method adds the value turnspeed to the outside motor (outside radius of turn) and subtracts turnspeed from the inside motor (inside radius of turn) giving the robot a turn rate proportional to turnspeed. Repeated calls to this method are cumulative and increase the turnleft rate with each call to this method.The absolute x and y motors speeds are changed by a call to this function.

void turnright(short turnspeed);// Turn right (clockwise) relative to current forward speed. This method adds the value turnspeed to the outside motor (outside radius of turn) and subtracts turnspeed from the inside motor (inside radius of turn) giving the robot a turn rate proportional to turnspeed. Repeated calls to this method are cumulative which increases the turnright rate with each call to this method.The absolute x and y motors speeds are changed by a call to this function.

void stop(void);// Stop robot motor motion.Set both x and y motors to a speed of 100 (zero speed).

void IncreaseSpeedx(short deltax);//Increase motor x spdx varaible by deltax increment value.This method adds the value deltax to the current motor x speed value. A negative deltax value decreases the current motor x speed value.This method changes the internally stored value of the spdx variable and does not take effect until a call to the speedCARxy() method which seeds the x motor (spdx) and y motor (spdy) speed commands to the Handyboard.

void IncreaseSpeedy(short deltay);//Increase motor y spdy varaible by deltay increment value. This method adds the value deltay to the current motor y speed value. A negative deltay value decreases the current motor y speed value.This method changes the internally stored value of the spdy variable and does not take effect until a call to the speedCARxy() method which seeds the x motor (spdx) and y motor (spdy) speed commands to the handyboard.
 

Motion Class Primitives


 

All of the motion functions are based on the three basic motion class methods Setspeedx, Setspeedx, and speedCARxy.Setspeedx and Setspeedy sets the motion class member speed variables spdx and spdy, for the left and right motors, respectively.Motor speed is defined from 0 to 200 with 0 representing full speed reverse and 200 representing full speed forward. Zero speed is defined as 100.The motor speed values do not become effective until the speedCARxy() method is called.This method forms the motion command packet and calls the Send_packet() method which sends the command to the Handyboard throught the serial port.Use the Setspeedx, Setspeedx, and speedCARxy methods to create custom motion control methods.
 

void Setspeedx(short speedx);//Changes the speed of the motor x and updates the spdx member variable to represent the actual internal robot speed value. Used by the movement command functions

void Setspeedy(short speedy);//Changes the speed of the motor y and updates the spdy member variable to represent the actual internal robot speed value. Used by the movement command functions

void speedCARxy();//This method sends a motor speed packet to the Handyboard to set the motor x and motor y speed values. The current value of the spdx and spdy variables is sent to the Handyboard.

Motion control class interface header file listing

 motion2p1.h

Motion control class implimentation .cpp file listing

motion2p1.cpp
 

Sample Program


 

Follow these steps to use the MOTION class in a program.

1.Include the motion2p1.h header file in your program

2.Instantiate a MOTION object in your program

3.Use the methods of the class as necessary to control robot motion

4.The handyboard must be on with the cable connected between the handyboard and the computers serial port.The program will lock up if there is a bad connection between the laptop and handyboard or the handyboard is not connected.
 

//Sample motion control program


 

#Include <iostream.h>

#Include “motion2p1.h” // Step1 Include the motion2p1.h header file in your program

Int main(void)

{
 

MOTION motors; // Step 2 Instantiate a MOTION object in your program

char key;

cin>>key;

switch(key) //Step 3 Use the methods of the class as necessary to control robot motion.

{

case '8'://Move Forward command input

 
cout<<"Move Forward"<<endl;

motors.IncreaseSpeedx(10);

motors.IncreaseSpeedy(10);

motors.speedCARxy();

//motors.forward(130);//Or just use this method

cout<<" - spdx = "<<motors.GetSpeedx()<<", spdy = "<<motors.GetSpeedy()<<endl;

break;

case '2':case 'k':case 'K'://Move Backward command input

cout<<"Move Backward"<<endl;

motors.IncreaseSpeedx(-10);

motors.IncreaseSpeedy(-10);

motors.speedCARxy();

//motors.forward(70);//Or just use this method

cout<<" - spdx = "<<motors.GetSpeedx()<<", spdy = "<<motors.GetSpeedy()<<endl;

break;

case '5':case 'i':case 'I'://Stop motion command input

cout<<"Stop Motion"<<endl;

speed = 0;

motors.stop();

cout<<" - spdx = "<<motors.GetSpeedx()<<", spdy = "<<motors.GetSpeedy()<<endl;

break;

case '4':case 'u':case 'U'://Turn Left command input

cout<<"Turn Left"<<endl;

motors.turnleft(5);

cout<<" - spdx = "<<motors.GetSpeedx()<<", spdy = "<<motors.GetSpeedy()<<endl;

break;

case '6':case 'o':case 'O'://Turn Right command input

cout<<"Turn Right"<<endl;

motors.turnright(5);

cout<<" - spdx = "<<motors.GetSpeedx()<<", spdy = "<<motors.GetSpeedy()<<endl;

break;

 

default:

break;
 

}//End switch statement
}//End main