fsdfds

Dependencies:   mbed

main.cpp

Committer:
teamat
Date:
2020-05-24
Revision:
13:205002e3c176
Parent:
12:ee175985ef09
Child:
14:353e92037bc8

File content as of revision 13:205002e3c176:

#include "mbed.h"

#define M_PI 3.14159265358979323846f
#define smoothingNumber 6


#define STATE_ERROR 0
#define STATE_INIT 1
#define STATE_GOTO_START 2
#define STATE_GOTO_END_COUNTING 3
#define STATE_GOTO_MIDDLE 4
#define STATE_WAITING 5
#define STATE_GOTO_SWING 6
#define STATE_START_SWING 7
#define STATE_SWING_RIGHT 8
#define STATE_SWING_LEFT 9
#define STATE_EMPTY_SWING 10

#define DIR_LEFT 0
#define DIR_RIGHT 1

#define timer_period_us 10


DigitalOut RCout(D10);
DigitalOut dir(D9);
InterruptIn leftSwitch(D2);
InterruptIn rightSwitch(D3);
Ticker tick;
Ticker speedTicker;
Ticker swingTicker;
RawSerial rpc(D1,D0,9600);
DigitalOut led(D4);

int period_us = 1;//300 26
int posCounter = 0;
int timerCounter = 0;

long pos=0;

long railLength = 0;

uint8_t state=STATE_INIT;
uint8_t data[2] = {0, 0};
uint8_t cmdIndex = 0;

Timer t;
SPI spi(D11,D12,D13);// mosi, miso, sclk
DigitalOut cs(D5);

float radius = 0.0025;

float angularPosNew = 0;
float angularPosOld = 0;

float timeOld = 0.0f;
float timeStart = 0.0f;

float dx = 0;
float xPosNew = 0;
float xPosOld = 0;
float speed = -1;
float posOffset = 0.0f;
float posMap[4] = {0.0f, 0.0f, 0.0f, 0.0f}; 

double dAngle = 0.0f;
double anSpd = 0.0f;

float timeOldPos = 0.0f;
float timeStartPos = 0.0f;

float angle=0.0f;
float angleOffset = 0;

float control = 0.0f;

double PIPI = 6.28;

bool canSend = false;
bool periodUpdated = false;
bool calibrated = false;
bool dirUpdated = false;

typedef union {
    float number[6];
    uint8_t numberCh[24];
} my_union;

my_union myUnion;

bool isPendulumSwinging() {
    return  state == STATE_SWING_RIGHT || state == STATE_SWING_LEFT;
}

float getPosMM() {
    //return (pos-railLength/2) * 550.0f/railLength;
    //return (pos - railLength / 2) * (350.0f / railLength);
    return pos / 3500.0f;
}

uint16_t getPendulumPos(){
    cs=0;
    wait_ms(1);
    uint16_t d=spi.write((short)0x00);
    d=d<<1;//fucking shithole fakebit
    d=d>>6;//no need debug info
    cs=1;
    wait_ms(1);
    return (uint16_t)d;
}


float getPendulumAngle(){
    angle = getPendulumPos();
    angle = angle * 6.28f / 1024.0f;
    angle += angleOffset;
    if (angle > 3.14) {
        angle = angle - PIPI;    
    }
    /*if (angle > PIPI + 0.01) {
        angle = fmod((angle + 3.14), PIPI) - 3.14;
        if (angle < -3.14) {
            angle += PIPI;
        }
    }*/
    /*if (calibrated) {
        float test = fmodf(angle, M_PI);
        if (test >= 1) {
            angle = -test;    
        } else {
            angle = test;
        }
    }*/
    return angle;
}


/*
 ANGULAR SPEED CALC
*/

void getDeltaAng(){

    angularPosNew = getPendulumAngle();

    dAngle = fmod((angularPosNew - angularPosOld + 3.14), PIPI) - 3.14;
    if (dAngle < -3.14) {
        dAngle += PIPI;
    }

    angularPosOld = angularPosNew;

}

void getAngularSpeed(){
    float deltaTime;

    timeStart = float(t.read());
    deltaTime = (timeStart - timeOld);
    getDeltaAng();
    anSpd = dAngle / deltaTime;
    timeOld=timeStart;
    //взятие по модулю, спросить
}

/*
    SPEED CALC
*/


void calcSpeed() {
    /*posMap[posCounter] = getPosMM() / 1000;
    if (posCounter == 3) {
        posCounter = 0;
        float pathSum = 0;
        for (int i = 0; i < 3; i++) {
            float pathDiff = posMap[i + 1] - posMap[i]; 
            if ((pathDiff) < 0) {
                pathSum += -pathDiff;
            } else {
                pathSum += pathDiff;
            }
        }
        speed = pathSum;  
    } else {
        posCounter += 1;
    }*/
    
    xPosNew = (getPosMM() - posOffset) / 1000;
    speed = xPosNew - xPosOld;
    if (dir == DIR_LEFT) {
        speed = -speed;
    }
    xPosOld = xPosNew;
}

void calcControl() {
    //float frequency = 1000000 / (period_us / 2);
    //float rates = frequency / 6400;
    //control = rates * PIPI * radius;
    if (dir = DIR_RIGHT) {
        control = -period_us;
    } else {
        control = period_us;
    }
}



void stepperFlip() {
    if (timerCounter * timer_period_us > period_us) {
        timerCounter = 0;
        if (state != STATE_WAITING && state != STATE_ERROR && state != STATE_INIT && state){
            RCout = !RCout;
            pos += (dir.read() * 2 - 1);
        }
        if (state == STATE_GOTO_MIDDLE && pos == railLength / 2) {
            posOffset = 40;
            state = STATE_WAITING;
        }
        if (state == STATE_SWING_LEFT && state==STATE_SWING_RIGHT) {
            pos += (dir.read() * 2 - 1);
            RCout = !RCout;
        }
    } else {
        timerCounter += 1;
    }
}


/*void updatePeriod(){
    tick.detach();
    tick.attach_us (&stepperFlip, period_us / 2.0f);
    wait_ms(20);
}*/

void leftEnd() {
    dir = DIR_RIGHT;
    if (state == STATE_GOTO_START) {
        state = STATE_GOTO_END_COUNTING;
        pos = 0;
    }
    else if (isPendulumSwinging()) {
        //state = STATE_GOTO_MIDDLE;
        //angleOffset -= 0.006191;
        state = STATE_ERROR;
    }
    /*if (state == STATE_GOTO_SWING) {
        state = STATE_ERROR;
    }*/
}

void rightEnd() {
    dir=DIR_LEFT;
    if (state == STATE_GOTO_END_COUNTING) {
        railLength=pos;
        state = STATE_GOTO_MIDDLE;
    }
    else if (isPendulumSwinging()) {
        //state = STATE_GOTO_MIDDLE;
        //angleOffset += 0.006191;
        state = STATE_ERROR;
    }
    /*if (state == STATE_GOTO_SWING) {
        state = STATE_ERROR;
    }*/
}


void sendData() {
    myUnion.number[0] = t.read();
    myUnion.number[1] = (getPosMM()- posOffset) / 1000 ;
    myUnion.number[2] = speed;
    //myUnion.number[3] = dAngle;
    myUnion.number[3] = angle;
    myUnion.number[4] = anSpd;
    myUnion.number[5] = control;
    for(int i = 0; i < 24; i++) {
        rpc.putc(myUnion.numberCh[i]);
    }
}


void changeDir() {
    if (dir == DIR_LEFT) {
        dir = DIR_RIGHT;    
    } else {
        dir = DIR_LEFT;
    }    
}

int command[2] = {0, 0};
bool newData = false;

void Rx_interrupt() {
    data[cmdIndex] = rpc.getc();
    if (cmdIndex == 1) {
        newData = true;
    }
    cmdIndex = !cmdIndex;
}

void proceedCommands() {
    newData = false;
    switch (data[0]) {
        case 50:
            canSend = true;
            break;
        case 60:
            led = !led;
            state = STATE_GOTO_SWING;
            break;
        case 65:
            led = !led;
            if (data[1] == 1) {
                dir = DIR_RIGHT;
            } else if (data[1] == 10) {
                dir = DIR_LEFT;
            }
            break;
        case 70:
            period_us = data[1];
            calcControl();
            break;
        default:
            break;    
    }
}


int main() {
    RCout = 1;
    wait_ms(500);
    spi.format(16,2);
    spi.frequency(1000000);
    t.start();
    leftSwitch.rise(&leftEnd);
    rightSwitch.rise(&rightEnd);
    rpc.attach(&Rx_interrupt, Serial::RxIrq);
    for (int i=5; i>0; i--) {
        getPendulumAngle();
        wait_ms(500);
    }
    angleOffset= 3.14 - angle;
    calibrated = true;
    led = !led;
    //wait(12);
    //wait(3);
    //updatePeriod();
    calcControl();
    tick.attach_us(stepperFlip, timer_period_us);
    state=STATE_GOTO_START;
    dir=DIR_LEFT;
    //swingTicker.attach(changeDir, 1.5);
    while(1) {
        getAngularSpeed();
        if (canSend) {
            sendData();
        }
        if (newData) {
            proceedCommands();    
        }
        /*if (periodUpdated) {
            calcControl();
            updatePeriod();
            periodUpdated = false;
        }*/
        switch(state) {
            case STATE_WAITING:
                //state = STATE_GOTO_SWING;
                break;
            case STATE_GOTO_START:
                break;
            case STATE_GOTO_END_COUNTING:
                break;
            case STATE_GOTO_SWING:
                speedTicker.attach(calcSpeed, 1);
                //swingTicker.attach(getSwingDirectory, 1);
                state = STATE_SWING_LEFT;
                break;
            case STATE_SWING_LEFT:
                /*if (swingCounter == 6) {
                    swingCounter = 0;
                    period_us += 4;
                    periodUpdated = true;
                }*/
                break;
            case STATE_SWING_RIGHT:
                /*if (swingCounter == 6) {
                    swingCounter = 0;
                    period_us += 4;
                    periodUpdated = true;
                }*/
                break;
            default:
                break;
        }
    }
}