Semi-Functional EtchSketch Smartbot code. Takes x/y values and draws with polar coords.

main.cpp

Committer:
theschrade54
Date:
2012-12-15
Revision:
0:eae9712515a6

File content as of revision 0:eae9712515a6:

#include "mbed.h"
#include "motordriver.h"
#include "Servo.h"
#include "HMC6352.h"

HMC6352 compass(p9, p10);
//Smartbot

DigitalOut mbedled1(LED1); //signals draw mode
DigitalOut mbedled2(LED2); //singals relocate mode
DigitalOut mbedled3(LED2); //signals left wheel movement
DigitalOut mbedled4(LED2); //signals right wheel movement

Serial pc(USBTX, USBRX); // tx, rx
Serial controller(p13, p14); //change to whatever rcv method we use

//See http://mbed.org/cookbook/Motor
//http://mbed.org/users/4180_1/notebook/sparkfun-magician-robot-base-kit/
//Connections to dual H-brdige driver for the two drive motors
Motor left(p21, p22, p20, 1); // pwm, fwd, rev, has brake feature
Motor right(p24, p25, p27, 1);

Servo penservo(p23);

int main()
{
    //init command vars
    char command = 0; //bit0 = 1 if shake; bit7 = 0 if y, 1 if x; bit6 = 0 if pos, 1 if neg
    char XorY = 128; // X or Y move command bitmask
    char NorP = 64; // Down or Up move command bitmask
    char mag = 62; // bitmask for magnitude of move command
    char magnitude = 0; //magnitude of move

    //Direction and Movement Variables, start on page 0 facing +y with dx, dy =0
    float nphi, myphi, dphi = 0.0; //angle math, (36)0 = +y, 90 = +x, 180 = -y, 270 = -x
    float dy, dx = 0.0; // where on page?
    float ny, nx = 0.0; // next move command coords
    //int pagesize = 1050; //square page side draw length + border
    float moveweight = 0; //length of current move order, effects speed
    int comcount = 4; //number of move commands to add into 1 move order
   // int flip = 0; //backwards to save time?
    int i;
    
    //Init Servo
    penservo = .5;

    //Initialize LEDs
    mbedled1 = 1;
    mbedled2 = 0;

    //Init IR Receiver
    controller.baud(2400);
    wait(1);
    
    //Init Compass to continuous mode, periodic set/reset, 20Hz measurement rate.
    compass.setOpMode(HMC6352_CONTINUOUS, 1, 20);
    wait(3);
    
    //Init Compass reading to 0
    for (i = 0; i < 5; i++) {  //Take Averaged Compass reading
        myphi += compass.sample()/50.0;
        wait(.05);
    }
    dphi = nphi - myphi;               // calc angle diff
    while (abs(dphi) > 15) {           // if diff sig, turn to 0
        myphi = 0.0;
        left.speed(-.5);
        for (i = 0; i < 3; i++) {  //Take Averaged Compass reading
        myphi += compass.sample()/30.0;
        wait(.01);
        }
        dphi = nphi - myphi;  
        wait(.01);             
    }         
    right.stop(1);                   //stop wheel(s) after turn 
    left.stop(1);              
    wait(.5);
    
    //pc.printf("myphi: %f", myphi); 
    //pc.printf("starting \n");

    while(1) {

        //if readable, get command
        if(controller.readable()) {
            mbedled2 = 1;
            command = controller.getc(); //Serial read
            comcount--;
            //pc.printf("%x \n", (command));
            mbedled2 = 0;
        }   else if (comcount < 4) { //decrement if command countdown started even if no command read
            command = 0;
            comcount--;
        }   else {
            command = 0;
        }

        //check for shake
        if (command==1) { //lift pen up and reposition
            mbedled1 = 0;
            penservo = 1;
            wait(3);
            dx = 0; //reset vars after reposition
            dy = 0;
            comcount = 5;
            mbedled1 = 1;
            penservo = .5;
        }

        //check for move command
        if ((abs(command) > 1) && (comcount > 0)) {
            magnitude = mag & command;
            if ( (command & XorY) == 128 ) {        // if bit7 then X axis
                if ( (command & NorP) == 64 ) {         // if bit6 then -x
                   // nx -= (.3+magnitude/16.0)/5.0;
                   nx -= magnitude / 4.0;
                } else {                                //else if !bit6 then +x
                   // nx += (.3+magnitude/16.0)/5.0;
                   nx += magnitude / 4.0;
                }
            } else {                                //else if !bit7 then Y axis
                if ( (command & NorP) == 64 ) {         // if bit6 then -y
                   // ny -= (.3+magnitude/16.0)/5.0;
                   ny -= magnitude / 4.0;
                } else {                                //else if !bit6 then +y
                   // ny += (.3+magnitude/16.0)/5.0;
                   ny += magnitude / 4.0;
                }
            }
            wait(.05);
        } else if (comcount == 0) { //move math
            if ((nx != 0) && (ny != 0)) {    // if both x&y change, calculate vector angle and length in polar coords
                dx += nx;
                dy += ny;
                moveweight = pow(ny, 2) + pow(nx, 2);   //moveweight = r
                moveweight = sqrt(moveweight);
                nphi = atan2(nx, ny);                   //new phi = principal arctan from -180 to 180. x and y flipped to get angle from y to x
                //pc.printf("POLAR myphi: %f, newphi: %f, movelength: %f \n", myphi, nphi, moveweight); 
            } else {
                dphi = 0;
                moveweight = 0;
            }
            
            for (i = 0; i < 3; i++) {  //Take Averaged Compass reading
                myphi += compass.sample()/30.0;
                wait(.01);
            }
            
            if (abs(nx) < 2) {                   //if only signif. y axis move
                moveweight = abs(ny);                        // set speed
                if (ny < -2) {nphi = 180;}         // set angles to axis 
                else if (ny > 2) {nphi = 0;}
                else {nphi = myphi;
                    moveweight = 0;}
            }
    
            if (abs(ny) < 2) {                   //if only signif. x axis move
                moveweight = abs(nx);
                if (nx < -2) {nphi = 270;}
                else if (nx > 2) {nphi = 90;}
                else {nphi = myphi;
                    moveweight = 0;}
            }
             
            dphi = nphi - myphi;               // calc angle diff
            //if (abs(dphi) > 340) { dphi = 0;}        // fix pos y axis
            /*if ((160 < abs(dphi)) && (abs(dphi)< 200)) {
                moveweight = -moveweight;
                dphi = 0;}       //flip speed instead of flip around
            if (dphi > 180) {                 // switch angle diff with mag above 180 and flip
                nphi -= 180;
                 moveweight = -moveweight;   //flip speed
            }
            if (dphi < -180) {
                nphi += 180;
                 moveweight = -moveweight;      //flip speed
            }
            */
            
            
            if (abs(dphi) > 15) { //turn left
                right.stop(1);                   //stop wheels before turn 
                left.stop(1);
                wait(.1);
                while (abs(dphi) > 15) {           // if diff sig, turn to 0
                    myphi = 0.0;
                    left.speed(-.5);
                    for (i = 0; i < 2; i++) { //Take quick Averaged Compass reading
                    myphi += compass.sample()/20.0;
                    wait(.01);}
                    dphi = nphi - myphi;               
                }         
                right.stop(1);                   //stop wheels after turn 
                left.stop(1);              
                wait(.1);
            }                         
            
            while (moveweight >= 1) {   //go fwd for r
                left.speed(.7);  
                right.speed(.7);
                wait(.1);
                moveweight--;
                //moveweight = moveweight/2;
            }
            
            while (moveweight <= -1) {   //go back for r
                left.speed(-.7);  
                right.speed(-.7);
                wait(.1);
                moveweight++;
                //moveweight = moveweight/2;
            }
    
            comcount = 4;            //reset vars
            nx = 0;
            ny = 0;
            moveweight = 0;
            dphi = 0;

        } else { //else stop
            left.stop(1);
            right.stop(1);
            wait(.1);
        }
    }
}