In our previous programming segment (16. Auto Take-Off and Auto-Landing programming of the #UAV and 6. How are we going to build a more stable Loiter program? - The Idea.) we had made Auto-Pilot program and also an Auto-take off and Auto-landing program for our U.A.V.
Then we thought more. What if due to some reason we want our U.A.V to move out of the Auto-Pilot mode towards the next desired waypoint (like sometimes we may want a quick auto-landing or surveillance of some other area)?. Hence we came up with another addition to the whole program we had made so far.
We decided to use one of the 2 output channels left (rest 5 out total 7 are used for Aileron, Throttle, rudder, Elevator and Mode) of the UDB Devboard to receive a signal from our transmitter so that whenever we change the position of the switch from its initial position (at start-up) i.e. from up to down or down to up, our DevBoard will switch out of the Auto-Pilot mode.
So in order form a logic, we first tried a simple C program in which if we press any letter different from the one we have put in the memory (through scanf function), then it will display a certain message and if we press the same letter as in the memory then another certain message will appear:
#include <stdio.h>
#include <conio.h>
int main()
{
char in, oc;
in = 'j';
printf("Testing code");
while(1)
{
printf("input pls");
oc=getch(); // so that we do not have to press enter every-time we enter something on screen
//scanf("%c", &oc);
//printf("yes wrkin");
if (oc!=in)
{
printf("Matched");
if ( (oc == 'j')||(oc == 'h'))
{
printf("moved to next waypoint");
in = oc;
}
}
}
getch();
return 0;
}
Then we thought more. What if due to some reason we want our U.A.V to move out of the Auto-Pilot mode towards the next desired waypoint (like sometimes we may want a quick auto-landing or surveillance of some other area)?. Hence we came up with another addition to the whole program we had made so far.
We decided to use one of the 2 output channels left (rest 5 out total 7 are used for Aileron, Throttle, rudder, Elevator and Mode) of the UDB Devboard to receive a signal from our transmitter so that whenever we change the position of the switch from its initial position (at start-up) i.e. from up to down or down to up, our DevBoard will switch out of the Auto-Pilot mode.
So in order form a logic, we first tried a simple C program in which if we press any letter different from the one we have put in the memory (through scanf function), then it will display a certain message and if we press the same letter as in the memory then another certain message will appear:
#include <stdio.h>
#include <conio.h>
int main()
{
char in, oc;
in = 'j';
printf("Testing code");
while(1)
{
printf("input pls");
oc=getch(); // so that we do not have to press enter every-time we enter something on screen
//scanf("%c", &oc);
//printf("yes wrkin");
if (oc!=in)
{
printf("Matched");
if ( (oc == 'j')||(oc == 'h'))
{
printf("moved to next waypoint");
in = oc;
}
}
}
getch();
return 0;
}
To implement this idea we went into the servoMix.c file of our program and edited the following:
static int mychannelvalue =0;
static char startflag =0; // will be used to check position of switch at sart-up only once
void startupfuntion(void); //to store the current position of the switch
void checkmode (void); // to check the position of the switch, if changed then switch-out of Auto-Pilot mode
static int currentvalue =0;
// Helicopter airframe
// Mix half of roll_control and half of pitch_control into aileron channels
// Mix full pitch_control into elevator
// Ignore waggle for now
#if ( AIRFRAME_TYPE == AIRFRAME_HELI )
temp = pwManual[AILERON_INPUT_CHANNEL] +
REVERSE_IF_NEEDED(AILERON_CHANNEL_REVERSED, roll_control/2 +
pitch_control/2) ;
udb_pwOut[AILERON_OUTPUT_CHANNEL] = udb_servo_pulsesat( temp ) ;
temp = pwManual[ELEVATOR_INPUT_CHANNEL] +
REVERSE_IF_NEEDED(ELEVATOR_CHANNEL_REVERSED, pitch_control) ;
udb_pwOut[ELEVATOR_OUTPUT_CHANNEL] = udb_servo_pulsesat( temp ) ;
temp = pwManual[AILERON_SECONDARY_OUTPUT_CHANNEL] +
REVERSE_IF_NEEDED(AILERON_SECONDARY_CHANNEL_REVERSED,
-roll_control/2 + pitch_control/2) ;
udb_pwOut[AILERON_SECONDARY_OUTPUT_CHANNEL] = temp ;
temp = pwManual[RUDDER_INPUT_CHANNEL] /*+
REVERSE_IF_NEEDED(RUDDER_CHANNEL_REVERSED, yaw_control)*/ ;
udb_pwOut[RUDDER_OUTPUT_CHANNEL] = udb_servo_pulsesat( temp ) ;
if ( pwManual[THROTTLE_INPUT_CHANNEL] == 0 )
{
udb_pwOut[THROTTLE_OUTPUT_CHANNEL] = 0 ;
}
else
{
temp = pwManual[THROTTLE_INPUT_CHANNEL] +
REVERSE_IF_NEEDED(THROTTLE_CHANNEL_REVERSED, throttle_control) ;
udb_pwOut[THROTTLE_OUTPUT_CHANNEL] = udb_servo_pulsesat( temp ) ;
}
#endif
mychannelvalue = udb_servo_pulsesat( pwManual[PASSTHROUGH_A_INPUT_CHANNEL] )
;
startupfuntion();
checkmode();
// next_waypoint();
udb_pwOut[PASSTHROUGH_A_OUTPUT_CHANNEL] = udb_servo_pulsesat(
pwManual[PASSTHROUGH_A_INPUT_CHANNEL] ) ;
udb_pwOut[PASSTHROUGH_B_OUTPUT_CHANNEL] = udb_servo_pulsesat(
pwManual[PASSTHROUGH_B_INPUT_CHANNEL] ) ;
udb_pwOut[PASSTHROUGH_C_OUTPUT_CHANNEL] = udb_servo_pulsesat(
pwManual[PASSTHROUGH_C_INPUT_CHANNEL] ) ;
udb_pwOut[PASSTHROUGH_D_OUTPUT_CHANNEL] = udb_servo_pulsesat(
pwManual[PASSTHROUGH_D_INPUT_CHANNEL] ) ;
}
void cameraServoMix( void )
{
int32_t temp ;
int16_t pwManual[NUM_INPUTS+1] ;
// If radio is off, use udb_pwTrim values instead of the udb_pwIn values
for (temp = 0; temp <= NUM_INPUTS; temp++)
if (udb_flags._.radio_on)
pwManual[temp] = udb_pwIn[temp];
else
pwManual[temp] = udb_pwTrim[temp];
temp = ( pwManual[CAMERA_PITCH_INPUT_CHANNEL] - 3000 ) +
REVERSE_IF_NEEDED(CAMERA_PITCH_CHANNEL_REVERSED,
cam_pitch_servo_pwm_delta ) ;
temp = cam_pitchServoLimit(temp) ;
udb_pwOut[CAMERA_PITCH_OUTPUT_CHANNEL] = udb_servo_pulsesat( temp + 3000 ) ;
temp = ( pwManual[CAMERA_YAW_INPUT_CHANNEL] - 3000 ) +
REVERSE_IF_NEEDED(CAMERA_YAW_CHANNEL_REVERSED,
cam_yaw_servo_pwm_delta ) ;
temp = cam_yawServoLimit(temp) ;
udb_pwOut[CAMERA_YAW_OUTPUT_CHANNEL] = udb_servo_pulsesat( temp + 3000 ) ;
}
void startupfuntion(void)
{
if (startflag == 0)
{
startflag =1;
currentvalue = mychannelvalue;
}
}
void checkmode(void)
{
int diff;
diff = mychannelvalue-currentvalue;
if(diff>100 || diff<-100)
{
if (flags._.GPS_steering == 1 && flags._.pitch_feedback == 1 && udb_flags._.radio_on == 1) //to check if in Auto-Pilot mode, else will never go for the function, make sure only Auto-Pilot switch-out
{
next_waypoint();
currentvalue = mychannelvalue;
}
}
}
static int mychannelvalue =0;
static char startflag =0; // will be used to check position of switch at sart-up only once
void startupfuntion(void); //to store the current position of the switch
void checkmode (void); // to check the position of the switch, if changed then switch-out of Auto-Pilot mode
static int currentvalue =0;
// Helicopter airframe
// Mix half of roll_control and half of pitch_control into aileron channels
// Mix full pitch_control into elevator
// Ignore waggle for now
#if ( AIRFRAME_TYPE == AIRFRAME_HELI )
temp = pwManual[AILERON_INPUT_CHANNEL] +
REVERSE_IF_NEEDED(AILERON_CHANNEL_REVERSED, roll_control/2 +
pitch_control/2) ;
udb_pwOut[AILERON_OUTPUT_CHANNEL] = udb_servo_pulsesat( temp ) ;
temp = pwManual[ELEVATOR_INPUT_CHANNEL] +
REVERSE_IF_NEEDED(ELEVATOR_CHANNEL_REVERSED, pitch_control) ;
udb_pwOut[ELEVATOR_OUTPUT_CHANNEL] = udb_servo_pulsesat( temp ) ;
temp = pwManual[AILERON_SECONDARY_OUTPUT_CHANNEL] +
REVERSE_IF_NEEDED(AILERON_SECONDARY_CHANNEL_REVERSED,
-roll_control/2 + pitch_control/2) ;
udb_pwOut[AILERON_SECONDARY_OUTPUT_CHANNEL] = temp ;
temp = pwManual[RUDDER_INPUT_CHANNEL] /*+
REVERSE_IF_NEEDED(RUDDER_CHANNEL_REVERSED, yaw_control)*/ ;
udb_pwOut[RUDDER_OUTPUT_CHANNEL] = udb_servo_pulsesat( temp ) ;
if ( pwManual[THROTTLE_INPUT_CHANNEL] == 0 )
{
udb_pwOut[THROTTLE_OUTPUT_CHANNEL] = 0 ;
}
else
{
temp = pwManual[THROTTLE_INPUT_CHANNEL] +
REVERSE_IF_NEEDED(THROTTLE_CHANNEL_REVERSED, throttle_control) ;
udb_pwOut[THROTTLE_OUTPUT_CHANNEL] = udb_servo_pulsesat( temp ) ;
}
#endif
mychannelvalue = udb_servo_pulsesat( pwManual[PASSTHROUGH_A_INPUT_CHANNEL] )
;
startupfuntion();
checkmode();
// next_waypoint();
udb_pwOut[PASSTHROUGH_A_OUTPUT_CHANNEL] = udb_servo_pulsesat(
pwManual[PASSTHROUGH_A_INPUT_CHANNEL] ) ;
udb_pwOut[PASSTHROUGH_B_OUTPUT_CHANNEL] = udb_servo_pulsesat(
pwManual[PASSTHROUGH_B_INPUT_CHANNEL] ) ;
udb_pwOut[PASSTHROUGH_C_OUTPUT_CHANNEL] = udb_servo_pulsesat(
pwManual[PASSTHROUGH_C_INPUT_CHANNEL] ) ;
udb_pwOut[PASSTHROUGH_D_OUTPUT_CHANNEL] = udb_servo_pulsesat(
pwManual[PASSTHROUGH_D_INPUT_CHANNEL] ) ;
}
void cameraServoMix( void )
{
int32_t temp ;
int16_t pwManual[NUM_INPUTS+1] ;
// If radio is off, use udb_pwTrim values instead of the udb_pwIn values
for (temp = 0; temp <= NUM_INPUTS; temp++)
if (udb_flags._.radio_on)
pwManual[temp] = udb_pwIn[temp];
else
pwManual[temp] = udb_pwTrim[temp];
temp = ( pwManual[CAMERA_PITCH_INPUT_CHANNEL] - 3000 ) +
REVERSE_IF_NEEDED(CAMERA_PITCH_CHANNEL_REVERSED,
cam_pitch_servo_pwm_delta ) ;
temp = cam_pitchServoLimit(temp) ;
udb_pwOut[CAMERA_PITCH_OUTPUT_CHANNEL] = udb_servo_pulsesat( temp + 3000 ) ;
temp = ( pwManual[CAMERA_YAW_INPUT_CHANNEL] - 3000 ) +
REVERSE_IF_NEEDED(CAMERA_YAW_CHANNEL_REVERSED,
cam_yaw_servo_pwm_delta ) ;
temp = cam_yawServoLimit(temp) ;
udb_pwOut[CAMERA_YAW_OUTPUT_CHANNEL] = udb_servo_pulsesat( temp + 3000 ) ;
}
void startupfuntion(void)
{
if (startflag == 0)
{
startflag =1;
currentvalue = mychannelvalue;
}
}
void checkmode(void)
{
int diff;
diff = mychannelvalue-currentvalue;
if(diff>100 || diff<-100)
{
if (flags._.GPS_steering == 1 && flags._.pitch_feedback == 1 && udb_flags._.radio_on == 1) //to check if in Auto-Pilot mode, else will never go for the function, make sure only Auto-Pilot switch-out
{
next_waypoint();
currentvalue = mychannelvalue;
}
}
}
No comments:
Post a Comment