Racelogic / Mbed 2 deprecated VIPS_LTC_RAW_IMU

Dependencies:   BufferedSerial FatFileSystemCpp mbed

main.cpp

Committer:
AndyA
Date:
2021-02-19
Revision:
10:053bac3e326b
Parent:
9:7214e3c3e5f8
Child:
11:ef7f6591b776

File content as of revision 10:053bac3e326b:

#include "mbed.h"
#include "MSCFileSystem.h"


#include "LTCApp.h"

  MSCFileSystem msc("msc"); 
//USBHostMSD msd("msc");

const int framesToCount = 300;
const int MaxTimeErrorUS = 150;
const int timerOverheadTime = 19;

BufferedSerial pc(USBTX, USBRX);
VIPSSerial VIPS(p28, p27);
BufferedSerial COM1(p13, p14);
FIZReader FIZPort(p9, p10);

DigitalOut logLED(LED1);
//DigitalOut PPS(p12);

DigitalOut led2(LED2);
DigitalOut led3(LED3);

DigitalOut frameToggle(LED4);
DigitalOut second(p23);

LTCDecode LTCInput(p7);
InterruptIn PPFin(p29);
InterruptIn Syncin(p8);

DigitalIn logButton(p21);

frameclock movieTime;

// clock to time everything with
Timer inputTimer;

float logButtonDownTime;
float logButtonUpTime;
int logButtonLastState;

bool logging = false;
FILE *logFile = NULL;


// Time since last frame event, used for position output interpolation
Timer TimeSinceLastFrame;
uint32_t TimeSinceLastFrameWrap;

// used to start PPS at the correct point
Timeout PPSsyncTimer;

// used to generate PPS edges
Ticker PPSOutputTimer;

frameRates detectedRate;
bool ppsRunning = false; // set when PPS start has been scheduled
volatile bool ppsActive = false;  // set when PPS is actuallt going (up to 1 second later)

volatile bool PPSHigh;
bool resync = false;
bool resyncDone = false;
uint32_t resyncPeriod;
bool OKToCheckSync = false;
volatile uint32_t VBOXTicks = 0; // time at the NEXT PPS edge
uint32_t lastPPSSecondStart;

#define _longPPMTrackLen_ 20
float PPMErrors[_longPPMTrackLen_];
float PPMTrackTotal;
int PPMTrackIndex;
float PPMHighAcc;
float remainingClockError;
bool ppmCorrection;


struct outputFormat_s {
    uint32_t header; // 2 byte header + 2 byte length
    uint32_t mask;
    uint32_t time;
    double x;
    double y;
    float z;
    uint8_t beacons;
    uint8_t solutionType;
    uint16_t kfStatus;
    float roll;
    float pitch;
    float yaw;
    uint8_t accuracy[4];
    uint32_t focus;
    uint16_t iris;
    uint16_t zoom;
    uint16_t checksum;
} __attribute__((packed)) ;

struct outputFormat_s packetOut;

void prepPacketOut()
{
    uint8_t bytes[4];
    bytes[0]=0x24;
    bytes[1]=0xd9;
    *(uint16_t*)(bytes+2) = sizeof(struct outputFormat_s);
    packetOut.header = *(uint32_t*)bytes;
    packetOut.mask = 0x0446;
    packetOut.accuracy[0] = 0;
    packetOut.accuracy[1] = 0;
    packetOut.accuracy[2] = 0;
    packetOut.accuracy[3] = 0;
}

void sendPosition(position *posPtr)
{
    if (posPtr) {
        packetOut.x = posPtr->X;
        packetOut.y = posPtr->Y;
        packetOut.z = posPtr->Height;
        packetOut.beacons = posPtr->beacons;
        packetOut.solutionType = posPtr->solutionType;
        packetOut.kfStatus = posPtr->KFStatus;
        packetOut.roll = posPtr->roll;
        packetOut.pitch = posPtr->pitch;
        packetOut.yaw = posPtr->yaw;
        packetOut.accuracy[3] = posPtr->ID;
    } else {
        packetOut.x = 0;
        packetOut.y = 0;
        packetOut.z = 0;
        packetOut.roll = 0;
        packetOut.pitch = 0;
        packetOut.yaw = 0;
        packetOut.accuracy[3] = 0;
        packetOut.beacons = 0;
        packetOut.solutionType = 0;
        packetOut.kfStatus = 0;
    }
    packetOut.time = movieTime.getTimeMS();
    FIZPort.getMostRecent(&packetOut.focus, &packetOut.iris, &packetOut.zoom);
    VIPSSerial::getCRC((void *)&packetOut, sizeof(struct outputFormat_s)-2, (void *)&packetOut.checksum);
    COM1.write(&packetOut, sizeof(struct outputFormat_s));
    if (logging) {
        if (!fwrite(&packetOut, sizeof(struct outputFormat_s), 1, logFile)) { // write failed
            logLED = 0;
            logging = false;
            fclose(logFile);
            logFile = NULL;
        }
    }
}


//called once per frame to output the current postition
void framePositionOutput()
{
    uint32_t outputTime = TimeSinceLastFrame.read_us();
    TimeSinceLastFrame.reset();
    sendPosition(VIPS.sendPositionForTime(outputTime));
    FIZPort.requestCurrent();
}

int getNextFileNumber()
{
    static unsigned int fileNbr = 0;
    char fileName[32];
    FILE *filePtr = NULL;
    do {
        if (filePtr != NULL)
            fclose(filePtr);
        sprintf(fileName,"/msc/VIPS%04u.bin",fileNbr++);
        filePtr = fopen(fileName,"rb");
    } while (filePtr != NULL);
    return fileNbr-1;
}

FILE *nextBinaryFile(void)
{
    char fileName[32];
    int file = getNextFileNumber();
    sprintf(fileName,"/msc/VIPS%04u.bin",file);
    return fopen(fileName,"wb");
}


volatile bool NewFramePulse= false;
uint32_t FramePulseTime;
volatile int framesIn = 0;
void OnPPFInputStartup(void)
{
    framesIn++;
}

volatile int SyncInCount = 0;
void OnSyncInputStartup(void)
{
    SyncInCount++;
}


void OnPPFInput(void)
{
    movieTime.nextFrame();
    FramePulseTime = inputTimer.read_us();
    NewFramePulse = true;
}


int main()
{
    pc.baud(115200);
    COM1.baud(115200);
    inputTimer.reset();
    inputTimer.start();

    pc.printf("Startup\r\n");
    logLED = 0;

    prepPacketOut();

    LTCInput.enable(true);

    VIPS.run();

    pc.printf("Startup\r\n");

    TimeSinceLastFrame.reset();
    TimeSinceLastFrame.start();

    pc.printf("Waiting for sync input clock\r\n");
    PPFin.rise(callback(&OnPPFInputStartup));
    Syncin.rise(callback(&OnSyncInputStartup));
    framesIn = 0;
    SyncInCount = 0;
    bool LockToSync = false;

    while (true) {
        if (SyncInCount == 100) {
            LockToSync= true;
            break;
        }
        if ((framesIn == 100) && (SyncInCount<45)) { // prefer frame sync 
            break;
        }
    }

    if (LockToSync) {
        pc.printf("Using Genlock sync input\r\n");
        Syncin.rise(callback(&OnPPFInputStartup));
        PPFin.rise(NULL);
    } else {
        pc.printf("Using pulse per frame input\r\n");
        Syncin.rise(NULL);
    }

    pc.printf("Measuring frame rate\r\n");

    int currentFrames = framesIn;
    while (framesIn == currentFrames);  // wait for next frame;
    inputTimer.reset();
    framesIn = 0;


    while (framesIn < 100);  // wait for 100 frames;
    uint32_t frameTime = inputTimer.read_us()/100;

    int framesPerSecond = frameRates::getClosestRate(frameTime);

    pc.printf("Detected frame rate %d\r\n",framesPerSecond);

    if (LTCInput.synced()) { // getting LTC so set the clock.
        currentFrames = framesIn;
        while (framesIn == currentFrames);  // wait for next frame;
        wait_us (frameTime/4); // ensure the LTC decode for the last frame is done.
        int hour,minute,second,frame;
        bool drop = LTCInput.isFrameDrop();
        LTCInput.getTime(&hour,&minute,&second,&frame);
        movieTime.setMode(framesPerSecond,drop);
        movieTime.setTime(hour,minute,second,frame);  
    } else { // no time code so clock time doesn't matter
        movieTime.setMode(framesPerSecond,false);
    }

    if (LockToSync)
        Syncin.rise(callback(&OnPPFInput));
    else
        PPFin.rise(callback(&OnPPFInput));

    pc.printf("Current time is %02d:%02d:%02d %02d\r\n",movieTime.hours(),movieTime.minutes(),movieTime.seconds(),movieTime.frame());
    LTCInput.enable(false);

    pc.printf("Running\r\n",framesPerSecond);

    getNextFileNumber();

    while (true) {
        if (NewFramePulse) { // New frame. Output data.
            //framePulse(FramePulseTime);
            framePositionOutput();
            NewFramePulse = false;
        }

        if (logButtonLastState != logButton) {
            if (logButton) { // pressed
                logButtonDownTime = inputTimer.read();
                if (logging) {
                    logLED = 0;
                    logging=false;
                    fclose(logFile);
                } else {
                    logFile = nextBinaryFile();
                    if(logFile) {
                        logLED = 1;
                        logging = true;
                    }
                }
            } else { // released
                logButtonUpTime = inputTimer.read();
            }
            logButtonLastState = logButton;
        }
    }
}