예제 #1
0
파일: Drive.c 프로젝트: SamChenzx/sdp
int main(){
    //Initializations
    Board_init();
    Serial_init();
    Timer_init();
    Drive_init();
    ENABLE_OUT_TRIS = OUTPUT;  
    ENABLE_OUT_LAT = MICRO;

#ifdef RECIEVE_CONTROL
    ENABLE_OUT_LAT = RECIEVER;
    while(1){
        asm("nop");
    }
#endif

    printf("State machine test harness.\n\n");

    // Test forward state
    printf("Forward state. Driving at 5, 10, 20, 40, 60, 80, 100, 125 \%.\n");
    uint8_t speed[] = {5, 10, 20, 40, 60, 80, 100, 125};
    int i, len = sizeof(speed);
    delayMillisecond(STATE_DELAY);
    for (i = 0; i < len; i++) {
        Drive_forward(speed[i]);
        delayMillisecond(STATE_DELAY);
    }
    Drive_stop();
    delayMillisecond(STATE_DELAY);

    setRudder(STOP_PULSE);
    delayMillisecond(STATE_DELAY);


    // Forward with heading
    printf("Track state. Driving at 5, 10, 25, 50, 100 \% at 0 deg north.\n");
    uint8_t speed2[] = {5, 10, 25, 50, 100};
    len = sizeof(speed2);
    delayMillisecond(STATE_DELAY);
    for (i = 0; i < len; i++) {
        Drive_forwardHeading(speed2[i], 0);
        delayMillisecond(STATE_DELAY);
    }
    Drive_stop();

    printf("Finished state machine test.\n\n");


    return SUCCESS;
}
예제 #2
0
파일: Drive.c 프로젝트: SamChenzx/sdp
int main(){
    //Initializations
    Board_init();
    Serial_init();
    Timer_init();
    Drive_init();
    ENABLE_OUT_TRIS = OUTPUT;  
    ENABLE_OUT_LAT = MICRO;

#ifdef RECIEVE_CONTROL
    ENABLE_OUT_LAT = RECIEVER;
    while(1){
        ;
    }
#endif

    printf("Actuator Test Harness Initiated\n\n");

    //Test Rudder
    printf("Centering rudder.\n");
    setRudder(RUDDER_TURN_LEFT, 0);
    delayMillisecond(ACTUATOR_DELAY);

    printf("Turning rudder left.\n");
    setRudder(RUDDER_TURN_LEFT, 100); //push to one direction
    delayMillisecond(ACTUATOR_DELAY);
    printf("Centering rudder.\n");
    setRudder(RUDDER_TURN_LEFT, 0);
    delayMillisecond(ACTUATOR_DELAY);

    printf("Turning rudder right.\n");
    setRudder(RUDDER_TURN_RIGHT, 100);
    delayMillisecond(ACTUATOR_DELAY);
    
    printf("Centering rudder.\n");
    setRudder(RUDDER_TURN_LEFT, 0);
    

    //Test Motor Left
    printf("Testing left motor.\n");
    setLeftMotor(0);
    delayMillisecond(ACTUATOR_DELAY);
    printf("Driving left motor forward.\n");
    setLeftMotor(100);
    delayMillisecond(ACTUATOR_DELAY);
    setLeftMotor(0);
    delayMillisecond(ACTUATOR_DELAY);
    //printf("Driving left motor reverse.\n");
    //setLeftMotor(MIN_PULSE);
    //delayMillisecond(ACTUATOR_DELAY);
    //setLeftMotor(0);
   

    //Test Motor Right
    printf("Testing right motor.\n");
    setRightMotor(0);
    delayMillisecond(ACTUATOR_DELAY);
    printf("Driving right motor forward.\n");
    setRightMotor(100);
    delayMillisecond(ACTUATOR_DELAY);
    setRightMotor(0);
    delayMillisecond(ACTUATOR_DELAY);
    //printf("Driving right motor reverse.\n");
    //setRightMotor(MIN_PULSE);
    //delayMillisecond(ACTUATOR_DELAY);
    //setRightMotor(STOP_PULSE);
    //delayMillisecond(ACTUATOR_DELAY);

//    // Remove this code
//    setRightMotor(MAX_PULSE);
//    setLeftMotor(MAX_PULSE);
//    while (1)
//        asm("nop");
//
//
//    printf("\nDone with drive test.\n");
    return SUCCESS;
}
예제 #3
0
파일: Drive.c 프로젝트: SamChenzx/sdp
/**********************************************************************
 * Function: updateHeading
 * @return None
 * @remark Determines the heading error using the tilt-compensated compass,
 *  and adjusts the rudder accordingly. Also, a bang-bang control has been
 *  implemented to turn the rudder to the maximum value if the boat's motors
 *  are being driven below some percentage defined above.
 * @author Darrel Deo
 * @author David Goodman
 * @date 2013.03.27 
 **********************************************************************/
static void updateRudder() {

    static int16_t lastThetaError; // used for derivative term
    
    rudderDirection = RUDDER_TURN_LEFT;
    
    // Get current heading, determine theta error
    uint16_t currentHeading = (uint16_t)TiltCompass_getHeading();
    int16_t thetaError = desiredHeading - currentHeading;
    
    // Bound theta error and determine turn direction
    if (thetaError > 0) {
        rudderDirection = (thetaError < 180)? RUDDER_TURN_RIGHT : RUDDER_TURN_LEFT;
        thetaError = (thetaError < 180)? thetaError : (360 - thetaError);
    }
    else {
        // theta error is negative
        rudderDirection = (thetaError > -180)? RUDDER_TURN_LEFT : RUDDER_TURN_RIGHT;
        thetaError = (thetaError > -180)? -thetaError : (360 + thetaError);
    }
    
    // Initialize or dump derivative if changed directions
    if (lastRudderDirection == RUDDER_TURN_NONE || rudderDirection != lastRudderDirection)
        lastThetaError = 0;
        
    /*    Controller Terms    */
    // Derivative (scaled by KD_RUDDER)
    float thetaErrorDerivative = (float)abs(thetaError - 
        lastThetaError)/MS_TO_SEC(TRACK_UPDATE_DELAY);
    
    // Proportional (scaled by KP_RUDDER), convert degrees to percent
    float uDegrees = KP_RUDDER*(float)thetaError + KD_RUDDER*thetaErrorDerivative;
    float uPercent = (uDegrees / RUDDER_ANGLE_MAX ) * 100;
    
    // Limit percentage from 0 to 100
    uPercent = (uPercent > 100.0)? 100.0f : uPercent;
    uPercent = (uPercent < 0.0)? 0.0f : uPercent;

    char *bangbang = "";
    // Bang-bang control to force rudder all the way if speed is low
    if (desiredSpeed < RUDDER_BANGBANG_SPEED_THRESHOLD
            && thetaError > RUDDER_BANGBANG_THETA_DEADBAND_THRESHOLD) {
        uPercent = 100.0f;
        bangbang = " BB";
    }
    
    // Command the rudder and save 
    setRudder(rudderDirection, (uint8_t)uPercent);
    lastThetaError = thetaError;
    lastRudderDirection = rudderDirection;
    char *dir;
    dir = (rudderDirection == RUDDER_TURN_RIGHT)? "R" : "L";
        
    #ifdef DEBUG_VERBOSE
    DBPRINT("Rudder control: rDegrees=%d, yDegrees=%d, eDegrees=%d, uDegrees=%.2f, uPercent=%d[%s]\n\n",
        desiredHeading, currentHeading, thetaError, uDegrees, (uint8_t)uPercent, dir);
    #endif

    #ifdef USE_PUBLIC_DEBUG
    sprintf(debugString, "R=%d, Y=%d, e=%d, U=%.2f, Up=%d[%s]%s, S=%d\n",
        desiredHeading, currentHeading, thetaError, uDegrees, (uint8_t)uPercent, dir, bangbang, desiredSpeed);
    #endif
}
예제 #4
0
CX10::CX10() {
    randomSeed((analogRead(A0) & 0x1F) | (analogRead(A1) << 5));
    for (int n = 0; n < CRAFT; ++n) {
        Craft *c = &craft_[n];
        c->nextPacket = 0;
        memset(c->aid, 0xff, sizeof c->aid);
        memset(c->Servo_data, 0, sizeof c->Servo_data);
        setThrottle(n, 0);
        setAileron(n, 500);
        setElevator(n, 500);
        setRudder(n, 500);
        for(uint8_t i=0;i<4;i++) {
#ifdef RFDUINO
            c->txid[i] = random(256);
#else
            c->txid[i] = random();
#endif
        }
        c->txid[1] %= 0x30;
        c->freq[0] = (c->txid[0] & 0x0F) + 0x03;
        c->freq[1] = (c->txid[0] >> 4) + 0x16;
        c->freq[2] = (c->txid[1] & 0x0F) + 0x2D;
        c->freq[3] = (c->txid[1] >> 4) + 0x40;
    }
    pinMode(ledPin, OUTPUT);
    //RF module pins
    pinMode(MOSI_pin, OUTPUT);
    pinMode(SCK_pin, OUTPUT);
    pinMode(MISO_pin, INPUT);
    pinMode(CS_pin, OUTPUT);
    pinMode(CE_pin, OUTPUT);
    digitalWrite(ledPin, LOW);//start LED off
    CS_on;//start CS high
    CE_on;//start CE high
    MOSI_on;//start MOSI high
    SCK_on;//start sck high
    delay(70);//wait 70ms
    CS_off;//start CS low
    CE_off;//start CE low
    MOSI_off;//start MOSI low
    SCK_off;//start sck low
    delay(100);
    CS_on;//start CS high
    delay(10);
#ifdef RFDUINO
    SPI.begin();
    SPI.setFrequency(250);
#endif
    //############ INIT1 ##############
    CS_off;
    _spi_write(0x3f); // Set Baseband parameters (debug registers) - BB_CAL
    _spi_write(0x4c);
    _spi_write(0x84);
    _spi_write(0x67);
    _spi_write(0x9c);
    _spi_write(0x20);
    CS_on;
    delayMicroseconds(5);
    CS_off;
    _spi_write(0x3e); // Set RF parameters (debug registers) - RF_CAL
    _spi_write(0xc9);
    _spi_write(0x9a);
    _spi_write(0xb0);
    _spi_write(0x61);
    _spi_write(0xbb);
    _spi_write(0xab);
    _spi_write(0x9c);
    CS_on;
    delayMicroseconds(5);
    CS_off;
    _spi_write(0x39); // Set Demodulator parameters (debug registers) - DEMOD_CAL
    _spi_write(0x0b);
    _spi_write(0xdf);
    _spi_write(0xc4);
    _spi_write(0xa7);
    _spi_write(0x03);
    CS_on;
    delayMicroseconds(5);
    CS_off;
    _spi_write(0x30); // Set TX address 0xCCCCCCCC
    _spi_write(0xcc);
    _spi_write(0xcc);
    _spi_write(0xcc);
    _spi_write(0xcc);
    _spi_write(0xcc);
    CS_on;
    delayMicroseconds(5);
    CS_off;
    _spi_write(0x2a); // Set RX pipe 0 address 0xCCCCCCCC
    _spi_write(0xcc);
    _spi_write(0xcc);
    _spi_write(0xcc);
    _spi_write(0xcc);
    _spi_write(0xcc);
    CS_on;
    delayMicroseconds(5);
    _spi_write_address(0xe1, 0x00); // Clear TX buffer
    _spi_write_address(0xe2, 0x00); // Clear RX buffer
    _spi_write_address(0x27, 0x70); // Clear interrupts
    _spi_write_address(0x21, 0x00); // No auto-acknowledge
    _spi_write_address(0x22, 0x01); // Enable only data pipe 0
    _spi_write_address(0x23, 0x03); // Set 5 byte rx/tx address field width
    _spi_write_address(0x25, 0x02); // Set channel frequency
    _spi_write_address(0x24, 0x00); // No auto-retransmit
    _spi_write_address(0x31, PACKET_LENGTH); // 19-byte payload
    _spi_write_address(0x26, 0x07); // 1 Mbps air data rate, 5dbm RF power
    _spi_write_address(0x50, 0x73); // Activate extra feature register
    _spi_write_address(0x3c, 0x00); // Disable dynamic payload length
    _spi_write_address(0x3d, 0x00); // Extra features all off
    MOSI_off;
    delay(100);//100ms delay

    //############ INIT2 ##############
    healthy_ = _spi_read_address(0x10) == 0xCC;
    
    _spi_write_address(0x20, 0x0e); // Power on, TX mode, 2 byte CRC
    MOSI_off;
    delay(100);
    bindAllowed_ = true;
    nextBind_ = micros();
    nextSlot_ = 0;
}