int do_mag_calibration(int mavlink_fd) { mavlink_and_console_log_info(mavlink_fd, CAL_QGC_STARTED_MSG, sensor_name); struct mag_scale mscale_null = { 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, }; int result = OK; // Determine which mags are available and reset each int32_t device_ids[max_mags]; char str[30]; for (size_t i=0; i<max_mags; i++) { device_ids[i] = 0; // signals no mag } for (unsigned cur_mag = 0; cur_mag < max_mags; cur_mag++) { // Reset mag id to mag not available (void)sprintf(str, "CAL_MAG%u_ID", cur_mag); result = param_set_no_notification(param_find(str), &(device_ids[cur_mag])); if (result != OK) { mavlink_and_console_log_info(mavlink_fd, "[cal] Unable to reset CAL_MAG%u_ID", cur_mag); break; } // Attempt to open mag (void)sprintf(str, "%s%u", MAG_BASE_DEVICE_PATH, cur_mag); int fd = px4_open(str, O_RDONLY); if (fd < 0) { continue; } // Get device id for this mag device_ids[cur_mag] = px4_ioctl(fd, DEVIOCGDEVICEID, 0); // Reset mag scale result = px4_ioctl(fd, MAGIOCSSCALE, (long unsigned int)&mscale_null); if (result != OK) { mavlink_and_console_log_critical(mavlink_fd, CAL_ERROR_RESET_CAL_MSG, cur_mag); } /* calibrate range */ if (result == OK) { result = px4_ioctl(fd, MAGIOCCALIBRATE, fd); if (result != OK) { mavlink_and_console_log_info(mavlink_fd, "[cal] Skipped scale calibration, sensor %u", cur_mag); /* this is non-fatal - mark it accordingly */ result = OK; } } px4_close(fd); } // Calibrate all mags at the same time if (result == OK) { switch (mag_calibrate_all(mavlink_fd, device_ids)) { case calibrate_return_cancelled: // Cancel message already displayed, we're done here result = ERROR; break; case calibrate_return_ok: /* auto-save to EEPROM */ result = param_save_default(); /* if there is a any preflight-check system response, let the barrage of messages through */ usleep(200000); if (result == OK) { mavlink_and_console_log_info(mavlink_fd, CAL_QGC_PROGRESS_MSG, 100); mavlink_and_console_log_info(mavlink_fd, CAL_QGC_DONE_MSG, sensor_name); break; } else { mavlink_and_console_log_critical(mavlink_fd, CAL_ERROR_SAVE_PARAMS_MSG); } // Fall through default: mavlink_and_console_log_critical(mavlink_fd, CAL_QGC_FAILED_MSG, sensor_name); break; } } /* give this message enough time to propagate */ usleep(600000); return result; }
int do_mag_calibration(orb_advert_t *mavlink_log_pub) { calibration_log_info(mavlink_log_pub, CAL_QGC_STARTED_MSG, sensor_name); struct mag_calibration_s mscale_null; mscale_null.x_offset = 0.0f; mscale_null.x_scale = 1.0f; mscale_null.y_offset = 0.0f; mscale_null.y_scale = 1.0f; mscale_null.z_offset = 0.0f; mscale_null.z_scale = 1.0f; int result = OK; // Determine which mags are available and reset each char str[30]; for (size_t i=0; i < max_mags; i++) { device_ids[i] = 0; // signals no mag } _last_mag_progress = 0; for (unsigned cur_mag = 0; cur_mag < max_mags; cur_mag++) { #ifndef __PX4_QURT // Reset mag id to mag not available (void)sprintf(str, "CAL_MAG%u_ID", cur_mag); result = param_set_no_notification(param_find(str), &(device_ids[cur_mag])); if (result != OK) { calibration_log_info(mavlink_log_pub, "[cal] Unable to reset CAL_MAG%u_ID", cur_mag); break; } #else (void)sprintf(str, "CAL_MAG%u_XOFF", cur_mag); result = param_set(param_find(str), &mscale_null.x_offset); if (result != OK) { PX4_ERR("unable to reset %s", str); } (void)sprintf(str, "CAL_MAG%u_YOFF", cur_mag); result = param_set(param_find(str), &mscale_null.y_offset); if (result != OK) { PX4_ERR("unable to reset %s", str); } (void)sprintf(str, "CAL_MAG%u_ZOFF", cur_mag); result = param_set(param_find(str), &mscale_null.z_offset); if (result != OK) { PX4_ERR("unable to reset %s", str); } (void)sprintf(str, "CAL_MAG%u_XSCALE", cur_mag); result = param_set(param_find(str), &mscale_null.x_scale); if (result != OK) { PX4_ERR("unable to reset %s", str); } (void)sprintf(str, "CAL_MAG%u_YSCALE", cur_mag); result = param_set(param_find(str), &mscale_null.y_scale); if (result != OK) { PX4_ERR("unable to reset %s", str); } (void)sprintf(str, "CAL_MAG%u_ZSCALE", cur_mag); result = param_set(param_find(str), &mscale_null.z_scale); if (result != OK) { PX4_ERR("unable to reset %s", str); } #endif /* for calibration, commander will run on apps, so orb messages are used to get info from dsp */ #ifndef __PX4_QURT // Attempt to open mag (void)sprintf(str, "%s%u", MAG_BASE_DEVICE_PATH, cur_mag); int fd = px4_open(str, O_RDONLY); if (fd < 0) { continue; } // Get device id for this mag device_ids[cur_mag] = px4_ioctl(fd, DEVIOCGDEVICEID, 0); internal[cur_mag] = (px4_ioctl(fd, MAGIOCGEXTERNAL, 0) <= 0); // Reset mag scale result = px4_ioctl(fd, MAGIOCSSCALE, (long unsigned int)&mscale_null); if (result != OK) { calibration_log_critical(mavlink_log_pub, CAL_ERROR_RESET_CAL_MSG, cur_mag); } /* calibrate range */ if (result == OK) { result = px4_ioctl(fd, MAGIOCCALIBRATE, fd); if (result != OK) { calibration_log_info(mavlink_log_pub, "[cal] Skipped scale calibration, sensor %u", cur_mag); /* this is non-fatal - mark it accordingly */ result = OK; } } px4_close(fd); #endif } // Calibrate all mags at the same time if (result == OK) { switch (mag_calibrate_all(mavlink_log_pub)) { case calibrate_return_cancelled: // Cancel message already displayed, we're done here result = ERROR; break; case calibrate_return_ok: /* auto-save to EEPROM */ result = param_save_default(); /* if there is a any preflight-check system response, let the barrage of messages through */ usleep(200000); if (result == OK) { calibration_log_info(mavlink_log_pub, CAL_QGC_PROGRESS_MSG, 100); usleep(20000); calibration_log_info(mavlink_log_pub, CAL_QGC_DONE_MSG, sensor_name); usleep(20000); break; } else { calibration_log_critical(mavlink_log_pub, CAL_ERROR_SAVE_PARAMS_MSG); usleep(20000); } // Fall through default: calibration_log_critical(mavlink_log_pub, CAL_QGC_FAILED_MSG, sensor_name); usleep(20000); break; } } /* give this message enough time to propagate */ usleep(600000); return result; }