// run the zigzag controller
// should be called at 100hz or more
void Copter::ModeZigZag::run()
{
    // initialize vertical speed and acceleration's range
    pos_control->set_max_speed_z(-get_pilot_speed_dn(), g.pilot_speed_up);
    pos_control->set_max_accel_z(g.pilot_accel_z);

    // if not auto armed or motors not enabled set throttle to zero and exit immediately
    if (!motors->armed() || !ap.auto_armed || !motors->get_interlock() || ap.land_complete) {
        zero_throttle_and_relax_ac();
        return;
    }

    // auto control
    if (stage == AUTO) {
        // if vehicle has reached destination switch to manual control
        if (reached_destination()) {
            AP_Notify::events.waypoint_complete = 1;
            stage = MANUAL_REGAIN;
            loiter_nav->init_target(wp_nav->get_wp_destination());
        } else {
            auto_control();
        }
    }

    // manual control
    if (stage == STORING_POINTS || stage == MANUAL_REGAIN) {
        // receive pilot's inputs, do position and attitude control
        manual_control();
    }
}
Exemple #2
0
//MAIN
int main(void)
{
	interrupts();
	setup_motor();
	TWI_init(CONTROL_ADDRESS);
	while(1){
		if(x == 0){
			manual_control_test();
		}
		else auto_control();
	}
}
void channels_handler(const lcm_recv_buf_t *rbuf, const char *channel,
                      const channels_t *msg, void *userdata)
{
    // create a copy of the received message
    channels_t new_msg;
    new_msg.utime = msg->utime;
    new_msg.num_channels = msg->num_channels;
    new_msg.channels = (int16_t*) malloc(msg->num_channels*sizeof(int16_t));
    for(int i = 0; i < msg->num_channels; i++)
    {
        new_msg.channels[i] = msg->channels[i];
    }
    
    // set fence switching value based on the data collection from the Quadrotor joystick
    double fence_thresh = 1500;
    
    // Copy state to local state struct to minimize mutex lock time
    struct state localstate;
    pthread_mutex_lock(&state_mutex);
    memcpy(&localstate, state, sizeof(struct state));
    pthread_mutex_unlock(&state_mutex);
    
    // Decide whether or not to edit the motor message prior to sending it
    // set_points[] array is specific to geofencing.  You need to add code
    // to compute them for our FlightLab application!!!
    float pose[8], set_points[8];
    
    // Checking if auto-pilot has been switched on by the pilot
   if (msg->channels[7] > fence_thresh)
      localstate.fence_on = 1;
   else
      localstate.fence_on = 0;
    
    if(localstate.fence_on == 1)
    {
        //printf("FENCE ON\n");
        // Cpoy state from processing loop
        for(int i = 0; i < 8; i++)
        {
            pose[i] = (float) localstate.pose[i];
            set_points[i] = localstate.set_points[i];
        }


        // if (prev_local_state.time - localstate.time == 0 || (mcobs[0]->time - mcobs[1]->time)> 1.5)

        // Check for data drop outs
        if ((!localstate.data) || (prev_local_state.time - localstate.time == 0))
        {
            // Check if watchdog has not timed out and data has dropped
            if (watchdog_count > 0)
                watchdog_count--;

            // If timed out then stay in base position
            if (watchdog_count == 0)
            {
                printf("WATCHDOG TIMEOUT\n");
                new_msg.channels[0] = thrust_PWM_base;
                new_msg.channels[1] = roll_PWM_base;
                new_msg.channels[2] = pitch_PWM_base;
                new_msg.channels[3] = yaw_PWM_base;
            }

            // If not timed out then still move towards the set point normally with autocontrol
            else
            {
                auto_control(pose, set_points, new_msg.channels);
            }
        }

        // If Data is incoming normally use autocontrol and reset the counters
        else
        {
            auto_control(pose, set_points, new_msg.channels);
            watchdog_count++;
            // If data starts coming properly then reset watchdog counter
            if (watchdog_count > 3)
                watchdog_count = 10;
        }
        printf("%d\n", watchdog_count);

        printf( "%d %d %d %d\n", new_msg.channels[0],new_msg.channels[1],new_msg.channels[2],new_msg.channels[3]);
        printf( "%f %f %f %f\n", localstate.pose[0],localstate.pose[1],localstate.pose[2],localstate.pose[3]);
        sleep(0.5);

    }
    
    else
    {  // Fence off
        // pass user commands through without modifying
        // new_msg.channels[7] = 1180;
       printf("FENCE OFF\n");
    }
    
    // send lcm message to motors
    channels_t_publish((lcm_t *) userdata, "CHANNELS_1_TX", &new_msg);
    
    // Save received (msg) and modified (new_msg) command data to file.
    // NOTE:  Customize as needed (set_points[] is for geofencing)
    fprintf(block_txt,"%ld,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%f,%f,%f,%f,%f,%f,%f,%f\n",
            (long int) msg->utime,msg->channels[0],msg->channels[1],msg->channels[2],
            msg->channels[3], msg->channels[7],
            new_msg.channels[0],new_msg.channels[1],new_msg.channels[2],
            new_msg.channels[3],new_msg.channels[7],
            set_points[0],set_points[1],set_points[2],
            set_points[3],set_points[4],set_points[5],set_points[6],
            set_points[7]);
    fflush(block_txt);

    pthread_mutex_lock(&state_mutex);
    memcpy(state, &localstate, sizeof(struct state));
    pthread_mutex_unlock(&state_mutex);
}