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;
}
Esempio n. 2
0
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;
}