示例#1
0
void atmega_i2c_cam_ctrl_periodic(void)
{
  dc_periodic_4Hz();

  // Request Status
  dc_send_command(DC_GET_STATUS);
}
示例#2
0
bool nav_spiral_run(void)
{
  struct EnuCoor_f pos_enu = *stateGetPositionEnu_f();

  VECT2_DIFF(nav_spiral.trans_current, pos_enu, nav_spiral.center);
  nav_spiral.dist_from_center = FLOAT_VECT3_NORM(nav_spiral.trans_current);

  float DistanceStartEstim;
  float CircleAlpha;

  switch (nav_spiral.status) {
    case SpiralOutside:
      //flys until center of the helix is reached an start helix
      nav_route_xy(nav_spiral.fly_from.x, nav_spiral.fly_from.y, nav_spiral.center.x, nav_spiral.center.y);
      // center reached?
      if (nav_approaching_xy(nav_spiral.center.x, nav_spiral.center.y, nav_spiral.fly_from.x, nav_spiral.fly_from.y, 0)) {
        // nadir image
#ifdef DIGITAL_CAM
        dc_send_command(DC_SHOOT);
#endif
        nav_spiral.status = SpiralStartCircle;
      }
      break;
    case SpiralStartCircle:
      // Starts helix
      // storage of current coordinates
      // calculation needed, State switch to SpiralCircle
      nav_circle_XY(nav_spiral.center.y, nav_spiral.center.y, nav_spiral.radius_start);
      if (nav_spiral.dist_from_center >= nav_spiral.radius_start) {
        VECT2_COPY(nav_spiral.last_circle, pos_enu);
        nav_spiral.status = SpiralCircle;
        // Start helix
#ifdef DIGITAL_CAM
        dc_Circle(360 / nav_spiral.segments);
#endif
      }
      break;
    case SpiralCircle: {
      nav_circle_XY(nav_spiral.center.x, nav_spiral.center.y, nav_spiral.radius_start);
      // Trigonometrische Berechnung des bereits geflogenen Winkels alpha
      // equation:
      // alpha = 2 * asin ( |Starting position angular - current positon| / (2* nav_spiral.radius_start)
      // if alphamax already reached, increase radius.

      //DistanceStartEstim = |Starting position angular - current positon|
      struct FloatVect2 pos_diff;
      VECT2_DIFF(pos_diff, nav_spiral.last_circle, pos_enu);
      DistanceStartEstim = float_vect2_norm(&pos_diff);
      CircleAlpha = (2.0 * asin(DistanceStartEstim / (2 * nav_spiral.radius_start)));
      if (CircleAlpha >= nav_spiral.alpha_limit) {
        VECT2_COPY(nav_spiral.last_circle, pos_enu);
        nav_spiral.status = SpiralInc;
      }
      break;
    }
    case SpiralInc:
      // increasing circle radius as long as it is smaller than max helix radius
      if (nav_spiral.radius_start + nav_spiral.radius_increment < nav_spiral.radius) {
        nav_spiral.radius_start = nav_spiral.radius_start + nav_spiral.radius_increment;
#ifdef DIGITAL_CAM
        if (dc_cam_tracing) {
          // calculating Cam angle for camera alignment
          nav_spiral.trans_current.z = stateGetPositionUtm_f()->alt - nav_spiral.center.z;
          dc_cam_angle = atan(nav_spiral.radius_start / nav_spiral.trans_current.z) * 180  / M_PI;
        }
#endif
      } else {
        nav_spiral.radius_start = nav_spiral.radius;
#ifdef DIGITAL_CAM
        // Stopps DC
        dc_stop();
#endif
      }
      nav_spiral.status = SpiralCircle;
      break;
    default:
      break;
  }

  NavVerticalAutoThrottleMode(0.); /* No pitch */
  NavVerticalAltitudeMode(nav_spiral.center.z, 0.); /* No preclimb */

  return true;
}
bool_t nav_survey_rectangle_rotorcraft_run(uint8_t wp1, uint8_t wp2)
{
  static bool_t is_last_half = FALSE;
  static float survey_radius;
  nav_survey_active = TRUE;

  /* entry scan */ // wait for start position and altitude be reached
  if (!nav_survey_rectangle_active && ((!nav_approaching_from(&survey_from_i, NULL, 0))
                                     || (fabsf(stateGetPositionEnu_f()->z - waypoints[wp1].enu_f.z)) > 1.)) {
  } else {
    if (!nav_survey_rectangle_active) {
      nav_survey_rectangle_active = TRUE;
      LINE_START_FUNCTION;
    }

    nav_survey_west = Min(WaypointX(wp1), WaypointX(wp2));
    nav_survey_east = Max(WaypointX(wp1), WaypointX(wp2));
    nav_survey_south = Min(WaypointY(wp1), WaypointY(wp2));
    nav_survey_north = Max(WaypointY(wp1), WaypointY(wp2));

    /* Update the current segment from corners' coordinates*/
    if (SurveyGoingNorth()) {
      survey_to.y = nav_survey_north;
      survey_from.y = nav_survey_south;
    } else if (SurveyGoingSouth()) {
      survey_to.y = nav_survey_south;
      survey_from.y = nav_survey_north;
    } else if (SurveyGoingEast()) {
      survey_to.x = nav_survey_east;
      survey_from.x = nav_survey_west;
    } else if (SurveyGoingWest()) {
      survey_to.x = nav_survey_west;
      survey_from.x = nav_survey_east;
    }

    if (!survey_uturn) { /* S-N, N-S, W-E or E-W straight route */
      /*  if you like to use position croos instead of approaching uncoment this line
          if ((stateGetPositionEnu_f()->y < nav_survey_north && SurveyGoingNorth()) ||
              (stateGetPositionEnu_f()->y > nav_survey_south && SurveyGoingSouth()) ||
              (stateGetPositionEnu_f()->x < nav_survey_east && SurveyGoingEast()) ||
              (stateGetPositionEnu_f()->x > nav_survey_west && SurveyGoingWest())) {
      */
      /* Continue ... */
      ENU_BFP_OF_REAL(survey_to_i, survey_to);

      if (!nav_approaching_from(&survey_to_i, NULL, 0)) {
        ENU_BFP_OF_REAL(survey_from_i, survey_from);

        horizontal_mode = HORIZONTAL_MODE_ROUTE;
        nav_route(&survey_from_i, &survey_to_i);

      } else {
        if (survey_orientation == NS) {
          /* North or South limit reached, prepare turn and next leg */
          float x0 = survey_from.x; /* Current longitude */
          if ((x0 + nav_survey_shift < nav_survey_west)
              || (x0 + nav_survey_shift > nav_survey_east)) {   // not room for full sweep
            if (((x0 + (nav_survey_shift / 2)) < nav_survey_west)
                || ((x0 + (nav_survey_shift / 2)) > nav_survey_east)) { //not room for half sweep
              if (is_last_half) {// was last sweep half?
                nav_survey_shift = -nav_survey_shift;
                if (interleave) {
                  survey_radius = nav_survey_shift;
                }else {
                  survey_radius = nav_survey_shift /2.;
                }
                is_last_half = FALSE;
              } else { // last sweep not half
                nav_survey_shift = -nav_survey_shift;
                if (interleave) {
                  survey_radius = nav_survey_shift /2.;
                }else{
                  survey_radius = nav_survey_shift ;
                }
              }
              rectangle_survey_sweep_num ++;
            } else { //room for half sweep after
              survey_radius = nav_survey_shift / 2.;
              is_last_half = TRUE;
            }
          } else {// room for full sweep after
            survey_radius = nav_survey_shift;
          }

          x0 = x0 + survey_radius; /* Longitude of next leg */
          survey_from.x = survey_to.x = x0;

          /* Swap South and North extremities */
          float tmp = survey_from.y;
          survey_from.y = survey_to.y;
          survey_to.y = tmp;

          /** Do half a circle around WP 0 */
          waypoints[0].enu_f.x = x0;
          waypoints[0].enu_f.y = survey_from.y;

          /* Computes the right direction */
          if (SurveyGoingEast()) {
            survey_radius = -survey_radius;
          }
        } else { /* (survey_orientation == WE) */
          /* East or West limit reached, prepare turn and next leg */
          /* There is a y0 declared in math.h (for ARM) !!! */
          float my_y0 = survey_from.y; /* Current latitude */
          if (my_y0 + nav_survey_shift < nav_survey_south
              || my_y0 + nav_survey_shift > nav_survey_north) { // not room for full sweep
            if (((my_y0 + (nav_survey_shift / 2)) < nav_survey_south)
                || ((my_y0 + (nav_survey_shift / 2)) > nav_survey_north)) { //not room for half sweep
              if (is_last_half) {// was last sweep half?
                nav_survey_shift = -nav_survey_shift;
                if (interleave) {
                  survey_radius = nav_survey_shift;
                }else {
                  survey_radius = nav_survey_shift /2.;
                }
                is_last_half = FALSE;
              } else { // last sweep not half
                nav_survey_shift = -nav_survey_shift;
                if (interleave) {
                  survey_radius = nav_survey_shift /2.;
                }else{
                  survey_radius = nav_survey_shift ;
                }
              }
              rectangle_survey_sweep_num ++;
            } else { //room for half sweep after
              survey_radius = nav_survey_shift / 2.;
              is_last_half = TRUE;
            }
          } else {// room for full sweep after
            survey_radius = nav_survey_shift;
          }

          my_y0 = my_y0 + survey_radius; /* latitude of next leg */
          survey_from.y = survey_to.y = my_y0;

          /* Swap West and East extremities */
          float tmp = survey_from.x;
          survey_from.x = survey_to.x;
          survey_to.x = tmp;

          /** Do half a circle around WP 0 */
          waypoints[0].enu_f.x = survey_from.x;
          waypoints[0].enu_f.y = my_y0;

          /* Computes the right direction */
          if (SurveyGoingNorth()) {
            survey_radius = -survey_radius;
          }
        }

        nav_in_segment = FALSE;
        survey_uturn = TRUE;
        LINE_STOP_FUNCTION;
#ifdef DIGITAL_CAM
        float temp;
        if (survey_orientation == NS) {
          temp = fabsf(nav_survey_north - nav_survey_south) / dc_distance_interval;
        } else{
          temp = fabsf(nav_survey_west - nav_survey_east) / dc_distance_interval;
        }
        double inteiro;
        double fract = modf (temp , &inteiro);
        if (fract > .5) {
          dc_send_command(DC_SHOOT); //if last shot is more than shot_distance/2 from the corner take a picture in the corner before go to the next sweep
        }
#endif
      }
    } else { /* START turn */

      static struct EnuCoor_f temp_f;
      if (survey_orientation == WE) {
        temp_f.x = waypoints[0].enu_f.x;
        temp_f.y = waypoints[0].enu_f.y - survey_radius;
      } else {
        temp_f.y = waypoints[0].enu_f.y;
        temp_f.x = waypoints[0].enu_f.x - survey_radius;
      }

      //detect when segment has done
      /*  if you like to use position croos instead of approaching uncoment this line
          if ( (stateGetPositionEnu_f()->y > waypoints[0].enu_f.y && ((survey_orientation == WE) && (temp_f.y < waypoints[0].enu_f.y)) )||
               (stateGetPositionEnu_f()->y < waypoints[0].enu_f.y && ((survey_orientation == WE) && (temp_f.y > waypoints[0].enu_f.y)) )||
               (stateGetPositionEnu_f()->x < waypoints[0].enu_f.x && ((survey_orientation == NS) && (temp_f.x > waypoints[0].enu_f.x)) )||
               (stateGetPositionEnu_f()->x > waypoints[0].enu_f.x && ((survey_orientation == NS) && (temp_f.x < waypoints[0].enu_f.x)) ) ) {
      */

      if (survey_orientation == WE) {
        ENU_BFP_OF_REAL(survey_from_i, temp_f);
        ENU_BFP_OF_REAL(survey_to_i, waypoints[0].enu_f);
      } else {
        ENU_BFP_OF_REAL(survey_from_i, temp_f);
        ENU_BFP_OF_REAL(survey_to_i, waypoints[0].enu_f);
      }
      if (nav_approaching_from(&survey_to_i, NULL, 0)) {
        survey_uturn = FALSE;
        nav_in_circle = FALSE;
        LINE_START_FUNCTION;
      } else {

        if (survey_orientation == WE) {
          ENU_BFP_OF_REAL(survey_from_i, temp_f);
          ENU_BFP_OF_REAL(survey_to_i, waypoints[0].enu_f);
        } else {
          ENU_BFP_OF_REAL(survey_from_i, temp_f);
          ENU_BFP_OF_REAL(survey_to_i, waypoints[0].enu_f);
        }

        horizontal_mode = HORIZONTAL_MODE_ROUTE;
        nav_route(&survey_from_i, &survey_to_i);
      }
    } /* END turn */

  } /* END entry scan  */
  return TRUE;

}// /* END survey_retangle */
示例#4
0
文件: spiral.c 项目: ERAUBB/paparazzi
bool_t SpiralNav(void)
{
  TransCurrentX = estimator_x - WaypointX(Center);
  TransCurrentY = estimator_y - WaypointY(Center);
  DistanceFromCenter = sqrt(TransCurrentX*TransCurrentX+TransCurrentY*TransCurrentY);

  float DistanceStartEstim;
  float CircleAlpha;

  switch(CSpiralStatus)
	{
	case Outside:
	  //flys until center of the helix is reached an start helix
	  nav_route_xy(FlyFromX,FlyFromY,WaypointX(Center), WaypointY(Center));
	  // center reached?
	  if (nav_approaching_xy(WaypointX(Center), WaypointY(Center), FlyFromX, FlyFromY, 0)) {
		// nadir image
#ifdef DIGITAL_CAM
		dc_send_command(DC_SHOOT);
#endif
		CSpiralStatus = StartCircle;
	  }
	  break;
	case StartCircle:
	  // Starts helix
	  // storage of current coordinates
	  // calculation needed, State switch to Circle
	  nav_circle_XY(WaypointX(Center), WaypointY(Center), SRad);
	  if(DistanceFromCenter >= SRad){
		LastCircleX = estimator_x;
		LastCircleY = estimator_y;
		CSpiralStatus = Circle;
		// Start helix
#ifdef DIGITAL_CAM
		dc_Circle(360/Segmente);
#endif
	  }
	  break;
	case Circle: {
	  nav_circle_XY(WaypointX(Center), WaypointY(Center), SRad);
	  // Trigonometrische Berechnung des bereits geflogenen Winkels alpha
	  // equation:
	  // alpha = 2 * asin ( |Starting position angular - current positon| / (2* SRad)
	  // if alphamax already reached, increase radius.

	  //DistanceStartEstim = |Starting position angular - current positon|
	  DistanceStartEstim = sqrt (((LastCircleX-estimator_x)*(LastCircleX-estimator_x))
									   + ((LastCircleY-estimator_y)*(LastCircleY-estimator_y)));
	  CircleAlpha = (2.0 * asin (DistanceStartEstim / (2 * SRad)));
	  if (CircleAlpha >= Alphalimit) {
		LastCircleX = estimator_x;
		LastCircleY = estimator_y;
		CSpiralStatus = IncSpiral;
	  }
	  break;
    }
	case IncSpiral:
	  // increasing circle radius as long as it is smaller than max helix radius
	  if(SRad + IRad < Spiralradius)
		{
		  SRad = SRad + IRad;
#ifdef DIGITAL_CAM
		  if (dc_cam_tracing) {
			// calculating Cam angle for camera alignment
			TransCurrentZ = estimator_z - ZPoint;
			dc_cam_angle = atan(SRad/TransCurrentZ) * 180  / M_PI;
          }
#endif
		}
	  else {
		SRad = Spiralradius;
#ifdef DIGITAL_CAM
		// Stopps DC
		dc_stop();
#endif
	  }
	  CSpiralStatus = Circle;
	  break;
       default:
         break;
	}
  return TRUE;
}
示例#5
0
文件: dc.c 项目: KISSMonX/paparazzi
void dc_periodic_4Hz(void)
{
  static uint8_t dc_shutter_timer = 0;

  switch (dc_autoshoot) {

    case DC_AUTOSHOOT_PERIODIC:
      if (dc_shutter_timer) {
        dc_shutter_timer--;
      } else {
        dc_shutter_timer = dc_autoshoot_quartersec_period;
        dc_send_command(DC_SHOOT);
      }
      break;

    case DC_AUTOSHOOT_DISTANCE:
      {
        struct FloatVect2 cur_pos;
        cur_pos.x = stateGetPositionEnu_f()->x;
        cur_pos.y = stateGetPositionEnu_f()->y;
        struct FloatVect2 delta_pos;
        VECT2_DIFF(delta_pos, cur_pos, last_shot_pos);
        float dist_to_last_shot = float_vect2_norm(&delta_pos);
        if (dist_to_last_shot > dc_distance_interval) {
          dc_gps_count++;
          dc_send_command(DC_SHOOT);
          VECT2_COPY(last_shot_pos, cur_pos);
        }
      }
      break;

    case DC_AUTOSHOOT_CIRCLE:
      {
        float course = DegOfRad(stateGetNedToBodyEulers_f()->psi) - dc_circle_start_angle;
        if (course < 0.)
          course += 360.;
        float current_block = floorf(course/dc_circle_interval);

        if (dim_mod(current_block, dc_circle_last_block, dc_circle_max_blocks) == 1) {
          dc_gps_count++;
          dc_circle_last_block = current_block;
          dc_send_command(DC_SHOOT);
        }
      }
      break;

    case DC_AUTOSHOOT_SURVEY:
      {
        float dist_x = dc_gps_x - stateGetPositionEnu_f()->x;
        float dist_y = dc_gps_y - stateGetPositionEnu_f()->y;

        if (dist_x*dist_x + dist_y*dist_y >= dc_gps_next_dist*dc_gps_next_dist) {
          dc_gps_next_dist += dc_survey_interval;
          dc_gps_count++;
          dc_send_command(DC_SHOOT);
        }
      }
      break;

    default:
      dc_autoshoot = DC_AUTOSHOOT_STOP;
  }
}