Code for our FYDP -only one IMU works right now -RTOS is working

Dependencies:   mbed

bt_shell/machine_interface/ros_machine_interface.h

Committer:
majik
Date:
2015-03-18
Revision:
0:964eb6a2ef00

File content as of revision 0:964eb6a2ef00:

#ifndef ROS_MACHINE_INTERFACE_H
#define ROS_MACHINE_INTERFACE_H
//THIS FILE IS INCOMPLETE///


/**This file contains the implementations for the controls through a python interface
//The brain file uses ';' to separate lines
Read IMU [acceleration and gyros]
Read Gyro
Read Angle
Read Acceleration
Read IR sensors
Read Optical flow sensors
Read current sensor
Read voltage sensor

Drive to [x,y] (x,y)
Drive fwd      (speed, time)
Run R motor    (speed,time)
Run L motor     (speed,time)
Set Direction   (direction)
Enable IMU control (bool)   //if this is enabled, IMU will keep robot straight
*/
#include "keybindings.h"


int ros_get_cmd(); //this reads from the bt connection
int q_pow10(int n);     //this calculates 10^n quickly (only up to 10^6)
void print_all();
int ros_get_cmd(char s[16], int n);
//char C;
//char buffer[10];
int IR_mm(float x);

bool ros_shell_connection(char c)
{
    char S[16];
    float dum;
    float param[5];
    int arg_in[10];
    char run_time;
    int m_offset = 100; //use this so that the MATLAB can send motor values between 0 and 200 instead of -100 and 100
    //bt.printf("&%f;",t.read());

    switch (c)
    {
        case CONNECTION:   //Return query if connection is ready
            bt.lock();
            bt.printf("\nEBOTDEMO\n");
            bt.unlock();
            reckon.reset();
            break;
        case ALL_SENSOR:    //returns ALL sensor data //while robot is moving, send things every 50milliseconds
            print_all();
            break;
        case CURRENT_SENSE:
            break; 
        case IMU_READ:
            send_flag = 1;
            //bt.lock();
            //bt.printf("i;%3.3f;%3.3f;%3.3f;%3.3f;%3.3f;%3.3f;",imu_data.acc[0],imu_data.acc[1],imu_data.acc[2],imu_data.ypr[0],imu_data.ypr[1],imu_data.ypr[2]);
            //bt.unlock();
            break;
        case IMU_YAW:
            dum = imu_data.ypr[0]*180/PI;
            bt.lock();
            bt.printf("y;%3.3f;",dum);
            bt.unlock();
            break;
        //optical flow
        case OPT_READ:
            //return optical flow (pixels/second for left and right)
            //TODO: include second optical flow sensor
            //bt.printf("O;%3.3f;%3.3f;",opt_flow.dx_px,opt_flow.dy_px);
            bt.lock();
            bt.printf("%c;%d;%d;%d;%d;",OPT_READ,reckon.flow_dx_L,reckon.flow_dy_L,reckon.flow_dx_R,reckon.flow_dy_R);
            bt.unlock();
            reckon.reset();
            break;
        case IR_READ:
            //return 5 IR sensors clockwise (Front, right_front, right_rear, left_rear, left_front)
            //ask Wen to fill out this function
            extern AnalogIn irL;
            extern AnalogIn irC;
            extern AnalogIn irR;
            extern DigitalOut irBack;
            if(irBack){
                irBack = 0; //read from IR
                Thread::wait(50);
            }
            param[0] = irL.read();
            Thread::wait(10);
            param[1] = irC.read();
            Thread::wait(10);
            param[2] = irR.read();
            param[3] = 0;
            param[4]=0;
            //irBack = 1; //read back IR
            /*Thread::wait(50);
            param[3] = irL.read();
            Thread::wait(10);
            param[4] = irR.read();
            irBack = 0;*/
            //bt.printf("%f;%f;%f;%f;%f;",param[0],param[1],param[2],param[3],param[4]);
            for(int i = 0; i<5; i++)
                arg_in[i]=IR_mm(param[i]);
            bt.lock();
            bt.printf("%d;%d;%d;%d;%d;",arg_in[0],arg_in[1],arg_in[2],arg_in[3],arg_in[4]);
            bt.unlock();
            //Thread::wait(40);
            break;
        /*case IR_1:
            if(irBack){
                irBack = 0;
                Thread::wait(50);
            }
            param[0] = irL.read();
            bt.printf("%c;%f;",IR_1,param[0]);
            break;
        case IR_2:
            if(irBack){
                irBack = 0;
                Thread::wait(50);
            }
            param[0] = irC.read();
            bt.printf("%c;%f;",IR_2,param[0]);
        break;
        case IR_3:
            if(irBack){
                irBack = 0;
                Thread::wait(50);
            }
            param[0] = irR.read();
            bt.printf("%c;%f;",IR_3,param[0]);
        break;
        case IR_4:
            if(!irBack){
                irBack = 1;
                Thread::wait(50);
            }
            param[0] = irR.read();
            bt.printf("%c;%f;",IR_4,param[0]);
            break;
        case IR_5:
            if(!irBack){
                irBack = 1;
                Thread::wait(50);
            }
            param[0] = irL.read();
            bt.printf("%c;%f;",IR_5,param[0]);
        break;*/
        case LOCATION:
            //return x,y,z,theta (maybe not z)
            break;
            
        case MOTOR:   //command: 'w[L_speed],[R_speed]      //I should write an actual function to receive data from serial
            //Another argument should be included: time to run motors.
            arg_in[0] = ros_get_cmd();
            arg_in[1] = ros_get_cmd();
            arg_in[2] = ros_get_cmd();
            if(arg_in[0] == arg_in[1] && arg_in[0] > 100){
                if(IR_mm(irC.read()) < 260 && IR_mm(irC.read()) > 0) //if there is an obstacle, don't drive fwd
                {   
                    bt.lock();
                    bt.printf("&;OBSTACLE;");
                    bt.unlock();
                    break;
                }
                fwd_flag = 1;
            }
            moveMotors(arg_in[0]-m_offset,arg_in[1]-m_offset,arg_in[2]);
            bt.lock();
            bt.printf("L=%d;R=%d;t=%d",arg_in[0],arg_in[1],arg_in[2]); //don't need to respond. Maybe have a confirmation?
            bt.unlock();
            send_flag = 1;
            break;

        case (MOTOR_STOP):
            *motors.Right = 0;
            *motors.Left = 0;
            send_flag = 0;  //
            break;
            
        
        
        
        case (IMU_CALIBRATE):
            calibrate_flag = 1;
            break;
        case (OPT_CALIBRATE):
            calibrate_optFlow_flag=1;
            break;
        case END_CONNECTION:
            bt.lock();
            bt.printf("End Connection\n");
            bt.unlock();
            return 0;
            ///break;
        default:
            bt.lock();
            bt.putc(c); //echo command
            bt.unlock();
            break;
    }
    bt.lock();     
    bt.printf("\n\r");
    bt.unlock();
    return 1;
}
int ros_get_cmd(char s[16], int n)
{
    int i= 0, j = 0;
    char S[16];
    int count = 0;
    while(count < n && i<13)
    {
        if(s[i] == ';')
            count++;
        i++;
    }
    count = 0;
    while(i<13)
    {
        if(s[i] == ';')
            break;
        S[j] = s[i];
        j++;
        i++;
    }
    for(i=0;i<j;i++)
    {
        count += ((S[i])-48)* q_pow10(j-i-1);
    }
    return count;
}
void ros_interface_send_data()
{
    //int mseconds = (int)time(NULL)+(int)t.read_ms();
    bt.lock();            
    bt.printf("&%d;",t.read_ms());//indicate start of line, output system time
    bt.unlock();
    //send all the requested data
    //if (x.list[0]){ //send all imu data
        //bt.printf("A%3.3f,%3.3f,%3.3f,G%3.3f,%3.3f,%3.3f",mpu.ax,mpu.ay,mpu.az,mpu.gx,mpu.gy,mpu.gz);
    //}
    
        //0 - IMU_all
        //1 - IMU_acc
        //2 - IMU_gyr
        //3 - IMU_rotation
        //4 - IR_sensors
        //5 - Optical_flow_sensors
        //6 - Current_sensor
        //7 - Voltage_sensor
        
        
}

int  ros_get_cmd()   //this requires a ',' or ';' or <enter> at the end of every command
{
    char c = '0';
    char C[10];     //stores the array of chars read
    int n=0;        //counter
    int timeout = 0;    //timeout counter
    int accum=0;  //accumulates value of array
    
   while(c != ',' && c != 13 && c !=';' && c!='x'){    //keep looping until a comma/semicolon is read (or enter is pressed)
        bt.lock();            
        while(! bt.readable()){
            bt.unlock();
            Thread::yield();   //wait for char input
            timeout++;
            if(timeout > 10000)   //if one second has passed, give up on this command
                return -1;
            bt.lock();
        }            
        c= bt.getc();   //read the next char in the buffer
        bt.unlock();
        
        //bt.printf("%c",c);  //REMOVE THIS. DEBUG ONLY
        //if(c == '.' || n >=9) break;  //concatenate decimals. I'm not handling decimals. No reason.
        C[n]=c;
        n++;
   }
    
    for(int i = 0; i<n-1; i++){
          //need to subtract 2: 1 b/c n is incremented at the end of each iteration, 2 b/c comma is read.
          accum += ((C[i])-48)* q_pow10(n-i-2);
    }
  // memset(buffer, 0 , sizeof buffer);
    return accum;
}

int q_pow10(int n){     //returns 10^n, up to 10^7  [8 sig figs]
    static int pow10[8] = {1,10,100,1000,10000,100000,1000000,10000000};
    return pow10[n];
}
void print_all(){   //call this function to print all sensor data
    float data[13];
    data[0]= getTime();
    data[1]= imu_data.ypr[0];
    data[2]= imu_data.ypr[1];
    data[3]= imu_data.ypr[2];
    
    data[4]= imu2_data.ypr[0];
    data[5]= imu2_data.ypr[1];
    data[6]= imu2_data.ypr[2];
    
    
    bt.lock();
    bt.printf("&;");
    bt.printf("%f;",data[0]);       //print time as an integer (milliseconds)
    for(int i = 1; i<=6; i++){
            bt.printf("%.3f;",data[i]);
    }
    bt.printf("\n\r");
    bt.unlock();
    //commented out the below code because we want to ignore the rear IR sensors
    /*dt = t.read() - data[0];
    irBack = 1;
    if(dt < 50)
        Thread::wait(50-dt);
    
    data[6]= irR.read();
    data[7]= irL.read();
    data[8]= imu_data.ypr[0]*180/PI;
    irBack = 0;
    */

}
int IR_mm(float x)  //converts IR sensor value to millimeters
{
    //return 9462/(x*3.3/5*1024 - 16.92);
    if (x <= 0.24)
        return -1;
    return 170/x;
}

#endif