Subversion Repositories FlightCtrl

Compare Revisions

Ignore whitespace Rev 2101 → Rev 2102

/branches/dongfang_FC_fixedwing/rc.c
11,9 → 11,12
// The channel array is 0-based!
volatile int16_t PPM_in[MAX_CHANNELS];
volatile uint8_t RCQuality;
 
uint8_t lastRCCommand = COMMAND_NONE;
uint8_t commandTimer = 0;
 
uint8_t lastFlightMode = FLIGHT_MODE_NONE;
 
/***************************************************************
* 16bit timer 1 is used to decode the PPM-Signal
***************************************************************/
149,6 → 152,45
#define COMMAND_CHANNEL_VERTICAL CH_THROTTLE
#define COMMAND_CHANNEL_HORIZONTAL CH_YAW
 
#define RC_SCALING 4
 
uint8_t getControlModeSwitch() {
int16_t channel = RCChannel(CH_MODESWITCH) + POT_OFFSET;
uint8_t flightMode = channel < 256/3 ? FLIGHT_MODE_MANUAL :
(channel > 256*2/3 ? FLIGHT_MODE_ANGLES : FLIGHT_MODE_RATE);
return flightMode;
}
 
// Gyro calibration is performed as.... well mode switch with no throttle and no airspeed would be nice.
// Maybe simply: Very very low throttle.
// Throttle xlow for COMMAND_TIMER: GYROCAL (once).
// mode switched: CHMOD
 
uint8_t RC_getCommand(void) {
uint8_t flightMode = getControlModeSwitch();
 
if (lastFlightMode != flightMode) {
lastFlightMode = flightMode;
lastRCCommand = COMMAND_CHMOD;
return lastRCCommand;
}
 
int16_t channel = RCChannel(CH_MODESWITCH) + POT_OFFSET;
if (channel <= -32) { // <= 900 us
if (commandTimer == COMMAND_TIMER) {
lastRCCommand = COMMAND_GYROCAL;
}
if (commandTimer <= COMMAND_TIMER) {
commandTimer++;
}
} else commandTimer = 0;
return lastRCCommand;
}
 
uint8_t RC_getArgument(void) {
return lastFlightMode;
}
 
/*
* Get Pitch, Roll, Throttle, Yaw values
*/
155,11 → 197,14
void RC_periodicTaskAndPRTY(int16_t* PRTY) {
if (RCQuality) {
RCQuality--;
PRTY[CONTROL_ELEVATOR] = RCChannel(CH_ELEVATOR);
PRTY[CONTROL_AILERONS] = RCChannel(CH_AILERONS);
PRTY[CONTROL_THROTTLE] = RCChannel(CH_THROTTLE);
PRTY[CONTROL_RUDDER] = RCChannel(CH_RUDDER);
PRTY[CONTROL_ELEVATOR] = RCChannel(CH_ELEVATOR) * RC_SCALING;
PRTY[CONTROL_AILERONS] = RCChannel(CH_AILERONS) * RC_SCALING;
PRTY[CONTROL_THROTTLE] = RCChannel(CH_THROTTLE) * RC_SCALING;
PRTY[CONTROL_RUDDER] = RCChannel(CH_RUDDER) * RC_SCALING;
 
debugOut.analog[16] = PRTY[CONTROL_ELEVATOR];
debugOut.analog[17] = PRTY[CONTROL_THROTTLE];
 
uint8_t command = COMMAND_NONE; //RC_getStickCommand();
if (lastRCCommand == command) {
// Keep timer from overrunning.
209,55 → 254,3
void RC_calibrate(void) {
// Do nothing.
}
 
uint8_t RC_getCommand(void) {
if (commandTimer == COMMAND_TIMER) {
// Stick has been held long enough; command committed.
return lastRCCommand;
}
// Not yet sure what the command is.
return COMMAND_NONE;
}
 
/*
* Command arguments on R/C:
* 2--3--4
* | | +
* 1 0 5 ^ 0
* | | |
* 8--7--6
*
* + <--
* 0
*
* Not in any of these positions: 0
*/
 
#define ARGUMENT_THRESHOLD 70
#define ARGUMENT_CHANNEL_VERTICAL CH_ELEVATOR
#define ARGUMENT_CHANNEL_HORIZONTAL CH_AILERONS
 
uint8_t RC_getArgument(void) {
if (RCChannel(ARGUMENT_CHANNEL_VERTICAL) > ARGUMENT_THRESHOLD) {
// vertical is up
if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD)
return 2;
if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD)
return 4;
return 3;
} else if (RCChannel(ARGUMENT_CHANNEL_VERTICAL) < -ARGUMENT_THRESHOLD) {
// vertical is down
if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD)
return 8;
if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD)
return 6;
return 7;
} else {
// vertical is around center
if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) > ARGUMENT_THRESHOLD)
return 1;
if (RCChannel(ARGUMENT_CHANNEL_HORIZONTAL) < -ARGUMENT_THRESHOLD)
return 5;
return 0;
}
}