NXP cup car code made by Pascal. "stable" version apr. 2016

Dependencies:   mbed FRDM-TFC PIDcontroller FreescaleIAP Vision MMA8451Q MotorControl

main.cpp

Committer:
Clarkk
Date:
2019-02-20
Revision:
3:c21068661635
Parent:
2:eb79d6e3f701

File content as of revision 3:c21068661635:

#include "mbed.h"
#include "TFC.h"
#include "MotorControl.h"
#include "Vision.h"
#include "MMA8451Q.h"
#include "PIDcontroller.h"

Serial pc(USBTX,USBRX);
Serial debug(PTD3,PTD2);
Ticker convTicker,batLevelTicker;
Timeout camExpoTimeout;
Timer t;
Ticker test;
Motors motors;
Vision vision;
PID steeringPID;
PID speedPID;

uint32_t convCounter = 0;

float getSteeringValue(float pixelIndex)
{
    // return steering angle to send to servo function of pixel target
    return ((-5e-6*pixelIndex+0.0009)*pixelIndex-0.0248)*pixelIndex-0.9129;
    //return ((-5e-6*pixelIndex+0.0009)*pixelIndex-0.0224)*pixelIndex-0.9218;
}

float flt[4]={0,0,0,0};
float steeringFilter(float x)
{
    return 2.0*x;
    
/*  uint8_t i;
    
    for(i=3;i>0;i--)
    {
        flt[i] = flt[i-1];
    }
    flt[0] = x;
    
    return (flt[0]+flt[1]*0.75+flt[2]*0.5+flt[3]*0.25)/2.5;*/
}

void applySteeringCommand(float value)
{
    float clamp = 0.55;
    if(value > clamp)
        value = clamp;
    if(value < -clamp)
        value = -clamp;
    TFC_SetServo(0,value);
}

void stopCameraExposure()
{
}

void dataConvertionRoutine()
{
    uint8_t mask;
    
    // convertion of motor current is done at each tick
    mask = ADC_MASK_CAPTURE_MOTOR_CURRENT;
    
    // convertion of line scan is done each 5 ticks
    if((convCounter % 5) == 0)
        mask |= ADC_MASK_CAPTURE_LINE_SCAN;
    
    // convertion of pot and battery is done each 5 ticks
    if((convCounter % 5) == 2)
        mask |= ADC_MASK_CAPTURE_POT_0 | ADC_MASK_CAPTURE_POT_1 | ADC_MASK_CAPTURE_BATTERY_LEVEL;

    TFC_StartDataAcquisition(mask);
    
    convCounter++;
    if(convCounter >= 4000000000)
        convCounter = 0;
    
    //TFC_StartDataAcquisition(ADC_MASK_CAPTURE_ALL);
    //camExpoTimeout.attach(&stopCameraExposure,camExposure);
}

void updateBatteryLevel()
{
    float batteryVoltage;
    batteryVoltage = motors.getAverageBatteryVoltage();
    TFC_SetBatteryLED_Level(batteryVoltage*3.3-18.8);
}

void saveADCMeas()
{
    //TFC_BAT_LED2_TOGGLE;
    if(TFC_MotorCurrentReady)
    {
        TFC_MotorCurrentReady = 0;
        motors.saveMotorCurrentMeasure(TFC_ReadMotACurrentRaw(),TFC_ReadMotBCurrentRaw()); 
    }
    if(TFC_LineScanImageReady)
    {
        TFC_LineScanImageReady = 0; // clear counter to be able to detect next frame
        vision.saveData((uint16_t*)TFC_LineScanImage0);
    }
    if(TFC_BatteryVoltageReady)
    {
        TFC_BatteryVoltageReady = 0;
        motors.saveBatteryVoltageMeasure(TFC_ReadBatteryVoltageRaw());
    }
}

void printCarSpeed(Serial& output, Motors motors, uint32_t index)
{
    output.printf("%d %f %f\r\n",index,motors.getCarSpeed(),motors.getSpeedError());
}

void printAll(Serial& output, Motors motors, float PWM, float steering, uint32_t index)
{
    output.printf("%d %f %f %f\n",index,motors.getCarSpeed(), PWM ,steering);
}

void printEdges(Serial& output, struct lineScanData lineData)
{
    uint8_t i;
    
    output.printf("[");
    for(i=0;i<lineData.leftEdgeIndex;i++) output.printf(" ");
    output.printf("^");
    for(i=lineData.leftEdgeIndex;i<lineData.mostWhiteIndex;i++) output.printf(" ");
    output.printf("|");
    for(i=lineData.mostWhiteIndex;i<lineData.rightEdgeIndex;i++) output.printf(" ");
    output.printf("^");
    for(i=lineData.rightEdgeIndex;i<128;i++) output.printf(" ");
    output.printf("]\r\n");
}

void printLine(Serial& output)
{
    uint8_t i;
    
    for(i=0;i<128;i++)
    {
        output.printf("%d ",TFC_LineScanImage0[i]);
    }
    output.printf("\r\n");
}

bool dir = false;
void invertMot()
{
    if(dir)
        motors.setFixedPWMValue(1.0);
    else
        motors.setFixedPWMValue(-1.0);
    dir = !dir;
}

int main()
{
    uint8_t r,l;
    float motorPWM,steering,steeringFiltered;
    float pixelTarget;
    struct lineScanData lineData;
    uint32_t lastcount = 0;
    bool debugon = false;
    
    //MMA8451Q acc(PTE25, PTE24, (0x1d<<1));
    
    TFC_Init();
    
    pc.baud(115200);
    debug.baud(115200);
    
//    test.attach(&invertMot,2);
    
    // run convertion routine each 2ms
    convTicker.attach_us(&dataConvertionRoutine, 2000);
    // record data when convertion done
    TFC_ConvertionReadyCallback.attach(&saveADCMeas);
    
    batLevelTicker.attach(&updateBatteryLevel,0.2);
    
    motors.setFixedPWMMode();
    motors.setSpeedTargetValue(2.0);
    motors.setFixedPWMValue(0.45);
    
    steeringPID.setReference(0);
    steeringPID.setCoefficients(1.2,0,0);
    steeringPID.setOutputLimits(-0.6,0.6);
    
    speedPID.setReference(1.0);
    speedPID.setCoefficients(0.6,3,0);
    speedPID.setOutputLimits(-1.0,1.0);

    while(1)
    {
        if(TFC_ReadPushButton(0))
        {
            motors.stop();
            debugon = false;
        }
        
        if(TFC_ReadPushButton(1))
        {
            motors.start();
            debugon = true;
        }
        
        vision.processTasks();
        lineData = vision.getRoadData();
        r = lineData.rightEdgeIndex;
        //if(r>=115)
        //    r = 128;
        l = lineData.leftEdgeIndex;
        //if(l<=13)
        //    l = 0;
        pixelTarget = (r+l)/2.0;

        steering = getSteeringValue(pixelTarget);
        
        // previous
        //applySteeringCommand(steeringFilter(steering));
        
        
        // new
        steeringFiltered = steeringPID.processNewValue(-steering);
        applySteeringCommand(steeringFiltered);
        
        // drive proportional to steering
        motorPWM = 0.5-abs(steeringFiltered)/2.0;
        motors.setFixedPWMValue(motorPWM);
        
        // speed is regulated
        //speedPID.setReference(1.8-abs(steeringFiltered)*2.5); // set speed to 2m/s max and decrease to 0.5m/s if steering is at max
        //motorPWM = speedPID.processNewValue(motors.getCarSpeed());
        //motors.setFixedPWMValue(motorPWM);

        motors.processTasks();
        //motorPWM = TFC_ReadPot(0);
        //motorPWM = (TFC_GetDIP_Switch()*0.05+0.25);
        //motors.setFixedPWMValue(motorPWM);
        
        /*if(TFC_LineScanImageReady)
        {
            TFC_LineScanImageReady = 0; // clear counter to be able to detect next frame

            // calculation time measure
            t.reset();
            t.start();
            
            // stop calculation time measurement
            t.stop();
            
            //pc.printf("Bat: %fV, PWM:%f, MA:%frps, MB:%frps\r",motors.getAverageBatteryVoltage(),motorPWM,motors.getWheelRPS('A'),motors.getWheelRPS('B'));
            //pc.printf("Bat: %fV, PWM:%f, MA:%fV, MB:%fV\r",motors.getAverageBatteryVoltage(),motorPWM,motors.getAverageMotCurrent('A'),motors.getAverageMotCurrent('B'));
            //pc.printf("Bat: %fV, PWM:%f, MotA:%f, MotB:%f, speedA:%f, speedB:%f\r",TFC_ReadBatteryVoltage(),motorPWM,TFC_ReadMotACurrent(),TFC_ReadMotBCurrent(),getMotSpeed('A',motorPWM),getMotSpeed('B',motorPWM));
            //pc.printf("Bat: %fV, d=%f, time:%dus max light:%d @ %d    \r",TFC_ReadBatteryVoltage(),steering,t.read_us(),lineData.maxLightValue,lineData.mostWhiteIndex);
        }*/
        
        if((convCounter % 100) == 0) // each 0.2 second
        {
            //printEdges(pc);
            //printLine(pc);
            
            //pc.printf("%d %d => %f\r\n",l,r,steering);
            //pc.printf("%f %f\r",motors.getAverageMotCurrent('A'),motors.getAverageMotCurrent('B'));
        }
        
        //pc.printf("%d %f %f %f    \r",lastcount,acc.getAccX(),acc.getAccY(),acc.getAccZ());
        if(debugon && (convCounter != lastcount))
        {
            lastcount = convCounter;
            //printAll(debug, motors, motorPWM, steeringFiltered, lastcount);
            //printCarSpeed(debug, motors, lastcount);
            //pc.printf("%d %f %f %f\n",lastcount,motors.getMotPWM('A'),motors.getMotCurrent('A'),motors.getWheelSpeed('A'));
            //pc.printf("%f\r",speedPID.getIntegralTerm());
            //debug.printf("%d %f %f %f\n",lastcount,motors.getMotCurrent('A'),motors.getMotCurrent('B'),motors.getCarSpeed(),);
            //debug.printf("%d %f %f %f\n",lastcount,motors.getMotPWM('A'),motors.getMotPWM('B'),steering);
            //debug.printf("%d %f %f %f\n",lastcount,acc.getAccX(),acc.getAccY(),steering);
        }
    }
}