示例#1
0
void Robot::setBrakesToCurrentRobotState()
{
	// This method is private, so it does not need a mutex-lock. The callers should have taken care of that.

	if(currentRobotStatus == idle || currentRobotStatus == stalled)
	{
		// The robot is NOT moving, apply the brakes.
		setBrakes(true);
	}
	else if(currentRobotStatus == moving)
	{
		// The robot IS moving, release the brakes.
		setBrakes(false);
	}
	else if(currentRobotStatus == aborting || currentRobotStatus == movementSetup)
	{
		// If we're entering one of these states, we need not change the brake-status. Why?
		// For Abortion:
		// - if we WERE moving before, we're now slowing down, so we still need the brakes loose.
		//
		// - if we were NOT moving, we're not going to start moving in the aborting state, so we
		//   can leave the brakes applied.
		// For movementSetup, we only go there from an idle state, so the brakes are applied already.
		logger->Robot("Robot::setBrakesToCurrentRobotState(): NOT changing brake-status, as we've entered aborting or movementSetup-state.");
	}
}
示例#2
0
文件: main.c 项目: billyfung/MSP430
__interrupt void interrupt1() {

	if (P1IFG & I1_LEFT_BUTTON) {
		switch (turnState) {
		case NO_TURN:
			leftTurn();
			autoCancelState = AUTO_CANCEL_DISABLED;
			break;
		case LEFT_TURN:
			cancelTurn();
			break;
		case RIGHT_TURN:
			cancelTurn();
			break;
		}

		P1IFG &= ~I1_LEFT_BUTTON;				// Clear interrupt flag
	}


	if (P1IFG & I1_LEFT_BRAKE || P1IFG & I1_RIGHT_BRAKE) {
		switch (brakeState) {
		case NO_BRAKES:
			setBrakes();
			break;
		}

		P1IFG &= ~(I1_LEFT_BRAKE + I1_RIGHT_BRAKE);				// Clear interrupt flag
	}


	LPM4_EXIT;
}
示例#3
0
//magnitude of brake level reading
void __attribute__((__interrupt__, no_auto_psv)) _IC3Interrupt(void)
{
	if(magnitude)
	{
		in2 = IC3BUF;
		IC3CON2bits.TRIGSTAT = 0;
		IC3CON2bits.TRIGSTAT = 1;
	}	
	else if(!magnitude)
	{
		in2 = IC3BUF;
		IC3CON2bits.TRIGSTAT = 0;
		IC3CON2bits.TRIGSTAT = 1;
		if(in2 > 22000)
		{
			brakeMag = 0;
		}
		else if(in2 > 20850)
		{
			brakeMag = 100;
		}
		else if((in2 < 14700) && (in2 > 0))
		{
			brakeMag = 0;
		}
		else
		{
			brakeMag = 4 * (unsigned long)in2 / 249 - 235;
		}
		setBrakes();				
	}
	_IC3IF = 0;
}	
示例#4
0
//steering input
//MIGHT need to change when left and right go to max settings - right now left hits max way sooner than the right side
void __attribute__((__interrupt__, no_auto_psv)) _IC1Interrupt(void)
{
	if(steer)
	{
		in1 = IC1BUF;
		IC1CON2bits.TRIGSTAT = 0;
		IC1CON2bits.TRIGSTAT = 1;
	}	
	else if(!steer)
	{
		in1 = IC1BUF;
		IC1CON2bits.TRIGSTAT = 0;
		IC1CON2bits.TRIGSTAT = 1;
		if((in1 > 33360) && (in1 < 50000)) //go full left
		{
			left = 100;
			right = 0;
			LED3 = 0;
		}
		else if((in1 < 27280) && (in1 > 0)) //go full right
		{
			right = 100;
			left = 0;
			LED3 = 0;
		}
		else if((in1 > 30387) && (in1 < 30487)) //go straight
		{
			right = 100;
			left = 100;
			LED3 = 0;
		}
		else
		{	
			brakeSteer = (20 * (unsigned long)in1 / 1217) - 448;
			LED3 = 1;
			if((brakeSteer > 0) && (brakeSteer < 50))
			{
				left = brakeSteer * 2;
				right = 100;
			}
			else if((brakeSteer > 50) && (brakeSteer < 100))
			{
				left = 100;
				right = 2 * (100 - brakeSteer);
			}
		}
		setBrakes();	
	}
	_IC1IF = 0;
}
示例#5
0
文件: main.c 项目: billyfung/MSP430
int main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer

    // Clock Settings -----------------
    BCSCTL1 = XT2OFF;													// Disable XT2
    BCSCTL2 = SELM1 + SELM0 + DIVM1 + DIVM0 + SELS + DIVS1 + DIVS0; 	// Set all clocks to use VLOCLK / 8
    BCSCTL3 = LFXT1S1;

    P1SEL = 0X00;
    P2SEL = 0X00;

    // Port Settings ------------------------
	P1DIR = O1_LEFT_LIGHT + O1_BRAKE_LIGHT + O1_DEBUG_LIGHT;			// Set outputs
	P1REN = I1_LEFT_BRAKE + I1_RIGHT_BRAKE + I1_LEFT_BUTTON;			// Enable pull up resistors
	P1OUT = I1_LEFT_BRAKE + I1_RIGHT_BRAKE + I1_LEFT_BUTTON;			// Set pull up resistors
	P1OUT &= ~(O1_LEFT_LIGHT + O1_BRAKE_LIGHT); 						// Turn off lights
	P1IE = I1_LEFT_BUTTON + I1_LEFT_BRAKE + I1_RIGHT_BRAKE;				// Set interrupt sources
	P1IES &= ~(I1_LEFT_BUTTON + I1_LEFT_BRAKE + I1_RIGHT_BRAKE);		// Interrupt on rising edge

	P2DIR = O2_RIGHT_LIGHT;												// Set outputs
	P2REN = I2_RIGHT_BUTTON;											// Enable pull up resistors
	P2OUT = I2_RIGHT_BUTTON;											// Enable pull up resistors
	P2OUT &= ~(O2_RIGHT_LIGHT);											// Turn off lights
	P2IE = I2_RIGHT_BUTTON;												// Set interrupt sources
	P2IES &= ~(I2_RIGHT_BUTTON); 										// Interrupt on rising edge.

	// Timer A settings
	TACCR0 = 600;
	TACCR1 = 300;
	TACTL = TASSEL1;						// Use SMCLK
	TACCTL1 = OUTMOD2 + OUTMOD1 + OUTMOD0 + CCIE;	// Reset/Set mode, enable interrupts


	// ADC settings
	ADC10CTL0 &= ~(ENC);		// Disable ADC before setting up
	// 8 cycle sample/hold, use 2.5V internal reference, use slower sampling rate, reference burst (power save)
	ADC10CTL0 = SREF0 + ADC10SHT0 + ADC10SR + REFBURST + REF2_5V + REFON + ADC10ON;// + ADC10IE;
	ADC10CTL1 = ADC10SSEL1 + ADC10SSEL0;		// Run off SMCLK
	ADC10AE0 = I1_COMPASS_A + I1_COMPASS_B;


	turnState = NO_TURN;
	brakeState = NO_BRAKES;
	compassState = COMPASS_A;
	autoCancelState = AUTO_CANCEL_DISABLED;


	_EINT();  // Global enable interrupts
	LPM4;

	while (1) {
		// Power down logic
		if (brakeState == NO_BRAKES && turnState == NO_TURN) {
			// Check that we haven't missed a brake signal before going to sleep
			if (brakesActive()) {
				//setBrakes();
			}
			else {
				_EINT();
				LPM4;		// Enter low power mode until a brake or turn event
			}
		}

		// Braking logic
		if (brakeState == BRAKES) {
			if(brakesActive()) {
				// currently braking, do nothing
			}
			else {
				// stop braking
				cancelBrakes();
			}
		}
		// Check that brakes aren't active, and turn on light if necessary
		else {
			if(brakesActive())
				setBrakes();
		}

		// Entry condition: in a turn state AND ADC not busy AND no ADC interrupts pending
		if (turnState != NO_TURN && !(ADC10CTL1 & ADC10BUSY) && !(ADC10CTL0 & ADC10IFG)) {
			// Start the ADC
			flush();
			startAnalogRead();
		}


		// Entry condition: ADC data ready AND in a turn state
		if ((ADC10CTL0 & ADC10IFG) && turnState != NO_TURN) {

			// Put data in buffer
			genericCompassValue = ADC10MEM;
			// Clear interrupt flag before proceeding
			ADC10CTL0 &= ~(ADC10IFG);
			bool bufferOverflow = push(&genericCompassValue);

			if (bufferOverflow) {
				switch(compassState) {
					case COMPASS_A:
						averagedCompassValueA = getAverage();
						compassState = COMPASS_B;
						flush();
						startAnalogRead();
						break;
					case COMPASS_B:
						averagedCompassValueB = getAverage();
						compassState = COMPASS_A;
						flush();
						startAnalogRead();
						break;
				}

				// We need to pass through two buffer overflows to get current compass data from both
				// channels. On the first pass we set the state to initializing, and on the second pass
				// we set the state to ready.
				switch (autoCancelState) {
					case AUTO_CANCEL_DISABLED:
						autoCancelState = AUTO_CANCEL_INITIALIZING;
					case AUTO_CANCEL_INITIALIZING:
						autoCancelState = AUTO_CANCEL_READY;
						break;
				}
			}
			// Keep polling compass
			else {
				startAnalogRead();
			}


			// Debug test  B-670
			if(averagedCompassValueA > 650)
				P1OUT |= O1_DEBUG_LIGHT;
			else
				P1OUT &= ~O1_DEBUG_LIGHT;
			// end debug
		}


		// Entry condition: in a turn state AND auto cancel is active
		// In here we have auto-cancel logic
		if (turnState != NO_TURN && autoCancelState == AUTO_CANCEL_ACTIVE) {
			int absTurnA = startCompassValueA - averagedCompassValueA;
			int absTurnB = startCompassValueB - averagedCompassValueB;

			absTurnA = (absTurnA >= 0) ? absTurnA : -absTurnA;
			absTurnB = (absTurnB >= 0) ? absTurnB : -absTurnB;

			if (absTurnA + absTurnB > MIN_TURN_VALUE) {
				cancelTurn();
				autoCancelState = AUTO_CANCEL_DISABLED;
			}
		}
	}

	return 0;
}