Exemple #1
0
void pos_init(void)
{
   ASSERT_ONCE();

   /* read configuration and initialize scl gates: */
   opcd_param_t params[] =
   {
      {"process_noise", &process_noise},
      {"ultra_noise", &ultra_noise},
      {"baro_noise", &baro_noise},
      {"gps_noise", &gps_noise},
      {"use_gps_speed", &use_gps_speed},
      OPCD_PARAMS_END
   };
   opcd_params_apply("kalman_pos.", params);
   LOG(LL_DEBUG, "process noise: %f, ultra noise: %f, baro noise: %f, gps noise: %f",
       tsfloat_get(&process_noise),
       tsfloat_get(&ultra_noise),
       tsfloat_get(&baro_noise),
       tsfloat_get(&gps_noise));

   /* set-up kalman filters: */
   kalman_init(&e_kalman, &process_noise, &gps_noise, 0, 0, tsint_get(&use_gps_speed));
   kalman_init(&n_kalman, &process_noise, &gps_noise, 0, 0, tsint_get(&use_gps_speed));
   kalman_init(&baro_u_kalman, &process_noise, &baro_noise, 0, 0, false);
   kalman_init(&ultra_u_kalman, &process_noise, &ultra_noise, 0, 0, false);
}
Exemple #2
0
bool auto_logic_run(bool *hard_off, bool is_full_auto, uint16_t sensor_status, bool flying, float channels[MAX_CHANNELS], float yaw, vec2_t *ne_gps_pos, float u_baro_pos, float u_ultra_pos)
{ 
   int rc_valid = sensor_status & RC_VALID;
   if (is_full_auto || rc_valid)
   {
      float gas_stick = channels[CH_GAS];
      if (is_full_auto || gas_stick > 0.5)
      {
         pthread_mutex_lock(&mutex);
         if (mode_is_ground)
            cm_u_set_ultra_pos(setp_u);
         else
            cm_u_set_baro_pos(setp_u);
         pthread_mutex_unlock(&mutex);
      }
      else
         cm_u_set_spd((gas_stick - 0.5) * 5.0);
   }
   else
      cm_u_set_spd(-0.5);

   if (u_ultra_pos > 1.0)
   {
      float yaw_stick = channels[CH_YAW];
      if (is_full_auto || (rc_valid && fabs(yaw_stick) < 0.05))
         cm_yaw_set_pos(tsfloat_get(&setp_yaw));
      else
         cm_yaw_set_spd(yaw_stick * 2.0f);
   }
   else
      cm_yaw_set_spd(0.0f);   

   float pitch = channels[CH_PITCH];
   float roll = channels[CH_ROLL];
   float sw_l = channels[CH_SWITCH_L];
   if (!is_full_auto && rc_valid && !is_full_auto && sqrt(pitch * pitch + roll * roll) > 0.1)
      hyst_gps_override = 1.0;
   hyst_gps_override -= 0.006;   

   if (hyst_gps_override > 0.0)
   {
      vec2_t angles;
      vec2_set(&angles, pitch, roll);
      cm_att_set_angles(&angles);
   }
   else
   {
      vec2_t ne_gps_setpoint;
      vec2_set(&ne_gps_setpoint, tsfloat_get(&setp_n), tsfloat_get(&setp_e));
      cm_att_set_gps_pos(&ne_gps_setpoint);
   }

   if (!is_full_auto && (sensor_status & RC_VALID) && sw_l > 0.5)
      *hard_off = true;

   return tsint_get(&motors_enabled);
}
Exemple #3
0
bool auto_logic_run(bool *hard_off, bool is_full_auto, uint16_t sensor_status, bool flying, float channels[PP_MAX_CHANNELS], float yaw, vec2_t *ne_gps_pos, float u_baro_pos, float u_ultra_pos)
{ 
   /* set u position: */
   pthread_mutex_lock(&mutex);
   if (mode_is_ground)
      cm_u_set_ultra_pos(setp_u);
   else
      cm_u_set_baro_pos(setp_u);
   pthread_mutex_unlock(&mutex);

   /* set gps position: */
   vec2_t ne_gps_setpoint;
   vec2_set(&ne_gps_setpoint, tsfloat_get(&setp_n), tsfloat_get(&setp_e));
   cm_att_set_gps_pos(&ne_gps_setpoint);
         
   /* set yaw position: */
   cm_yaw_set_pos(tsfloat_get(&setp_yaw));

   /* safe_auto code: */
   if (!is_full_auto && (sensor_status & RC_VALID))
   {
      printf("SAFE_AUTO\n");

      float sw_l = channels[CH_SWITCH_L];
      if (sw_l > 0.5)
      {
         *hard_off = true;
      }

      float gas_stick = channels[CH_GAS];
      if (gas_stick < 0.8)
         cm_u_set_acc((gas_stick - 0.5) * 5.0);
      
      float pitch = channels[CH_PITCH];
      float roll = channels[CH_ROLL];
      if (sqrt(pitch * pitch + roll * roll) > 0.1)
         hyst_gps_override = 1.0;
      hyst_gps_override -= 0.006;   

      if (hyst_gps_override > 0.0)
      {
         vec2_t angles;
         vec2_set(&angles, pitch, roll);
         cm_att_set_angles(&angles);
      }
   }

   return tsint_get(&motors_enabled);
}
Exemple #4
0
float yaw_ctrl_step(float *err_out, float yaw, float _speed, float dt)
{
   float err;
   float yaw_ctrl;
   if (tsint_get(&manual))
   {
      yaw_ctrl = 0.0f;
      err = 0.0; /* we control nothing, so the error is always 0 */
   }
   else
   {
      err = circle_err(yaw, tsfloat_get(&pos));
      float speed_setpoint = -speed_func(err);
      float speed_err = speed_setpoint - _speed;
      yaw_ctrl = pid_control(&controller, speed_err, dt);
   }
   *err_out = err;
   return yaw_ctrl;
}
Exemple #5
0
int channels_init(void)
{
   ASSERT_ONCE();

   opcd_param_t params[] =
   {
      {"pitch.index", &pitch_index},
      {"pitch.max", &pitch_max},
      {"pitch.min", &pitch_min},
      {"roll.index", &roll_index},
      {"roll.max", &roll_max},
      {"roll.min", &roll_min},
      {"yaw.index", &yaw_index},
      {"yaw.max", &yaw_max},
      {"yaw.min", &yaw_min},
      {"gas.index", &gas_index},
      {"gas.max", &gas_max},
      {"gas.min", &gas_min},
      {"two_state.index", &two_state_index},
      {"two_state.max", &two_state_max},
      {"two_state.min", &two_state_min},
      {"three_state.index", &three_state_index},
      {"three_state.max", &three_state_max},
      {"three_state.min", &three_state_min},
      OPCD_PARAMS_END
   };
   opcd_params_apply(".", params);

   /* check if channels are configured: */
   if (tsint_get(&pitch_index) == -1)
   {
      LOG(LL_INFO, "channels not configured; use pp_rc_cal and start the service again");
      return -1;
   }

   linfunc_init_points(&pitch_linfunc, tsfloat_get(&pitch_min), -1.0f, tsfloat_get(&pitch_max), 1.0f);
   linfunc_init_points(&roll_linfunc, tsfloat_get(&roll_min), -1.0f, tsfloat_get(&roll_max), 1.0f);
   linfunc_init_points(&yaw_linfunc, tsfloat_get(&yaw_min), -1.0f, tsfloat_get(&yaw_max), 1.0f);
   linfunc_init_points(&gas_linfunc, tsfloat_get(&gas_min), -1.0f, tsfloat_get(&gas_max), 1.0f);
   linfunc_init_points(&two_state_linfunc, tsfloat_get(&two_state_min), 0.0f, tsfloat_get(&two_state_max), 1.0f);
   linfunc_init_points(&three_state_linfunc, tsfloat_get(&three_state_min), 0.0f, tsfloat_get(&three_state_max), 1.0f);
   return 0;
}
Exemple #6
0
void channels_update(float out[PP_MAX_CHANNELS], float in[16])
{
   memset(out, 0, sizeof(float) * PP_MAX_CHANNELS);
   out[CH_PITCH] = linfunc_calc(&pitch_linfunc, in[tsint_get(&pitch_index)]);
   out[CH_ROLL] = linfunc_calc(&roll_linfunc, in[tsint_get(&roll_index)]);
   out[CH_YAW] = linfunc_calc(&yaw_linfunc, in[tsint_get(&yaw_index)]);
   out[CH_GAS] = linfunc_calc(&gas_linfunc, in[tsint_get(&gas_index)]);
   int twsi = tsint_get(&two_state_index);
   if (twsi != -1)
      out[CH_TWO_STATE] = linfunc_calc(&two_state_linfunc, in[twsi]);
   int trsi = tsint_get(&three_state_index);
   if (trsi != -1)
      out[CH_THREE_STATE] = linfunc_calc(&three_state_linfunc, in[trsi]);
}
Exemple #7
0
int _main(void)
{
   THROW_BEGIN()

   /* init scl and get sockets:: */
   THROW_ON_ERR(scl_init("arduino"));
   void *rc_socket = scl_get_socket("rc_raw");
   THROW_IF(rc_socket == NULL, -ENODEV);
   void *power_socket = scl_get_socket("power");
   THROW_IF(power_socket == NULL, -ENODEV);

   /* allocate msgpack buffers: */
   msgpack_sbuffer *msgpack_buf = msgpack_sbuffer_new();
   THROW_IF(msgpack_buf == NULL, -ENOMEM);
   msgpack_packer *pk = msgpack_packer_new(msgpack_buf, msgpack_sbuffer_write);
   THROW_IF(pk == NULL, -ENOMEM);
 
   /* fetch parameters: */
   char *dev_path;
   tsint_t dev_speed;
   opcd_params_init("exynos_quad.arduino_serial.", 0);
   opcd_param_t params[] =
   {
      {"path", &dev_path},
      {"speed", &dev_speed},
      OPCD_PARAMS_END
   };
   opcd_params_apply("", params);
   
   /* opern serial port: */
   serialport_t port;
   THROW_ON_ERR(serial_open(&port, dev_path, tsint_get(&dev_speed), O_RDONLY));

   uint16_t channels_raw[PPM_CHAN_MAX];
   uint32_t voltage_raw, current_raw;
   float channels[PPM_CHAN_MAX];

   while (running)
   {
      int c = serial_read_char(&port);
      if (c < 0)
         msleep(1);
      
      /* parse channels: */
      int status = ppm_parse_frame(channels_raw, (uint8_t)(c));
      if (status)
      {
         int sig_valid = 0;
         int invalid_count = 0;
         FOR_N(i, PPM_CHAN_MAX)
         {
            uint16_t chan_in = channels_raw[i];
            if (chan_in >= PPM_VALUE_INVALID)
               invalid_count++;
            if (chan_in > PPM_VALUE_MAX)
               chan_in = PPM_VALUE_MAX;
            if (chan_in < PPM_VALUE_MIN)
               chan_in = PPM_VALUE_MIN;
            channels[i] = (float)(chan_in - PPM_VALUE_MIN) / (PPM_VALUE_MAX - PPM_VALUE_MIN) * 2.f - 1.f;
         }
         sig_valid = (invalid_count < (PPM_CHAN_MAX / 3));
         
         /* send channels: */
         msgpack_sbuffer_clear(msgpack_buf);
         msgpack_pack_array(pk, 1 + PPM_CHAN_MAX);
         PACKI(sig_valid);               /* index 0: valid */
         PACKFV(channels, PPM_CHAN_MAX); /* index 1, .. : channels */
         scl_copy_send_dynamic(rc_socket, msgpack_buf->data, msgpack_buf->size);
      }

      /* parse adc voltage/current: */
      status = power_parse_frame(&voltage_raw, &current_raw, (uint8_t)(c));
      if (status)
      {
         float voltage = (float)(voltage_raw) / 1000.0;
         float current = (float)(current_raw) / 1000.0;
         
         /* send voltage / current: */
         msgpack_sbuffer_clear(msgpack_buf);
         msgpack_pack_array(pk, 2);
         PACKF(voltage); /* index 0 */
         PACKF(current); /* index 1 */
	      scl_copy_send_dynamic(power_socket, msgpack_buf->data, msgpack_buf->size);
      }
   }
Exemple #8
0
void _main(int argc, char *argv[])
{
   (void)argc;
   (void)argv;
   
   if (scl_init("gpsp") != 0)
   {
      syslog(LOG_CRIT, "could not init scl module");
      exit(EXIT_FAILURE);
   }

   gps_socket = scl_get_socket("data");
   if (gps_socket == NULL)
   {
      syslog(LOG_CRIT, "could not get scl gate");   
      exit(EXIT_FAILURE);
   }
   int64_t hwm = 1;
   zmq_setsockopt(gps_socket, ZMQ_SNDHWM, &hwm, sizeof(hwm));
  
   opcd_param_t params[] =
   {
      {"serial_path", &serial_path},
      {"serial_speed", &serial_speed},
      OPCD_PARAMS_END
   };
   
   opcd_params_init("sensors.gps.", 0);
   opcd_params_apply("", params);
   
   int status = serial_open(&port, serial_path, tsint_get(&serial_speed), 0, 0, 0);
   if (status < 0)
   {
      syslog(LOG_CRIT, "could not open serial port: %s", serial_path);
      exit(EXIT_FAILURE);
   }


   nmeaPARSER parser;
   nmea_parser_init(&parser);

   nmeaINFO info;
   nmea_zero_INFO(&info);

   int time_set = 0;
   int smask = 0; /* global smask collects all sentences and is never reset,
                     in contrast to info.smask */
   while (running)
   {
      int c = serial_read_char(&port);
      if (c < 0)
         continue;
      char b = c;

      /* parse NMEA frame: */
      if (nmea_parse(&parser, &b, 1, &info) == 1)
      {
         smask |= info.smask;
         if (   (info.smask & GPGGA) /* check for new position update */
             && (smask & (GPGSA | GPRMC))) /* go sure that we collect all sentences for first output*/
         {
            GpsData gps_data = GPS_DATA__INIT;
            
            /* set general data: */
            char time_str[TIME_STR_LEN];
            generate_time_str(time_str, &info.utc);
            gps_data.fix = 0;
            gps_data.time = time_str;
 
            /* set system time to gps time once: */
            if (!time_set && info.fix >= 2)
            {
               char shell_date_cmd[TIME_STR_LEN + 8];
               linux_sys_set_timezone(convert(info.lat), convert(info.lon));
               sprintf(shell_date_cmd, "date -s \"%s\"", time_str);
               time_set = system(shell_date_cmd) == 0;
            }
            
            /* set position data if a minimum of satellites is seen: */
            if (info.fix >= 2)
            {
               gps_data.fix = 2;
               PB_SET(gps_data, hdop, info.HDOP);
               PB_SET(gps_data, lat, convert(info.lat));
               PB_SET(gps_data, lon, convert(info.lon));
               PB_SET(gps_data, sats, info.satinfo.inuse);
               PB_SET(gps_data, course, info.track);
               PB_SET(gps_data, speed, info.speed);
            }
              
            /* set data for 3d fix: */
            if (info.fix == 3)
            {
               gps_data.fix = 3;
               PB_SET(gps_data, vdop, info.VDOP);
               PB_SET(gps_data, alt, info.elv);
            }

            /* add satellit info: */
            unsigned int i;
            gps_data.n_satinfo = info.satinfo.inview;
            SatInfo **satinfo = malloc(gps_data.n_satinfo * sizeof(SatInfo *));
            for (i = 0; i < gps_data.n_satinfo; i++)
            {
               /* fill SatInfo structure: */
               nmeaSATELLITE *nmea_satinfo = &info.satinfo.sat[i];
               satinfo[i] = malloc(gps_data.n_satinfo * sizeof(SatInfo));
               sat_info__init(satinfo[i]);
               satinfo[i]->id = nmea_satinfo->id;
               satinfo[i]->in_use = info.satinfo.in_use[i] ? 1 : 0;
               satinfo[i]->elv = nmea_satinfo->elv;
               satinfo[i]->azimuth = nmea_satinfo->azimuth;
               satinfo[i]->sig = nmea_satinfo->sig;
            }
            gps_data.satinfo = satinfo;

            /* send the data: */
            SCL_PACK_AND_SEND_DYNAMIC(gps_socket, gps_data, gps_data);
            
            /* free allocated memory: */
            for (i = 0; i < gps_data.n_satinfo; i++)
            {
               free(satinfo[i]);
            }
            free(satinfo);
         }
         nmea_zero_INFO(&info);
      }
   }
}