void acc_mag_cal_init(void) { ASSERT_ONCE(); /* load calibration: */ opcd_param_t params[] = { /* acc bias: */ {"acc_bias_x", &acc_bias[0]}, {"acc_bias_y", &acc_bias[1]}, {"acc_bias_z", &acc_bias[2]}, /* acc scale: */ {"acc_scale_x", &acc_scale[0]}, {"acc_scale_y", &acc_scale[1]}, {"acc_scale_z", &acc_scale[2]}, /* mag bias: */ {"mag_bias_x", &mag_bias[0]}, {"mag_bias_y", &mag_bias[1]}, {"mag_bias_z", &mag_bias[2]}, /* mag scale: */ {"mag_scale_x", &mag_scale[0]}, {"mag_scale_y", &mag_scale[1]}, {"mag_scale_z", &mag_scale[2]}, OPCD_PARAMS_END }; opcd_params_apply("cal.", params); }
void att_ctrl_init(void) { ASSERT_ONCE(); /* load parameters: */ opcd_param_t params[] = { {"p", &angle_p.value}, {"i", &angle_i.value}, {"i_max", &angle_i_max.value}, {"d", &angle_d.value}, {"filt_fg", &filt_fg}, {"pitch_bias", &biases[0]}, {"roll_bias", &biases[1]}, OPCD_PARAMS_END }; opcd_params_apply("controllers.attitude.", params); /* initialize filter: */ filter1_lp_init(&filter, tsfloat_get(&filt_fg), 0.0033333, 2); /* initialize controllers: */ FOR_EACH(i, controllers) { pid_init(&controllers[i], &angle_p, &angle_i, &angle_d, &angle_i_max); }
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); }
int fc_init(void) { if (!is_initialized) { is_initialized = 1; char *serial_port; opcd_param_t params[] = { {"serial_port", &serial_port}, {"setting", &setting}, OPCD_PARAMS_END }; opcd_params_apply("actuators.mk_fc.", params); int ret; /* perform initialization once here: */ if ((ret = serial_open(&port, serial_port, 57600, ICRNL, ICANON, 0)) != 0) { return ret; } else { const struct timespec dreq_period = {0, DREQ_THREAD_TIMEOUT_MS * NSEC_PER_MSEC}; frame_t frame; char data = 1; LOG(LL_INFO, "setting up mikrokopter interface"); build_frame(frame, OUT_NC_REDIRECT_UART, (const plchar_t *)&data, 0); serial_write_line(&port, frame); rpm = malloc(sizeof(float) * platform_motors()); for (int i = 0; i < platform_motors(); i++) { rpm[i] = 0.0f; } periodic_thread_start(&dreq_thread, dreq_thread_func, DREQ_THREAD_NAME, DREQ_THREAD_PRIORITY, dreq_period, NULL); simple_thread_start(&sread_thread, sread_thread_func, SREAD_THREAD_NAME, SREAD_THREAD_PRIORITY, NULL); LOG(LL_INFO, "mikrokopter interface up and running"); } } else { LOG(LL_DEBUG, "mikrokopter interface already running"); } return 0; }
void cmc_init(void) { ASSERT_ONCE(); opcd_param_t params[] = { {"scale_x", &scale[0]}, {"scale_y", &scale[1]}, {"scale_z", &scale[2]}, {"bias", &bias}, OPCD_PARAMS_END }; opcd_params_apply("cmc.", params); }
void u_speed_init(void) { ASSERT_ONCE(); opcd_param_t params[] = { {"p", &speed_p}, {"i", &speed_i}, {"imax", &speed_imax}, OPCD_PARAMS_END }; opcd_params_apply("controllers.u_speed.", params); pid_init(&ctrl, &speed_p, &speed_i, NULL, &speed_imax); }
void u_ctrl_init(const float dt) { ASSERT_ONCE(); opcd_param_t params[] = { {"p", &pos_p}, {"d", &pos_d}, {"i", &pos_i}, {"imax", &pos_imax}, {"lpfg", &lpfg}, OPCD_PARAMS_END }; opcd_params_apply("controllers.u_pos.", params); pid_init(&ctrl, &pos_p, &pos_i, &pos_d, &pos_imax); filter1_lp_init(&filter, tsfloat_get(&lpfg), dt, 1); }
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; }
void att_ctrl_init(void) { ASSERT_ONCE(); /* load parameters: */ opcd_param_t params[] = { {"p", &angle_p.value}, {"i", &angle_i.value}, {"i_max", &angle_i_max.value}, {"d", &angle_d.value}, {"pitch_bias", &biases[0]}, {"roll_bias", &biases[1]}, {"angles_max", &angles_max}, OPCD_PARAMS_END }; opcd_params_apply("controllers.attitude.", params); /* initialize controllers: */ FOR_EACH(i, controllers) pid_init(&controllers[i], &angle_p, &angle_i, &angle_d, &angle_i_max); }
void yaw_ctrl_init(void) { ASSERT_ONCE(); opcd_param_t params[] = { {"speed_min", &speed_min}, {"speed_std", &speed_std}, {"speed_max", &speed_max}, {"speed_slope", &speed_slope}, {"speed_p", &speed_p.value}, {"speed_i", &speed_i.value}, {"speed_imax", &speed_imax.value}, {"manual", &manual}, OPCD_PARAMS_END }; opcd_params_apply("controllers.yaw.", params); tsfloat_init(&pos, 0.0f); tsfloat_init(&speed, tsfloat_get(&speed_std)); pid_init(&controller, &speed_p, &speed_i, NULL, &speed_imax); }
void ne_speed_ctrl_init(float dt) { ASSERT_ONCE(); /* load parameters: */ opcd_param_t params[] = { {"p", &speed_p.value}, {"i", &speed_i.value}, {"i_max", &speed_i_max.value}, {"d", &speed_d.value}, {"lpfg", &lpfg}, OPCD_PARAMS_END }; opcd_params_apply("controllers.ne_speed.", params); filter1_lp_init(&filter, tsfloat_get(&lpfg), dt, 2); /* initialize controllers: */ FOR_EACH(i, controllers) { pid_init(&controllers[i], &speed_p, &speed_i, &speed_d, &speed_i_max); }
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, ¤t_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); } }
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); } } }
void main_init(int argc, char *argv[]) { bool override_hw = false; if (argc > 1) { if (strcmp(argv[1], "calibrate") == 0) calibrate = true; else override_hw = true; } /* init data structures: */ memset(&pos_in, 0, sizeof(pos_in_t)); vec3_init(&pos_in.acc); /* init SCL subsystem: */ syslog(LOG_INFO, "initializing signaling and communication link (SCL)"); if (scl_init("pilot") != 0) { syslog(LOG_CRIT, "could not init scl module"); die(); } /* init params subsystem: */ syslog(LOG_INFO, "initializing opcd interface"); opcd_params_init("pilot.", 1); /* initialize logger: */ syslog(LOG_INFO, "opening logger"); if (logger_open() != 0) { syslog(LOG_CRIT, "could not open logger"); die(); } syslog(LOG_CRIT, "logger opened"); LOG(LL_INFO, "initializing platform"); if (arcade_quad_init(&platform, override_hw) < 0) { LOG(LL_ERROR, "could not initialize platform"); die(); } acc_mag_cal_init(); cmc_init(); const size_t array_len = sizeof(float) * platform.n_motors; setpoints = malloc(array_len); ASSERT_NOT_NULL(setpoints); memset(setpoints, 0, array_len); rpm_square = malloc(array_len); ASSERT_NOT_NULL(rpm_square); memset(rpm_square, 0, array_len); LOG(LL_INFO, "initializing model/controller"); pos_init(); ne_speed_ctrl_init(REALTIME_PERIOD); att_ctrl_init(); yaw_ctrl_init(); u_ctrl_init(); u_speed_init(); navi_init(); LOG(LL_INFO, "initializing command interface"); cmd_init(); motors_state_init(); blackbox_init(); /* init flight logic: */ flight_logic_init(); /* init calibration data: */ cal_init(&gyro_cal, 3, 1000); cal_ahrs_init(); flight_state_init(50, 150, 4.0); piid_init(REALTIME_PERIOD); interval_init(&gyro_move_interval); gps_data_init(&gps_data); mag_decl_init(); cal_init(&rc_cal, 3, 500); tsfloat_t acc_fg; opcd_param_t params[] = { {"acc_fg", &acc_fg}, OPCD_PARAMS_END }; opcd_params_apply("main.", params); filter1_lp_init(&lp_filter, tsfloat_get(&acc_fg), 0.06, 3); cm_init(); mon_init(); LOG(LL_INFO, "entering main loop"); }