Saturday, May 18, 2013

23. Switch-out from Auto-Pilot Mode : Another function for #UAV

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;
}

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;
}
}
}

No comments:

Post a Comment