Exemplo n.º 1
0
static void usage()
{
	PX4_INFO("usage: navigator {start|stop|status|fencefile}");
}
Exemplo n.º 2
0
void OutputMavlink::print_status()
{
	PX4_INFO("Output: Mavlink");
}
Exemplo n.º 3
0
/**
 * Perform some basic functional tests on the driver;
 * make sure we can collect data from the sensor in polled
 * and automatic modes.
 */
void
test(enum IST8310_BUS busid)
{
	struct ist8310_bus_option &bus = find_bus(busid);
	struct mag_report report;
	ssize_t sz;
	int ret;
	const char *path = bus.devpath;

	int fd = open(path, O_RDONLY);

	if (fd < 0) {
		err(1, "%s open failed (try 'ist8310 start')", path);
	}

	/* do a simple demand read */
	sz = read(fd, &report, sizeof(report));

	if (sz != sizeof(report)) {
		err(1, "immediate read failed");
	}

	print_message(report);

	/* check if mag is onboard or external */
	if ((ret = ioctl(fd, MAGIOCGEXTERNAL, 0)) < 0) {
		errx(1, "failed to get if mag is onboard or external");
	}

	/* set the queue depth to 5 */
	if (OK != ioctl(fd, SENSORIOCSQUEUEDEPTH, 10)) {
		errx(1, "failed to set queue depth");
	}

	/* start the sensor polling at 2Hz */
	if (OK != ioctl(fd, SENSORIOCSPOLLRATE, 2)) {
		errx(1, "failed to set 2Hz poll rate");
	}

	/* read the sensor 5x and report each value */
	for (unsigned i = 0; i < 5; i++) {
		struct pollfd fds;

		/* wait for data to be ready */
		fds.fd = fd;
		fds.events = POLLIN;
		ret = poll(&fds, 1, 2000);

		if (ret != 1) {
			errx(1, "timed out waiting for sensor data");
		}

		/* now go get it */
		sz = read(fd, &report, sizeof(report));

		if (sz != sizeof(report)) {
			err(1, "periodic read failed");
		}

		print_message(report);
	}

	PX4_INFO("PASS");
	exit(0);
}
Exemplo n.º 4
0
/**
 * @brief Starts the driver.
 */
void start(enum LL40LS_BUS busid, uint8_t rotation)
{
	int fd, ret;

	if (instance) {
		PX4_INFO("driver already started");
		return;
	}

	if (busid == LL40LS_BUS_PWM) {
		instance = new LidarLitePWM(LL40LS_DEVICE_PATH_PWM, rotation);

		if (!instance) {
			PX4_ERR("Failed to instantiate LidarLitePWM");
			return;
		}

		if (instance->init() != PX4_OK) {
			PX4_ERR("failed to initialize LidarLitePWM");
			stop();
			return;
		}

	} else {
		for (uint8_t i = 0; i < (sizeof(bus_options) / sizeof(bus_options[0])); i++) {
			if (busid != LL40LS_BUS_I2C_ALL && busid != bus_options[i].busid) {
				continue;
			}

			instance = new LidarLiteI2C(bus_options[i].busnum, bus_options[i].devname, rotation);

			if (!instance) {
				PX4_ERR("Failed to instantiate LidarLiteI2C");
				return;
			}

			if (instance->init() == PX4_OK) {
				break;
			}

			PX4_ERR("failed to initialize LidarLiteI2C on busnum=%u", bus_options[i].busnum);
			stop();
		}
	}

	if (!instance) {
		PX4_WARN("No LidarLite found");
		return;
	}

	fd = px4_open(instance->get_dev_name(), O_RDONLY);

	if (fd == -1) {
		PX4_ERR("Error opening fd");
		stop();
		return;
	}

	ret = px4_ioctl(fd, SENSORIOCSPOLLRATE, SENSOR_POLLRATE_DEFAULT);
	px4_close(fd);

	if (ret < 0) {
		PX4_ERR("pollrate fail");
		stop();
		return;
	}
}
Exemplo n.º 5
0
int navio_sysfs_rc_in_main(int argc, char *argv[])
{
	if (argc < 2) {
		usage("missing command");
		return 1;
	}

	if (!strcmp(argv[1], "start")) {

		if (rc_input != nullptr && rc_input->isRunning()) {
			PX4_WARN("already running");
			/* this is not an error */
			return 0;
		}

		rc_input = new RcInput();

		// Check if alloc worked.
		if (rc_input == nullptr) {
			PX4_ERR("alloc failed");
			return -1;
		}

		int ret = rc_input->start();

		if (ret != 0) {
			PX4_ERR("start failed");
		}

		return 0;
	}

	if (!strcmp(argv[1], "stop")) {

		if (rc_input == nullptr || !rc_input->isRunning()) {
			PX4_WARN("not running");
			/* this is not an error */
			return 0;
		}

		rc_input->stop();

		// Wait for task to die
		int i = 0;

		do {
			/* wait up to 3s */
			usleep(100000);

		} while (rc_input->isRunning() && ++i < 30);

		delete rc_input;
		rc_input = nullptr;

		return 0;
	}

	if (!strcmp(argv[1], "status")) {
		if (rc_input != nullptr && rc_input->isRunning()) {
			PX4_INFO("running");

		} else {
			PX4_INFO("not running\n");
		}

		return 0;
	}

	usage("unrecognized command");
	return 1;

}
Exemplo n.º 6
0
int
sf0x_main(int argc, char *argv[])
{
	// check for optional arguments
	int ch;
	uint8_t rotation = distance_sensor_s::ROTATION_DOWNWARD_FACING;
	int myoptind = 1;
	const char *myoptarg = NULL;


	while ((ch = px4_getopt(argc, argv, "R:", &myoptind, &myoptarg)) != EOF) {
		switch (ch) {
		case 'R':
			rotation = (uint8_t)atoi(myoptarg);
			PX4_INFO("Setting distance sensor orientation to %d", (int)rotation);
			break;

		default:
			PX4_WARN("Unknown option!");
		}
	}

	/*
	 * Start/load the driver.
	 */
	if (!strcmp(argv[myoptind], "start")) {
		if (argc > myoptind + 1) {
			sf0x::start(argv[myoptind + 1], rotation);

		} else {
			sf0x::start(SF0X_DEFAULT_PORT, rotation);
		}
	}

	/*
	 * Stop the driver
	 */
	if (!strcmp(argv[myoptind], "stop")) {
		sf0x::stop();
	}

	/*
	 * Test the driver/device.
	 */
	if (!strcmp(argv[myoptind], "test")) {
		sf0x::test();
	}

	/*
	 * Reset the driver.
	 */
	if (!strcmp(argv[myoptind], "reset")) {
		sf0x::reset();
	}

	/*
	 * Print driver information.
	 */
	if (!strcmp(argv[myoptind], "info") || !strcmp(argv[1], "status")) {
		sf0x::info();
	}

	errx(1, "unrecognized command, try 'start', 'test', 'reset' or 'info'");
}
Exemplo n.º 7
0
int ver_main(int argc, char *argv[])
{
	/* defaults to an error */
	int ret = 1;

	/* first check if there are at least 2 params */
	if (argc >= 2) {
		if (argv[1] != NULL) {

			if (!strncmp(argv[1], sz_ver_hwcmp_str, sizeof(sz_ver_hwcmp_str))) {
				if (argc >= 3 && argv[2] != NULL) {
					/* compare 3rd parameter with HW_ARCH string, in case of match, return 0 */
					ret = strncmp(HW_ARCH, argv[2], strlen(HW_ARCH));

					if (ret == 0) {
						PX4_INFO("match: %s", HW_ARCH);
					}

					return ret;

				} else {
					warn("Not enough arguments, try 'ver hwcmp PX4FMU_V2'");
					return 1;
				}
			}

			/* check if we want to show all */
			bool show_all = !strncmp(argv[1], sz_ver_all_str, sizeof(sz_ver_all_str));

			if (show_all || !strncmp(argv[1], sz_ver_hw_str, sizeof(sz_ver_hw_str))) {
				printf("HW arch: %s\n", HW_ARCH);
				ret = 0;

			}

			if (show_all || !strncmp(argv[1], sz_ver_git_str, sizeof(sz_ver_git_str))) {
				printf("FW git-hash: %s\n", px4_git_version);
				unsigned fwver = version_tag_to_number(px4_git_tag);
				unsigned major = (fwver >> (8 * 3)) & 0xFF;
				unsigned minor = (fwver >> (8 * 2)) & 0xFF;
				unsigned patch = (fwver >> (8 * 1)) & 0xFF;
				unsigned type = (fwver >> (8 * 0)) & 0xFF;
				printf("FW version: %s (%u.%u.%u %u), %u\n", px4_git_tag, major, minor, patch,
				       type, fwver);
				/* middleware is currently the same thing as firmware, so not printing yet */
				printf("OS version: %s (%u)\n", os_git_tag, version_tag_to_number(os_git_tag));
				ret = 0;

			}

			if (show_all || !strncmp(argv[1], sz_ver_bdate_str, sizeof(sz_ver_bdate_str))) {
				printf("Build datetime: %s %s\n", __DATE__, __TIME__);
				ret = 0;

			}

			if (show_all || !strncmp(argv[1], sz_ver_gcc_str, sizeof(sz_ver_gcc_str))) {
				printf("Toolchain: %s\n", __VERSION__);
				ret = 0;

			}

			if (show_all || !strncmp(argv[1], mcu_ver_str, sizeof(mcu_ver_str))) {

				char rev;
				char *revstr;

				int chip_version = mcu_version(&rev, &revstr);

				if (chip_version < 0) {
					printf("UNKNOWN MCU\n");

				} else {
					printf("MCU: %s, rev. %c\n", revstr, rev);

					if (chip_version < MCU_REV_STM32F4_REV_3) {
						printf("\nWARNING   WARNING   WARNING!\n"
						       "Revision %c has a silicon errata\n"
						       "This device can only utilize a maximum of 1MB flash safely!\n"
						       "https://pixhawk.org/help/errata\n\n", rev);
					}
				}

				ret = 0;
			}

			if (show_all || !strncmp(argv[1], mcu_uid_str, sizeof(mcu_uid_str))) {
				uint32_t uid[3];

				mcu_unique_id(uid);

				printf("UID: %X:%X:%X \n", uid[0], uid[1], uid[2]);

				ret = 0;
			}


			if (ret == 1) {
				warn("unknown command.\n");
				return 1;
			}

		} else {
Exemplo n.º 8
0
void
Syslink::handle_raw_other(syslink_message_t *sys)
{
	// This function doesn't actually do anything
	// It is just here to return null responses to most standard messages

	crtp_message_t *c = (crtp_message_t *) &sys->length;

	if (c->port == CRTP_PORT_LOG) {

		PX4_INFO("Log: %d %d", c->channel, c->data[0]);

		if (c->channel == 0) { // Table of Contents Access

			uint8_t cmd = c->data[0];

			if (cmd == 0) { // GET_ITEM
				//int id = c->data[1];
				memset(&c->data[2], 0, 3);
				c->data[2] = 1; // type
				c->size = 1 + 5;
				send_message(sys);

			} else if (cmd == 1) { // GET_INFO
				memset(&c->data[1], 0, 7);
				c->size = 1 + 8;
				send_message(sys);
			}

		} else if (c->channel == 1) { // Log control

			uint8_t cmd = c->data[0];

			PX4_INFO("Responding to cmd: %d", cmd);
			c->data[2] = 0; // Success
			c->size = 3 + 1;

			// resend message
			send_message(sys);

		} else if (c->channel == 2) { // Log data

		}
	} else if (c->port == CRTP_PORT_MEM) {
		if (c->channel == 0) { // Info
			int cmd = c->data[0];

			if (cmd == 1) { // GET_NBR_OF_MEMS
				c->data[1] = 0;
				c->size = 2 + 1;

				// resend message
				send_message(sys);
			}
		}

	} else if (c->port == CRTP_PORT_PARAM) {
		if (c->channel == 0) { // TOC Access
			//	uint8_t msgId = c->data[0];

			c->data[1] = 0; // Last parameter (id = 0)
			memset(&c->data[2], 0, 10);
			c->size = 1 + 8;
			send_message(sys);
		}

		else if (c->channel == 1) { // Param read
			// 0 is ok
			c->data[1] = 0; // value
			c->size = 1 + 2;
			send_message(sys);
		}

	} else {
		PX4_INFO("Got raw: %d", c->port);
	}
}
Exemplo n.º 9
0
void BlockLocalPositionEstimator::gpsInit()
{
	// check for good gps signal
	uint8_t nSat = _sub_gps.get().satellites_used;
	float eph = _sub_gps.get().eph;
	float epv = _sub_gps.get().epv;
	uint8_t fix_type = _sub_gps.get().fix_type;

	if (
		nSat < 6 ||
		eph > _gps_eph_max.get() ||
		epv > _gps_epv_max.get() ||
		fix_type < 3
	) {
		_gpsStats.reset();
		return;
	}

	// measure
	Vector<double, n_y_gps> y;

	if (gpsMeasure(y) != OK) {
		_gpsStats.reset();
		return;
	}

	// if finished
	if (_gpsStats.getCount() > REQ_GPS_INIT_COUNT) {
		// get mean gps values
		double gpsLat = _gpsStats.getMean()(0);
		double gpsLon = _gpsStats.getMean()(1);
		float gpsAlt = _gpsStats.getMean()(2);

		_sensorTimeout &= ~SENSOR_GPS;
		_sensorFault &= ~SENSOR_GPS;
		_gpsStats.reset();

		if (!_receivedGps) {
			// this is the first time we have received gps
			_receivedGps = true;

			// note we subtract X_z which is in down directon so it is
			// an addition
			_gpsAltOrigin = gpsAlt + _x(X_z);

			// find lat, lon of current origin by subtracting x and y
			// if not using vision position since vision will
			// have it's own origin, not necessarily where vehicle starts
			if (!(_fusion.get() & FUSE_VIS_POS)) {
				double gpsLatOrigin = 0;
				double gpsLonOrigin = 0;
				// reproject at current coordinates
				map_projection_init(&_map_ref, gpsLat, gpsLon);
				// find origin
				map_projection_reproject(&_map_ref, -_x(X_x), -_x(X_y), &gpsLatOrigin, &gpsLonOrigin);
				// reinit origin
				map_projection_init(&_map_ref, gpsLatOrigin, gpsLonOrigin);

				// always override alt origin on first GPS to fix
				// possible baro offset in global altitude at init
				_altOrigin = _gpsAltOrigin;
				_altOriginInitialized = true;
			}

			PX4_INFO("[lpe] gps init "
				 "lat %6.2f lon %6.2f alt %5.1f m",
				 gpsLat,
				 gpsLon,
				 double(gpsAlt));
		}
	}
}
Exemplo n.º 10
0
/**
 * Perform some basic functional tests on the driver;
 * make sure we can collect data from the sensor in polled
 * and automatic modes.
 */
void
test()
{
	PX4_INFO("PASS");
}
Exemplo n.º 11
0
void
Syslink::handle_message(syslink_message_t *msg)
{
	hrt_abstime t = hrt_absolute_time();

	if (t - _lasttime > 1000000) {
		pktrate = _count;
		rxrate = _count_in;
		txrate = _count_out;
		nullrate = _null_count;

		_lasttime = t;
		_count = 0;
		_null_count = 0;
		_count_in = 0;
		_count_out = 0;
	}

	_count++;

	if (msg->type == SYSLINK_PM_ONOFF_SWITCHOFF) {
		// When the power button is hit
	} else if (msg->type == SYSLINK_PM_BATTERY_STATE) {

		if (msg->length != 9) {
			return;
		}

		uint8_t flags = msg->data[0];
		int charging = flags & 1;
		int powered = flags & 2;

		float vbat; //, iset;
		memcpy(&vbat, &msg->data[1], sizeof(float));
		//memcpy(&iset, &msg->data[5], sizeof(float));

		_battery.updateBatteryStatus(t, vbat, -1, true, true, 0, 0, false, &_battery_status);


		// Update battery charge state
		if (charging) {
			_bstate = BAT_CHARGING;
		}

		/* With the usb plugged in and battery disconnected, it appears to be charged. The voltage check ensures that a battery is connected  */
		else if (powered && !charging && _battery_status.voltage_filtered_v > 3.7f) {
			_bstate = BAT_CHARGED;

		} else {
			_bstate = BAT_DISCHARGING;
		}


		// announce the battery status if needed, just publish else
		if (_battery_pub != nullptr) {
			orb_publish(ORB_ID(battery_status), _battery_pub, &_battery_status);

		} else {
			_battery_pub = orb_advertise(ORB_ID(battery_status), &_battery_status);
		}

	} else if (msg->type == SYSLINK_RADIO_RSSI) {
		uint8_t rssi = msg->data[0]; // Between 40 and 100 meaning -40 dBm to -100 dBm
		_rssi = 140 - rssi * 100 / (100 - 40);

	} else if (msg->type == SYSLINK_RADIO_RAW) {
		handle_raw(msg);
		_lastrxtime = t;

	} else if ((msg->type & SYSLINK_GROUP) == SYSLINK_RADIO) {
		handle_radio(msg);

	} else if ((msg->type & SYSLINK_GROUP) == SYSLINK_OW) {
		memcpy(&_memory->msgbuf, msg, sizeof(syslink_message_t));
		px4_sem_post(&memory_sem);

	} else {
		PX4_INFO("GOT %d", msg->type);
	}

	//Send queued messages
	if (!_queue.empty()) {
		_queue.get(msg, sizeof(syslink_message_t));
		send_message(msg);
	}


	float p = (t % 500000) / 500000.0f;

	/* Use LED_GREEN for charging indicator */
	if (_bstate == BAT_CHARGED) {
		led_on(LED_GREEN);

	} else if (_bstate == BAT_CHARGING && p < 0.25f) {
		led_on(LED_GREEN);

	} else {
		led_off(LED_GREEN);
	}

	/* Alternate RX/TX LEDS when transfering */
	bool rx = t - _lastrxtime < 200000,
	     tx = t - _lasttxtime < 200000;


	if (rx && p < 0.25f) {
		led_on(LED_RX);

	} else {
		led_off(LED_RX);
	}

	if (tx && p > 0.5f && p > 0.75f) {
		led_on(LED_TX);

	} else {
		led_off(LED_TX);
	}


	// resend parameters if they haven't been acknowledged
	if (_params_ack[0] == 0 && t - _params_update[0] > 10000) {
		set_channel(_channel);

	} else if (_params_ack[1] == 0 && t - _params_update[1] > 10000) {
		set_datarate(_rate);

	} else if (_params_ack[2] == 0 && t - _params_update[2] > 10000) {
		set_address(_addr);
	}

}
Exemplo n.º 12
0
int
tfmini_main(int argc, char *argv[])
{
	// check for optional arguments
	int ch;
	uint8_t rotation = distance_sensor_s::ROTATION_DOWNWARD_FACING;
	const char *device_path = "";
	int myoptind = 1;
	const char *myoptarg = nullptr;


	while ((ch = px4_getopt(argc, argv, "R:d:", &myoptind, &myoptarg)) != EOF) {
		switch (ch) {
		case 'R':
			rotation = (uint8_t)atoi(myoptarg);
			PX4_INFO("Setting distance sensor orientation to %d", (int)rotation);
			break;

		case 'd':
			device_path = myoptarg;
			PX4_INFO("Using device path '%s'", device_path);
			break;

		default:
			PX4_WARN("Unknown option!");
		}
	}

	/*
	 * Start/load the driver.
	 */
	if (!strcmp(argv[myoptind], "start")) {
		if (strcmp(device_path, "") != 0) {
			tfmini::start(device_path, rotation);

		} else {
			PX4_WARN("Please specify device path!");
			tfmini::usage();
			return PX4_ERROR;
		}
	}

	/*
	 * Stop the driver
	 */
	if (!strcmp(argv[myoptind], "stop")) {
		tfmini::stop();
	}

	/*
	 * Test the driver/device.
	 */
	if (!strcmp(argv[myoptind], "test")) {
		tfmini::test();
	}

	/*
	 * Reset the driver.
	 */
	if (!strcmp(argv[myoptind], "reset")) {
		tfmini::reset();
	}

	/*
	 * Print driver information.
	 */
	if (!strcmp(argv[myoptind], "info") || !strcmp(argv[1], "status")) {
		tfmini::info();
	}

	PX4_ERR("unrecognized command, try 'start', 'test', 'reset' or 'info'");
	return PX4_ERROR;
}
Exemplo n.º 13
0
static int usage()
{
	PX4_INFO("usage: camera_trigger {start|stop|status|test}\n");
	return 1;
}
Exemplo n.º 14
0
void
Navigator::task_main()
{
	bool have_geofence_position_data = false;

	/* Try to load the geofence:
	 * if /fs/microsd/etc/geofence.txt load from this file */
	struct stat buffer;

	if (stat(GEOFENCE_FILENAME, &buffer) == 0) {
		PX4_INFO("Loading geofence from %s", GEOFENCE_FILENAME);
		_geofence.loadFromFile(GEOFENCE_FILENAME);
	}

	/* do subscriptions */
	_global_pos_sub = orb_subscribe(ORB_ID(vehicle_global_position));
	_local_pos_sub = orb_subscribe(ORB_ID(vehicle_local_position));
	_gps_pos_sub = orb_subscribe(ORB_ID(vehicle_gps_position));
	_sensor_combined_sub = orb_subscribe(ORB_ID(sensor_combined));
	_fw_pos_ctrl_status_sub = orb_subscribe(ORB_ID(fw_pos_ctrl_status));
	_vstatus_sub = orb_subscribe(ORB_ID(vehicle_status));
	_land_detected_sub = orb_subscribe(ORB_ID(vehicle_land_detected));
	_home_pos_sub = orb_subscribe(ORB_ID(home_position));
	_offboard_mission_sub = orb_subscribe(ORB_ID(mission));
	_param_update_sub = orb_subscribe(ORB_ID(parameter_update));
	_vehicle_command_sub = orb_subscribe(ORB_ID(vehicle_command));
	_traffic_sub = orb_subscribe(ORB_ID(transponder_report));

	/* copy all topics first time */
	vehicle_status_update();
	vehicle_land_detected_update();
	global_position_update();
	local_position_update();
	gps_position_update();
	sensor_combined_update();
	home_position_update(true);
	fw_pos_ctrl_status_update(true);
	params_update();

	/* wakeup source(s) */
	px4_pollfd_struct_t fds[1] = {};

	/* Setup of loop */
	fds[0].fd = _local_pos_sub;
	fds[0].events = POLLIN;

	/* rate-limit position subscription to 20 Hz / 50 ms */
	orb_set_interval(_local_pos_sub, 50);

	while (!_task_should_exit) {

		/* wait for up to 1000ms for data */
		int pret = px4_poll(&fds[0], (sizeof(fds) / sizeof(fds[0])), 1000);

		if (pret == 0) {
			/* Let the loop run anyway, don't do `continue` here. */

		} else if (pret < 0) {
			/* this is undesirable but not much we can do - might want to flag unhappy status */
			PX4_ERR("poll error %d, %d", pret, errno);
			usleep(10000);
			continue;

		} else {
			if (fds[0].revents & POLLIN) {
				/* success, local pos is available */
				local_position_update();
			}
		}

		perf_begin(_loop_perf);

		bool updated;

		/* gps updated */
		orb_check(_gps_pos_sub, &updated);

		if (updated) {
			gps_position_update();

			if (_geofence.getSource() == Geofence::GF_SOURCE_GPS) {
				have_geofence_position_data = true;
			}
		}

		/* global position updated */
		orb_check(_global_pos_sub, &updated);

		if (updated) {
			global_position_update();

			if (_geofence.getSource() == Geofence::GF_SOURCE_GLOBALPOS) {
				have_geofence_position_data = true;
			}
		}

		/* sensors combined updated */
		orb_check(_sensor_combined_sub, &updated);

		if (updated) {
			sensor_combined_update();
		}

		/* parameters updated */
		orb_check(_param_update_sub, &updated);

		if (updated) {
			params_update();
		}

		/* vehicle status updated */
		orb_check(_vstatus_sub, &updated);

		if (updated) {
			vehicle_status_update();
		}

		/* vehicle land detected updated */
		orb_check(_land_detected_sub, &updated);

		if (updated) {
			vehicle_land_detected_update();
		}

		/* navigation capabilities updated */
		orb_check(_fw_pos_ctrl_status_sub, &updated);

		if (updated) {
			fw_pos_ctrl_status_update();
		}

		/* home position updated */
		orb_check(_home_pos_sub, &updated);

		if (updated) {
			home_position_update();
		}

		/* vehicle_command updated */
		orb_check(_vehicle_command_sub, &updated);

		if (updated) {
			vehicle_command_s cmd;
			orb_copy(ORB_ID(vehicle_command), _vehicle_command_sub, &cmd);

			if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_GO_AROUND) {

				// DO_GO_AROUND is currently handled by the position controller (unacknowledged)
				// TODO: move DO_GO_AROUND handling to navigator
				publish_vehicle_command_ack(cmd, vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED);

			} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_REPOSITION) {

				position_setpoint_triplet_s *rep = get_reposition_triplet();
				position_setpoint_triplet_s *curr = get_position_setpoint_triplet();

				// store current position as previous position and goal as next
				rep->previous.yaw = get_global_position()->yaw;
				rep->previous.lat = get_global_position()->lat;
				rep->previous.lon = get_global_position()->lon;
				rep->previous.alt = get_global_position()->alt;

				rep->current.loiter_radius = get_loiter_radius();
				rep->current.loiter_direction = 1;
				rep->current.type = position_setpoint_s::SETPOINT_TYPE_LOITER;
				rep->current.cruising_speed = get_cruising_speed();
				rep->current.cruising_throttle = get_cruising_throttle();

				// Go on and check which changes had been requested
				if (PX4_ISFINITE(cmd.param4)) {
					rep->current.yaw = cmd.param4;

				} else {
					rep->current.yaw = NAN;
				}

				if (PX4_ISFINITE(cmd.param5) && PX4_ISFINITE(cmd.param6)) {

					// Position change with optional altitude change
					rep->current.lat = (cmd.param5 < 1000) ? cmd.param5 : cmd.param5 / (double)1e7;
					rep->current.lon = (cmd.param6 < 1000) ? cmd.param6 : cmd.param6 / (double)1e7;

					if (PX4_ISFINITE(cmd.param7)) {
						rep->current.alt = cmd.param7;

					} else {
						rep->current.alt = get_global_position()->alt;
					}

				} else if (PX4_ISFINITE(cmd.param7) && curr->current.valid
					   && PX4_ISFINITE(curr->current.lat)
					   && PX4_ISFINITE(curr->current.lon)) {

					// Altitude without position change
					rep->current.lat = curr->current.lat;
					rep->current.lon = curr->current.lon;
					rep->current.alt = cmd.param7;

				} else {
					// All three set to NaN - hold in current position
					rep->current.lat = get_global_position()->lat;
					rep->current.lon = get_global_position()->lon;
					rep->current.alt = get_global_position()->alt;
				}

				rep->previous.valid = true;
				rep->current.valid = true;
				rep->next.valid = false;

				// CMD_DO_REPOSITION is acknowledged by commander

			} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_NAV_TAKEOFF) {
				position_setpoint_triplet_s *rep = get_takeoff_triplet();

				// store current position as previous position and goal as next
				rep->previous.yaw = get_global_position()->yaw;
				rep->previous.lat = get_global_position()->lat;
				rep->previous.lon = get_global_position()->lon;
				rep->previous.alt = get_global_position()->alt;

				rep->current.loiter_radius = get_loiter_radius();
				rep->current.loiter_direction = 1;
				rep->current.type = position_setpoint_s::SETPOINT_TYPE_TAKEOFF;

				if (home_position_valid()) {
					rep->current.yaw = cmd.param4;
					rep->previous.valid = true;

				} else {
					rep->current.yaw = get_local_position()->yaw;
					rep->previous.valid = false;
				}

				if (PX4_ISFINITE(cmd.param5) && PX4_ISFINITE(cmd.param6)) {
					rep->current.lat = (cmd.param5 < 1000) ? cmd.param5 : cmd.param5 / (double)1e7;
					rep->current.lon = (cmd.param6 < 1000) ? cmd.param6 : cmd.param6 / (double)1e7;

				} else {
					// If one of them is non-finite, reset both
					rep->current.lat = NAN;
					rep->current.lon = NAN;
				}

				rep->current.alt = cmd.param7;

				rep->current.valid = true;
				rep->next.valid = false;

				// CMD_NAV_TAKEOFF is acknowledged by commander

			} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_LAND_START) {

				/* find NAV_CMD_DO_LAND_START in the mission and
				 * use MAV_CMD_MISSION_START to start the mission there
				 */
				if (_mission.land_start()) {
					vehicle_command_s vcmd = {};
					vcmd.command = vehicle_command_s::VEHICLE_CMD_MISSION_START;
					vcmd.param1 = _mission.get_land_start_index();
					publish_vehicle_cmd(&vcmd);

				} else {
					PX4_WARN("planned mission landing not available");
				}

				publish_vehicle_command_ack(cmd, vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED);

			} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_MISSION_START) {
				if (_mission_result.valid && PX4_ISFINITE(cmd.param1) && (cmd.param1 >= 0)) {
					if (!_mission.set_current_offboard_mission_index(cmd.param1)) {
						PX4_WARN("CMD_MISSION_START failed");
					}
				}

				// CMD_MISSION_START is acknowledged by commander

			} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_CHANGE_SPEED) {
				if (cmd.param2 > FLT_EPSILON) {
					// XXX not differentiating ground and airspeed yet
					set_cruising_speed(cmd.param2);

				} else {
					set_cruising_speed();

					/* if no speed target was given try to set throttle */
					if (cmd.param3 > FLT_EPSILON) {
						set_cruising_throttle(cmd.param3 / 100);

					} else {
						set_cruising_throttle();
					}
				}

				// TODO: handle responses for supported DO_CHANGE_SPEED options?
				publish_vehicle_command_ack(cmd, vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED);

			} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_ROI
				   || cmd.command == vehicle_command_s::VEHICLE_CMD_NAV_ROI
				   || cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_LOCATION
				   || cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_WPNEXT_OFFSET
				   || cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_NONE) {
				_vroi = {};

				switch (cmd.command) {
				case vehicle_command_s::VEHICLE_CMD_DO_SET_ROI:
				case vehicle_command_s::VEHICLE_CMD_NAV_ROI:
					_vroi.mode = cmd.param1;
					break;

				case vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_LOCATION:
					_vroi.mode = vehicle_command_s::VEHICLE_ROI_LOCATION;
					break;

				case vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_WPNEXT_OFFSET:
					_vroi.mode = vehicle_command_s::VEHICLE_ROI_WPNEXT;
					_vroi.pitchOffset = cmd.param5;
					_vroi.rollOffset = cmd.param6;
					_vroi.yawOffset = cmd.param7;
					break;

				case vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_NONE:
					_vroi.mode = vehicle_command_s::VEHICLE_ROI_NONE;
					break;
				}

				switch (_vroi.mode) {
				case vehicle_command_s::VEHICLE_ROI_NONE:
					break;

				case vehicle_command_s::VEHICLE_ROI_WPNEXT:
					// TODO: implement point toward next MISSION
					break;

				case vehicle_command_s::VEHICLE_ROI_WPINDEX:
					_vroi.mission_seq = cmd.param2;
					break;

				case vehicle_command_s::VEHICLE_ROI_LOCATION:
					_vroi.lat = cmd.param5;
					_vroi.lon = cmd.param6;
					_vroi.alt = cmd.param7;
					break;

				case vehicle_command_s::VEHICLE_ROI_TARGET:
					_vroi.target_seq = cmd.param2;
					break;

				default:
					_vroi.mode = vehicle_command_s::VEHICLE_ROI_NONE;
					break;
				}

				_vroi.timestamp = hrt_absolute_time();

				if (_vehicle_roi_pub != nullptr) {
					orb_publish(ORB_ID(vehicle_roi), _vehicle_roi_pub, &_vroi);

				} else {
					_vehicle_roi_pub = orb_advertise(ORB_ID(vehicle_roi), &_vroi);
				}

				publish_vehicle_command_ack(cmd, vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED);
			}
		}

		/* Check for traffic */
		check_traffic();

		/* Check geofence violation */
		static hrt_abstime last_geofence_check = 0;

		if (have_geofence_position_data &&
		    (_geofence.getGeofenceAction() != geofence_result_s::GF_ACTION_NONE) &&
		    (hrt_elapsed_time(&last_geofence_check) > GEOFENCE_CHECK_INTERVAL)) {

			bool inside = _geofence.check(_global_pos, _gps_pos, _sensor_combined.baro_alt_meter, _home_pos,
						      home_position_valid());
			last_geofence_check = hrt_absolute_time();
			have_geofence_position_data = false;

			_geofence_result.timestamp = hrt_absolute_time();
			_geofence_result.geofence_action = _geofence.getGeofenceAction();
			_geofence_result.home_required = _geofence.isHomeRequired();

			if (!inside) {
				/* inform other apps via the mission result */
				_geofence_result.geofence_violated = true;

				/* Issue a warning about the geofence violation once */
				if (!_geofence_violation_warning_sent) {
					mavlink_log_critical(&_mavlink_log_pub, "Geofence violation");
					_geofence_violation_warning_sent = true;
				}

			} else {
				/* inform other apps via the mission result */
				_geofence_result.geofence_violated = false;

				/* Reset the _geofence_violation_warning_sent field */
				_geofence_violation_warning_sent = false;
			}

			publish_geofence_result();
		}

		/* Do stuff according to navigation state set by commander */
		NavigatorMode *navigation_mode_new{nullptr};

		switch (_vstatus.nav_state) {
		case vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_mission;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_loiter;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_RCRECOVER:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_rcLoss;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_RTL:
			_pos_sp_triplet_published_invalid_once = false;

			// if RTL is set to use a mission landing and mission has a planned landing, then use MISSION
			if (mission_landing_required() && on_mission_landing()) {
				navigation_mode_new = &_mission;

			} else {
				navigation_mode_new = &_rtl;
			}

			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_takeoff;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_LAND:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_land;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_PRECLAND:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_precland;
			_precland.set_mode(PrecLandMode::Required);
			break;

		case vehicle_status_s::NAVIGATION_STATE_DESCEND:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_land;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_RTGS:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_dataLinkLoss;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_LANDENGFAIL:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_engineFailure;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_LANDGPSFAIL:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_gpsFailure;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_FOLLOW_TARGET:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_follow_target;
			break;

		case vehicle_status_s::NAVIGATION_STATE_MANUAL:
		case vehicle_status_s::NAVIGATION_STATE_ACRO:
		case vehicle_status_s::NAVIGATION_STATE_ALTCTL:
		case vehicle_status_s::NAVIGATION_STATE_POSCTL:
		case vehicle_status_s::NAVIGATION_STATE_TERMINATION:
		case vehicle_status_s::NAVIGATION_STATE_OFFBOARD:
		case vehicle_status_s::NAVIGATION_STATE_STAB:
		default:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = nullptr;
			_can_loiter_at_sp = false;
			break;
		}

		/* we have a new navigation mode: reset triplet */
		if (_navigation_mode != navigation_mode_new) {
			reset_triplets();
		}

		_navigation_mode = navigation_mode_new;

		/* iterate through navigation modes and set active/inactive for each */
		for (unsigned int i = 0; i < NAVIGATOR_MODE_ARRAY_SIZE; i++) {
			_navigation_mode_array[i]->run(_navigation_mode == _navigation_mode_array[i]);
		}

		/* if we landed and have not received takeoff setpoint then stay in idle */
		if (_land_detected.landed &&
		    !((_vstatus.nav_state == vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF)
		      || (_vstatus.nav_state == vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION))) {

			_pos_sp_triplet.current.type = position_setpoint_s::SETPOINT_TYPE_IDLE;
			_pos_sp_triplet.current.valid = true;
			_pos_sp_triplet.previous.valid = false;
			_pos_sp_triplet.next.valid = false;

		}

		/* if nothing is running, set position setpoint triplet invalid once */
		if (_navigation_mode == nullptr && !_pos_sp_triplet_published_invalid_once) {
			_pos_sp_triplet_published_invalid_once = true;
			reset_triplets();
		}

		if (_pos_sp_triplet_updated) {
			_pos_sp_triplet.timestamp = hrt_absolute_time();
			publish_position_setpoint_triplet();
			_pos_sp_triplet_updated = false;
		}

		if (_mission_result_updated) {
			publish_mission_result();
			_mission_result_updated = false;
		}

		perf_end(_loop_perf);
	}

	orb_unsubscribe(_global_pos_sub);
	orb_unsubscribe(_local_pos_sub);
	orb_unsubscribe(_gps_pos_sub);
	orb_unsubscribe(_sensor_combined_sub);
	orb_unsubscribe(_fw_pos_ctrl_status_sub);
	orb_unsubscribe(_vstatus_sub);
	orb_unsubscribe(_land_detected_sub);
	orb_unsubscribe(_home_pos_sub);
	orb_unsubscribe(_offboard_mission_sub);
	orb_unsubscribe(_param_update_sub);
	orb_unsubscribe(_vehicle_command_sub);

	PX4_INFO("exiting");

	_navigator_task = -1;
}
Exemplo n.º 15
0
void usage()
{
	PX4_INFO("usage: uart_esc start -d /dev/tty-3");
	PX4_INFO("       uart_esc stop");
	PX4_INFO("       uart_esc status");
}
Exemplo n.º 16
0
static int micrortps_start(int argc, char *argv[])
{
	if (0 > parse_options(argc, argv)) {
		printf("EXITING...\n");
		_rtps_task = -1;
		return -1;
	}

	switch (_options.transport) {
	case options::eTransports::UART: {
			transport_node = new UART_node(_options.device, _options.baudrate, _options.poll_ms);
			printf("\nUART transport: device: %s; baudrate: %d; sleep: %dms; poll: %dms\n\n",
			       _options.device, _options.baudrate, _options.sleep_ms, _options.poll_ms);
		}
		break;

	case options::eTransports::UDP: {
			transport_node = new UDP_node(_options.recv_port, _options.send_port);
			printf("\nUDP transport: recv port: %u; send port: %u; sleep: %dms\n\n",
			       _options.recv_port, _options.send_port, _options.sleep_ms);
		}
		break;

	default:
		_rtps_task = -1;
		printf("EXITING...\n");
		return -1;
	}

	if (0 > transport_node->init()) {
		printf("EXITING...\n");
		_rtps_task = -1;
		return -1;
	}


	struct timespec begin;

	int total_read = 0, loop = 0;

	uint32_t received = 0;

	micrortps_start_topics(begin, total_read, received, loop);

	struct timespec end;

	px4_clock_gettime(CLOCK_REALTIME, &end);

	double elapsed_secs = double(end.tv_sec - begin.tv_sec) + double(end.tv_nsec - begin.tv_nsec) / double(1000000000);

	printf("RECEIVED: %lu messages in %d LOOPS, %d bytes in %.03f seconds - %.02fKB/s\n\n",
	       (unsigned long)received, loop, total_read, elapsed_secs, (double)total_read / (1000 * elapsed_secs));

	delete transport_node;

	transport_node = nullptr;

	PX4_INFO("exiting");

	fflush(stdout);

	_rtps_task = -1;

	return 0;
}
Exemplo n.º 17
0
static int usage()
{
	PX4_INFO("usage: camera_feedback {start|stop}\n");
	return 1;
}
Exemplo n.º 18
0
void InputTest::print_status()
{
	PX4_INFO("Input: Test");
}
Exemplo n.º 19
0
/**
 * The daemon thread.
 */
static int frsky_telemetry_thread_main(int argc, char *argv[])
{
	/* Default values for arguments */
	char *device_name = "/dev/ttyS6"; /* USART8 */

	/* Work around some stupidity in task_create's argv handling */
	argc -= 2;
	argv += 2;

	int ch;

	while ((ch = getopt(argc, argv, "d:")) != EOF) {
		switch (ch) {
		case 'd':
			device_name = optarg;
			break;

		default:
			usage();
			break;
		}
	}

	/* Open UART assuming D type telemetry */
	struct termios uart_config_original;
	struct termios uart_config;
	const int uart = sPort_open_uart(device_name, &uart_config, &uart_config_original);

	if (uart < 0) {
		warnx("could not open %s", device_name);
		err(1, "could not open %s", device_name);
	}

	/* poll descriptor */
	struct pollfd fds[1];
	fds[0].fd = uart;
	fds[0].events = POLLIN;

	thread_running = true;

	/* Main thread loop */
	char sbuf[20];
	frsky_state = SCANNING;
	frsky_state_t baudRate = DTYPE;

	while (!thread_should_exit && frsky_state == SCANNING) {
		/* 2 byte polling frames indicate SmartPort telemetry
		 * 11 byte packets indicate D type telemetry
		 */
		int status = poll(fds, sizeof(fds) / sizeof(fds[0]), 3000);

		if (status > 0) {
			/* traffic on the port, D type is 11 bytes per frame, SmartPort is only 2
			 * Wait long enough for 11 bytes at 9600 baud
			 */
			usleep(12000);
			int nbytes = read(uart, &sbuf[0], sizeof(sbuf));
			PX4_DEBUG("frsky input: %d bytes: %x %x, speed: %d", nbytes, sbuf[0], sbuf[1], baudRate);

			// look for valid header byte
			if (nbytes > 10) {
				if (baudRate == DTYPE) {
					// see if we got a valid D-type hostframe
					struct adc_linkquality host_frame;

					if (frsky_parse_host((uint8_t *)&sbuf[0], nbytes, &host_frame)) {
						frsky_state = baudRate;
						break;
					}

				} else {
					// check for alternating S.port start bytes
					int index = 0;

					while (index < 2 && sbuf[index] != 0x7E) { index++; }

					if (index < 2) {

						int success = 1;

						for (int i = index + 2; i < nbytes; i += 2) {
							if (sbuf[i] != 0x7E) { success = 0; break; }
						}

						if (success) {
							frsky_state = baudRate;
							break;
						}
					}
				}

			}

			// alternate between S.port and D-type baud rates
			if (baudRate == SPORT) {
				PX4_DEBUG("setting baud rate to %d", 9600);
				set_uart_speed(uart, &uart_config, B9600);
				baudRate = DTYPE;

			} else {
				PX4_DEBUG("setting baud rate to %d", 57600);
				set_uart_speed(uart, &uart_config, B57600);
				baudRate = SPORT;

			}

			// wait a second
			usleep(1000000);
			// flush buffer
			read(uart, &sbuf[0], sizeof(sbuf));

		}
	}

	if (frsky_state == SPORT) {
		/* Subscribe to topics */
		if (!sPort_init()) {
			err(1, "could not allocate memory");
		}

		PX4_INFO("sending FrSky SmartPort telemetry");

		struct sensor_baro_s *sensor_baro = malloc(sizeof(struct sensor_baro_s));

		if (sensor_baro == NULL) {
			err(1, "could not allocate memory");
		}

		static float filtered_alt = NAN;
		int sensor_sub = orb_subscribe(ORB_ID(sensor_baro));

		/* send S.port telemetry */
		while (!thread_should_exit) {

			/* wait for poll frame starting with value 0x7E
			* note that only the bus master is supposed to put a 0x7E on the bus.
			* slaves use byte stuffing to send 0x7E and 0x7D.
			* we expect a poll frame every 12msec
			*/
			int status = poll(fds, sizeof(fds) / sizeof(fds[0]), 50);

			if (status < 1) { continue; }

			// read 1 byte
			int newBytes = read(uart, &sbuf[0], 1);

			if (newBytes < 1 || sbuf[0] != 0x7E) { continue; }

			/* wait for ID byte */
			status = poll(fds, sizeof(fds) / sizeof(fds[0]), 50);

			if (status < 1) { continue; }

			hrt_abstime now = hrt_absolute_time();

			newBytes = read(uart, &sbuf[1], 1);

			/* get a local copy of the current sensor values
			 * in order to apply a lowpass filter to baro pressure.
			 */
			static float last_baro_alt = 0;
			bool sensor_updated;
			orb_check(sensor_sub, &sensor_updated);

			if (sensor_updated) {
				orb_copy(ORB_ID(sensor_baro), sensor_sub, sensor_baro);

				if (isnan(filtered_alt)) {
					filtered_alt = sensor_baro->altitude;

				} else {
					filtered_alt = .05f * sensor_baro->altitude + .95f * filtered_alt;
				}
			}

			// allow a minimum of 500usec before reply
			usleep(500);

			sPort_update_topics();

			static hrt_abstime lastBATV = 0;
			static hrt_abstime lastCUR = 0;
			static hrt_abstime lastALT = 0;
			static hrt_abstime lastSPD = 0;
			static hrt_abstime lastFUEL = 0;
			static hrt_abstime lastVSPD = 0;
			static hrt_abstime lastGPS = 0;
			static hrt_abstime lastNAV_STATE = 0;
			static hrt_abstime lastGPS_FIX = 0;


			switch (sbuf[1]) {

			case SMARTPORT_POLL_1:

				/* report BATV at 1Hz */
				if (now - lastBATV > 1000 * 1000) {
					lastBATV = now;
					/* send battery voltage */
					sPort_send_BATV(uart);
				}

				break;


			case SMARTPORT_POLL_2:

				/* report battery current at 5Hz */
				if (now - lastCUR > 200 * 1000) {
					lastCUR = now;
					/* send battery current */
					sPort_send_CUR(uart);
				}

				break;


			case SMARTPORT_POLL_3:

				/* report altitude at 5Hz */
				if (now - lastALT > 200 * 1000) {
					lastALT = now;
					/* send altitude */
					sPort_send_ALT(uart);
				}

				break;


			case SMARTPORT_POLL_4:

				/* report speed at 5Hz */
				if (now - lastSPD > 200 * 1000) {
					lastSPD = now;
					/* send speed */
					sPort_send_SPD(uart);
				}

				break;

			case SMARTPORT_POLL_5:

				/* report fuel at 1Hz */
				if (now - lastFUEL > 1000 * 1000) {
					lastFUEL = now;
					/* send fuel */
					sPort_send_FUEL(uart);
				}

				break;

			case SMARTPORT_POLL_6:

				/* report vertical speed at 10Hz */
				if (now - lastVSPD > 100 * 1000) {
					/* estimate vertical speed using first difference and delta t */
					uint64_t dt = now - lastVSPD;
					float speed  = (filtered_alt - last_baro_alt) / (1e-6f * (float)dt);

					/* save current alt and timestamp */
					last_baro_alt = filtered_alt;
					lastVSPD = now;

					sPort_send_VSPD(uart, speed);
				}

				break;

			case SMARTPORT_POLL_7:

				/* report GPS data elements at 5*5Hz */
				if (now - lastGPS > 100 * 1000) {
					static int elementCount = 0;

					switch (elementCount) {

					case 0:
						sPort_send_GPS_LON(uart);
						elementCount++;
						break;

					case 1:
						sPort_send_GPS_LAT(uart);
						elementCount++;
						break;

					case 2:
						sPort_send_GPS_CRS(uart);
						elementCount++;
						break;

					case 3:
						sPort_send_GPS_ALT(uart);
						elementCount++;
						break;

					case 4:
						sPort_send_GPS_SPD(uart);
						elementCount++;
						break;

					case 5:
						sPort_send_GPS_TIME(uart);
						elementCount = 0;
						break;
					}

				}

			case SMARTPORT_POLL_8:

				/* report nav_state as DIY_NAVSTATE 2Hz */
				if (now - lastNAV_STATE > 500 * 1000) {
					lastNAV_STATE = now;
					/* send T1 */
					sPort_send_NAV_STATE(uart);
				}

				/* report satcount and fix as DIY_GPSFIX at 2Hz */
				else if (now - lastGPS_FIX > 500 * 1000) {
					lastGPS_FIX = now;
					/* send T2 */
					sPort_send_GPS_FIX(uart);
				}

				break;
			}
		}

		PX4_DEBUG("freeing sPort memory");
		sPort_deinit();
		free(sensor_baro);

		/* either no traffic on the port (0=>timeout), or D type packet */

	} else if (frsky_state == DTYPE) {
		/* detected D type telemetry: reconfigure UART */
		PX4_INFO("sending FrSky D type telemetry");
		int status = set_uart_speed(uart, &uart_config, B9600);

		if (status < 0) {
			PX4_DEBUG("error setting speed for %s, quitting", device_name);
			/* Reset the UART flags to original state */
			tcsetattr(uart, TCSANOW, &uart_config_original);
			close(uart);

			thread_running = false;
			return 0;
		}

		int iteration = 0;

		/* Subscribe to topics */
		if (!frsky_init()) {
			err(1, "could not allocate memory");
		}

		struct adc_linkquality host_frame;

		/* send D8 mode telemetry */
		while (!thread_should_exit) {

			/* Sleep 100 ms */
			usleep(100000);

			/* parse incoming data */
			int nbytes = read(uart, &sbuf[0], sizeof(sbuf));
			bool new_input = frsky_parse_host((uint8_t *)&sbuf[0], nbytes, &host_frame);

			/* the RSSI value could be useful */
			if (false && new_input) {
				warnx("host frame: ad1:%u, ad2: %u, rssi: %u",
				      host_frame.ad1, host_frame.ad2, host_frame.linkq);
			}

			frsky_update_topics();

			/* Send frame 1 (every 200ms): acceleration values, altitude (vario), temperatures, current & voltages, RPM */
			if (iteration % 2 == 0) {
				frsky_send_frame1(uart);
			}

			/* Send frame 2 (every 1000ms): course, latitude, longitude, speed, altitude (GPS), fuel level */
			if (iteration % 10 == 0) {
				frsky_send_frame2(uart);
			}

			/* Send frame 3 (every 5000ms): date, time */
			if (iteration % 50 == 0) {
				frsky_send_frame3(uart);

				iteration = 0;
			}

			iteration++;
		}

//		/* TODO: flush the input buffer if in full duplex mode */
//		read(uart, &sbuf[0], sizeof(sbuf));
		PX4_DEBUG("freeing frsky memory");
		frsky_deinit();

	}

	/* Reset the UART flags to original state */
	tcsetattr(uart, TCSANOW, &uart_config_original);
	close(uart);

	thread_running = false;
	return 0;
}
Exemplo n.º 20
0
int
param_main(int argc, char *argv[])
{
	if (argc >= 2) {
		if (!strcmp(argv[1], "save")) {
			if (argc >= 3) {
				return do_save(argv[2]);

			} else {
				int ret = do_save_default();

				if (ret) {
					PX4_ERR("Param save failed (%i)", ret);
					return 1;

				} else {
					return 0;
				}
			}
		}

		if (!strcmp(argv[1], "load")) {
			if (argc >= 3) {
				return do_load(argv[2]);

			} else {
				return do_load(param_get_default_file());
			}
		}

		if (!strcmp(argv[1], "import")) {
			if (argc >= 3) {
				return do_import(argv[2]);

			} else {
				return do_import(param_get_default_file());
			}
		}

		if (!strcmp(argv[1], "select")) {
			if (argc >= 3) {
				param_set_default_file(argv[2]);

			} else {
				param_set_default_file(NULL);
			}

			PX4_INFO("selected parameter default file %s", param_get_default_file());
			return 0;
		}

		if (!strcmp(argv[1], "show")) {
			if (argc >= 3) {
				// optional argument -c to show only non-default params
				if (!strcmp(argv[2], "-c")) {
					if (argc >= 4) {
						return do_show(argv[3], true);

					} else {
						return do_show(NULL, true);
					}

				} else {
					return do_show(argv[2], false);
				}

			} else {
				return do_show(NULL, false);
			}
		}

		if (!strcmp(argv[1], "set")) {
			if (argc >= 5) {

				/* if the fail switch is provided, fails the command if not found */
				bool fail = !strcmp(argv[4], "fail");

				return do_set(argv[2], argv[3], fail);

			} else if (argc >= 4) {
				return do_set(argv[2], argv[3], false);

			} else {
				PX4_ERR("not enough arguments.\nTry 'param set PARAM_NAME 3 [fail]'");
				return 1;
			}
		}

		if (!strcmp(argv[1], "compare")) {
			if (argc >= 4) {
				return do_compare(argv[2], &argv[3], argc - 3, COMPARE_OPERATOR_EQUAL);

			} else {
				PX4_ERR("not enough arguments.\nTry 'param compare PARAM_NAME 3'");
				return 1;
			}
		}

		if (!strcmp(argv[1], "greater")) {
			if (argc >= 4) {
				return do_compare(argv[2], &argv[3], argc - 3, COMPARE_OPERATOR_GREATER);

			} else {
				PX4_ERR("not enough arguments.\nTry 'param greater PARAM_NAME 3'");
				return 1;
			}
		}

		if (!strcmp(argv[1], "reset")) {
			if (argc >= 3) {
				return do_reset((const char **) &argv[2], argc - 2);

			} else {
				return do_reset(NULL, 0);
			}
		}

		if (!strcmp(argv[1], "reset_nostart")) {
			if (argc >= 3) {
				return do_reset_nostart((const char **) &argv[2], argc - 2);

			} else {
				return do_reset_nostart(NULL, 0);
			}
		}

		if (!strcmp(argv[1], "index_used")) {
			if (argc >= 3) {
				return do_show_index(argv[2], true);

			} else {
				PX4_ERR("no index provided");
				return 1;
			}
		}

		if (!strcmp(argv[1], "index")) {
			if (argc >= 3) {
				return do_show_index(argv[2], false);

			} else {
				PX4_ERR("no index provided");
				return 1;
			}
		}

		if (!strcmp(argv[1], "find")) {
			if (argc >= 3) {
				return do_find(argv[2]);

			} else {
				PX4_ERR("not enough arguments.\nTry 'param find PARAM_NAME'");
				return 1;
			}
		}
	}

	PX4_INFO("expected a command, try 'load', 'import', 'show [-c] [<filter>]', 'set <param> <value>', 'compare',\n'index', 'index_used', 'find', 'greater', 'select', 'save', or 'reset' ");
	return 1;
}
int do_accel_calibration(orb_advert_t *mavlink_log_pub)
{
#ifdef __PX4_NUTTX
	int fd;
#endif

	calibration_log_info(mavlink_log_pub, CAL_QGC_STARTED_MSG, sensor_name);

	struct accel_calibration_s accel_scale;
	accel_scale.x_offset = 0.0f;
	accel_scale.x_scale = 1.0f;
	accel_scale.y_offset = 0.0f;
	accel_scale.y_scale = 1.0f;
	accel_scale.z_offset = 0.0f;
	accel_scale.z_scale = 1.0f;

	int res = PX4_OK;

	char str[30];

	/* reset all sensors */
	for (unsigned s = 0; s < max_accel_sens; s++) {
#ifdef __PX4_NUTTX
		sprintf(str, "%s%u", ACCEL_BASE_DEVICE_PATH, s);
		/* reset all offsets to zero and all scales to one */
		fd = px4_open(str, 0);

		if (fd < 0) {
			continue;
		}

		device_id[s] = px4_ioctl(fd, DEVIOCGDEVICEID, 0);

		res = px4_ioctl(fd, ACCELIOCSSCALE, (long unsigned int)&accel_scale);
		px4_close(fd);

		if (res != PX4_OK) {
			calibration_log_critical(mavlink_log_pub, CAL_ERROR_RESET_CAL_MSG, s);
		}
#else
		(void)sprintf(str, "CAL_ACC%u_XOFF", s);
		res = param_set_no_notification(param_find(str), &accel_scale.x_offset);
		if (res != PX4_OK) {
			PX4_ERR("unable to reset %s", str);
		}
		(void)sprintf(str, "CAL_ACC%u_YOFF", s);
		res = param_set_no_notification(param_find(str), &accel_scale.y_offset);
		if (res != PX4_OK) {
			PX4_ERR("unable to reset %s", str);
		}
		(void)sprintf(str, "CAL_ACC%u_ZOFF", s);
		res = param_set_no_notification(param_find(str), &accel_scale.z_offset);
		if (res != PX4_OK) {
			PX4_ERR("unable to reset %s", str);
		}
		(void)sprintf(str, "CAL_ACC%u_XSCALE", s);
		res = param_set_no_notification(param_find(str), &accel_scale.x_scale);
		if (res != PX4_OK) {
			PX4_ERR("unable to reset %s", str);
		}
		(void)sprintf(str, "CAL_ACC%u_YSCALE", s);
		res = param_set_no_notification(param_find(str), &accel_scale.y_scale);
		if (res != PX4_OK) {
			PX4_ERR("unable to reset %s", str);
		}
		(void)sprintf(str, "CAL_ACC%u_ZSCALE", s);
		res = param_set_no_notification(param_find(str), &accel_scale.z_scale);
		if (res != PX4_OK) {
			PX4_ERR("unable to reset %s", str);
		}
		param_notify_changes();
#endif
	}

	float accel_offs[max_accel_sens][3];
	float accel_T[max_accel_sens][3][3];
	unsigned active_sensors = 0;

	/* measure and calculate offsets & scales */
	if (res == PX4_OK) {
		calibrate_return cal_return = do_accel_calibration_measurements(mavlink_log_pub, accel_offs, accel_T, &active_sensors);
		if (cal_return == calibrate_return_cancelled) {
			// Cancel message already displayed, nothing left to do
			return PX4_ERROR;
		} else if (cal_return == calibrate_return_ok) {
			res = PX4_OK;
		} else {
			res = PX4_ERROR;
		}
	}

	if (res != PX4_OK) {
		if (active_sensors == 0) {
			calibration_log_critical(mavlink_log_pub, CAL_ERROR_SENSOR_MSG);
		}
		return PX4_ERROR;
	}

	/* measurements completed successfully, rotate calibration values */
	param_t board_rotation_h = param_find("SENS_BOARD_ROT");
	int32_t board_rotation_int;
	param_get(board_rotation_h, &(board_rotation_int));
	enum Rotation board_rotation_id = (enum Rotation)board_rotation_int;
	math::Matrix<3, 3> board_rotation;
	get_rot_matrix(board_rotation_id, &board_rotation);
	math::Matrix<3, 3> board_rotation_t = board_rotation.transposed();

	bool tc_locked[3] = {false}; // true when the thermal parameter instance has already been adjusted by the calibrator

	for (unsigned uorb_index = 0; uorb_index < active_sensors; uorb_index++) {

		/* handle individual sensors, one by one */
		math::Vector<3> accel_offs_vec(accel_offs[uorb_index]);
		math::Vector<3> accel_offs_rotated = board_rotation_t * accel_offs_vec;
		math::Matrix<3, 3> accel_T_mat(accel_T[uorb_index]);
		math::Matrix<3, 3> accel_T_rotated = board_rotation_t * accel_T_mat * board_rotation;

		accel_scale.x_offset = accel_offs_rotated(0);
		accel_scale.x_scale = accel_T_rotated(0, 0);
		accel_scale.y_offset = accel_offs_rotated(1);
		accel_scale.y_scale = accel_T_rotated(1, 1);
		accel_scale.z_offset = accel_offs_rotated(2);
		accel_scale.z_scale = accel_T_rotated(2, 2);

		bool failed = false;

		failed = failed || (PX4_OK != param_set_no_notification(param_find("CAL_ACC_PRIME"), &(device_id_primary)));


		PX4_INFO("found offset %d: x: %.6f, y: %.6f, z: %.6f", uorb_index,
				(double)accel_scale.x_offset,
				(double)accel_scale.y_offset,
				(double)accel_scale.z_offset);
		PX4_INFO("found scale %d: x: %.6f, y: %.6f, z: %.6f", uorb_index,
				(double)accel_scale.x_scale,
				(double)accel_scale.y_scale,
				(double)accel_scale.z_scale);

		/* check if thermal compensation is enabled */
		int32_t tc_enabled_int;
		param_get(param_find("TC_A_ENABLE"), &(tc_enabled_int));
		if (tc_enabled_int == 1) {
			/* Get struct containing sensor thermal compensation data */
			struct sensor_correction_s sensor_correction; /**< sensor thermal corrections */
			memset(&sensor_correction, 0, sizeof(sensor_correction));
			int sensor_correction_sub = orb_subscribe(ORB_ID(sensor_correction));
			orb_copy(ORB_ID(sensor_correction), sensor_correction_sub, &sensor_correction);
			orb_unsubscribe(sensor_correction_sub);

			/* don't allow a parameter instance to be calibrated more than once by another uORB instance */
			if (!tc_locked[sensor_correction.accel_mapping[uorb_index]]) {
				tc_locked[sensor_correction.accel_mapping[uorb_index]] = true;

				/* update the _X0_ terms to include the additional offset */
				int32_t handle;
				float val;
				for (unsigned axis_index = 0; axis_index < 3; axis_index++) {
					val = 0.0f;
					(void)sprintf(str, "TC_A%u_X0_%u", sensor_correction.accel_mapping[uorb_index], axis_index);
					handle = param_find(str);
					param_get(handle, &val);
					if (axis_index == 0) {
						val += accel_scale.x_offset;
					} else if (axis_index == 1) {
						val += accel_scale.y_offset;
					} else if (axis_index == 2) {
						val += accel_scale.z_offset;
					}
					failed |= (PX4_OK != param_set_no_notification(handle, &val));
				}

				/* update the _SCL_ terms to include the scale factor */
				for (unsigned axis_index = 0; axis_index < 3; axis_index++) {
					val = 1.0f;
					(void)sprintf(str, "TC_A%u_SCL_%u", sensor_correction.accel_mapping[uorb_index], axis_index);
					handle = param_find(str);
					if (axis_index == 0) {
						val = accel_scale.x_scale;
					} else if (axis_index == 1) {
						val = accel_scale.y_scale;
					} else if (axis_index == 2) {
						val = accel_scale.z_scale;
					}
					failed |= (PX4_OK != param_set_no_notification(handle, &val));
				}
				param_notify_changes();
			}

			// Ensure the calibration values used by the driver are at default settings when we are using thermal calibration data
			accel_scale.x_offset = 0.f;
			accel_scale.y_offset = 0.f;
			accel_scale.z_offset = 0.f;
			accel_scale.x_scale = 1.f;
			accel_scale.y_scale = 1.f;
			accel_scale.z_scale = 1.f;
		}

		// save the driver level calibration data
		(void)sprintf(str, "CAL_ACC%u_XOFF", uorb_index);
		failed |= (PX4_OK != param_set_no_notification(param_find(str), &(accel_scale.x_offset)));
		(void)sprintf(str, "CAL_ACC%u_YOFF", uorb_index);
		failed |= (PX4_OK != param_set_no_notification(param_find(str), &(accel_scale.y_offset)));
		(void)sprintf(str, "CAL_ACC%u_ZOFF", uorb_index);
		failed |= (PX4_OK != param_set_no_notification(param_find(str), &(accel_scale.z_offset)));
		(void)sprintf(str, "CAL_ACC%u_XSCALE", uorb_index);
		failed |= (PX4_OK != param_set_no_notification(param_find(str), &(accel_scale.x_scale)));
		(void)sprintf(str, "CAL_ACC%u_YSCALE", uorb_index);
		failed |= (PX4_OK != param_set_no_notification(param_find(str), &(accel_scale.y_scale)));
		(void)sprintf(str, "CAL_ACC%u_ZSCALE", uorb_index);
		failed |= (PX4_OK != param_set_no_notification(param_find(str), &(accel_scale.z_scale)));
		(void)sprintf(str, "CAL_ACC%u_ID", uorb_index);
		failed |= (PX4_OK != param_set_no_notification(param_find(str), &(device_id[uorb_index])));

		if (failed) {
			calibration_log_critical(mavlink_log_pub, CAL_ERROR_SET_PARAMS_MSG, uorb_index);
			return PX4_ERROR;
		}

#ifdef __PX4_NUTTX
		sprintf(str, "%s%u", ACCEL_BASE_DEVICE_PATH, uorb_index);
		fd = px4_open(str, 0);

		if (fd < 0) {
			calibration_log_critical(mavlink_log_pub, CAL_QGC_FAILED_MSG, "sensor does not exist");
			res = PX4_ERROR;
		} else {
			res = px4_ioctl(fd, ACCELIOCSSCALE, (long unsigned int)&accel_scale);
			px4_close(fd);
		}

		if (res != PX4_OK) {
			calibration_log_critical(mavlink_log_pub, CAL_ERROR_APPLY_CAL_MSG, uorb_index);
		}
#endif
	}

	if (res == PX4_OK) {
		/* if there is a any preflight-check system response, let the barrage of messages through */
		usleep(200000);

		calibration_log_info(mavlink_log_pub, CAL_QGC_DONE_MSG, sensor_name);

	} else {
		calibration_log_critical(mavlink_log_pub, CAL_QGC_FAILED_MSG, sensor_name);
	}

	/* give this message enough time to propagate */
	usleep(600000);

	return res;
}
Exemplo n.º 22
0
static int
task_main(int argc, char *argv[])
{
	work_q_item_t *work;

	/* Initialize global variables */
	g_key_offsets[0] = 0;

	for (unsigned i = 0; i < (DM_KEY_NUM_KEYS - 1); i++) {
		g_key_offsets[i + 1] = g_key_offsets[i] + (g_per_item_max_index[i] * k_sector_size);
	}

	unsigned max_offset = g_key_offsets[DM_KEY_NUM_KEYS - 1] + (g_per_item_max_index[DM_KEY_NUM_KEYS - 1] * k_sector_size);

	for (unsigned i = 0; i < dm_number_of_funcs; i++) {
		g_func_counts[i] = 0;
	}

	/* Initialize the item type locks, for now only DM_KEY_MISSION_STATE supports locking */
	px4_sem_init(&g_sys_state_mutex, 1, 1); /* Initially unlocked */

	for (unsigned i = 0; i < DM_KEY_NUM_KEYS; i++) {
		g_item_locks[i] = NULL;
	}

	g_item_locks[DM_KEY_MISSION_STATE] = &g_sys_state_mutex;

	g_task_should_exit = false;

	init_q(&g_work_q);
	init_q(&g_free_q);

	px4_sem_init(&g_work_queued_sema, 1, 0);

	/* See if the data manage file exists and is a multiple of the sector size */
	g_task_fd = open(k_data_manager_device_path, O_RDONLY | O_BINARY);

	if (g_task_fd >= 0) {

#ifndef __PX4_POSIX
		// XXX on Mac OS and Linux the file is not a multiple of the sector sizes
		// this might need further inspection.

		/* File exists, check its size */
		int file_size = lseek(g_task_fd, 0, SEEK_END);

		if ((file_size % k_sector_size) != 0) {
			PX4_WARN("Incompatible data manager file %s, resetting it", k_data_manager_device_path);
			PX4_WARN("Size: %u, sector size: %d", file_size, k_sector_size);
			close(g_task_fd);
			unlink(k_data_manager_device_path);
		}

#else
		close(g_task_fd);
#endif

	}

	/* Open or create the data manager file */
	g_task_fd = open(k_data_manager_device_path, O_RDWR | O_CREAT | O_BINARY, PX4_O_MODE_666);

	if (g_task_fd < 0) {
		PX4_WARN("Could not open data manager file %s", k_data_manager_device_path);
		px4_sem_post(&g_init_sema); /* Don't want to hang startup */
		return -1;
	}

	if ((unsigned)lseek(g_task_fd, max_offset, SEEK_SET) != max_offset) {
		close(g_task_fd);
		PX4_WARN("Could not seek data manager file %s", k_data_manager_device_path);
		px4_sem_post(&g_init_sema); /* Don't want to hang startup */
		return -1;
	}

	fsync(g_task_fd);

	/* see if we need to erase any items based on restart type */
	int sys_restart_val;

	const char *restart_type_str = "Unkown restart";

	if (param_get(param_find("SYS_RESTART_TYPE"), &sys_restart_val) == OK) {
		if (sys_restart_val == DM_INIT_REASON_POWER_ON) {
			restart_type_str = "Power on restart";
			_restart(DM_INIT_REASON_POWER_ON);

		} else if (sys_restart_val == DM_INIT_REASON_IN_FLIGHT) {
			restart_type_str = "In flight restart";
			_restart(DM_INIT_REASON_IN_FLIGHT);
		}
	}

	/* We use two file descriptors, one for the caller context and one for the worker thread */
	/* They are actually the same but we need to some way to reject caller request while the */
	/* worker thread is shutting down but still processing requests */
	g_fd = g_task_fd;

	PX4_INFO("%s, data manager file '%s' size is %d bytes",
		 restart_type_str, k_data_manager_device_path, max_offset);

	/* Tell startup that the worker thread has completed its initialization */
	px4_sem_post(&g_init_sema);

	/* Start the endless loop, waiting for then processing work requests */
	while (true) {

		/* do we need to exit ??? */
		if ((g_task_should_exit) && (g_fd >= 0)) {
			/* Close the file handle to stop further queuing */
			g_fd = -1;
		}

		if (!g_task_should_exit) {
			/* wait for work */
			px4_sem_wait(&g_work_queued_sema);
		}

		/* Empty the work queue */
		while ((work = dequeue_work_item())) {

			/* handle each work item with the appropriate handler */
			switch (work->func) {
			case dm_write_func:
				g_func_counts[dm_write_func]++;
				work->result =
					_write(work->write_params.item, work->write_params.index, work->write_params.persistence, work->write_params.buf,
					       work->write_params.count);
				break;

			case dm_read_func:
				g_func_counts[dm_read_func]++;
				work->result =
					_read(work->read_params.item, work->read_params.index, work->read_params.buf, work->read_params.count);
				break;

			case dm_clear_func:
				g_func_counts[dm_clear_func]++;
				work->result = _clear(work->clear_params.item);
				break;

			case dm_restart_func:
				g_func_counts[dm_restart_func]++;
				work->result = _restart(work->restart_params.reason);
				break;

			default: /* should never happen */
				work->result = -1;
				break;
			}

			/* Inform the caller that work is done */
			px4_sem_post(&work->wait_sem);
		}

		/* time to go???? */
		if ((g_task_should_exit) && (g_fd < 0)) {
			break;
		}
	}

	close(g_task_fd);
	g_task_fd = -1;

	/* The work queue is now empty, empty the free queue */
	for (;;) {
		if ((work = (work_q_item_t *)sq_remfirst(&(g_free_q.q))) == NULL) {
			break;
		}

		if (work->first) {
			free(work);
		}
	}

	destroy_q(&g_work_q);
	destroy_q(&g_free_q);
	px4_sem_destroy(&g_work_queued_sema);
	px4_sem_destroy(&g_sys_state_mutex);

	return 0;
}
Exemplo n.º 23
0
int
ll40ls_main(int argc, char *argv[])
{
	int ch;
	int myoptind = 1;
	const char *myoptarg = nullptr;
	enum LL40LS_BUS busid = LL40LS_BUS_I2C_ALL;
	uint8_t rotation = distance_sensor_s::ROTATION_DOWNWARD_FACING;

	while ((ch = px4_getopt(argc, argv, "IXR:", &myoptind, &myoptarg)) != EOF) {
		switch (ch) {
#ifdef PX4_I2C_BUS_ONBOARD

		case 'I':
			busid = LL40LS_BUS_I2C_INTERNAL;
			break;
#endif

		case 'X':
			busid = LL40LS_BUS_I2C_EXTERNAL;
			break;

		case 'R':
			rotation = (uint8_t)atoi(myoptarg);
			PX4_INFO("Setting Lidar orientation to %d", (int)rotation);
			break;

		default:
			ll40ls::usage();
			return 0;
		}
	}

	/* Determine protocol first because it's needed next. */
	if (argc > myoptind + 1) {
		const char *protocol = argv[myoptind + 1];

		if (!strcmp(protocol, "pwm")) {
			busid = LL40LS_BUS_PWM;;

		} else if (!strcmp(protocol, "i2c")) {
			// Do nothing

		} else {
			warnx("unknown protocol, choose pwm or i2c");
			ll40ls::usage();
			return 0;
		}
	}

	/* Now determine action. */
	if (argc > myoptind) {
		const char *verb = argv[myoptind];

		if (!strcmp(verb, "start")) {
			ll40ls::start(busid, rotation);

		} else if (!strcmp(verb, "stop")) {
			ll40ls::stop();

		} else if (!strcmp(verb, "test")) {
			ll40ls::test();

		} else if (!strcmp(verb, "reset")) {
			ll40ls::reset();

		} else if (!strcmp(verb, "regdump")) {
			ll40ls::regdump();

		} else if (!strcmp(verb, "info") || !strcmp(verb, "status")) {
			ll40ls::info();

		} else {
			ll40ls::usage();
		}

		return 0;
	}

	warnx("unrecognized command, try 'start', 'test', 'reset', 'info' or 'regdump'");
	ll40ls::usage();
	return 0;
}
Exemplo n.º 24
0
static void
usage(void)
{
	PX4_INFO("usage: dataman {start [-f datafile]|stop|status|poweronrestart|inflightrestart}");
}
Exemplo n.º 25
0
/**
 * Perform some basic functional tests on the driver;
 * make sure we can collect data from the sensor in polled
 * and automatic modes.
 */
int
test()
{
	struct distance_sensor_s report;
	ssize_t sz;
	int ret;

	int fd = px4_open(SF1XX_DEVICE_PATH, O_RDONLY);

	if (fd < 0) {
		PX4_ERR("%s open failed (try 'sf1xx start' if the driver is not running)", SF1XX_DEVICE_PATH);
		return PX4_ERROR;
	}

	/* do a simple demand read */
	sz = read(fd, &report, sizeof(report));

	if (sz != sizeof(report)) {
		PX4_ERR("immediate read failed");
		return PX4_ERROR;
	}

	print_message(report);

	/* start the sensor polling at 2Hz */
	if (OK != ioctl(fd, SENSORIOCSPOLLRATE, 2)) {
		PX4_ERR("failed to set 2Hz poll rate");
		return PX4_ERROR;
	}

	/* read the sensor 5x and report each value */
	for (unsigned i = 0; i < 5; i++) {
		struct pollfd fds;

		/* wait for data to be ready */
		fds.fd = fd;
		fds.events = POLLIN;
		ret = poll(&fds, 1, 2000);

		if (ret != 1) {
			PX4_ERR("timed out waiting for sensor data");
			return PX4_ERROR;
		}

		/* now go get it */
		sz = read(fd, &report, sizeof(report));

		if (sz != sizeof(report)) {
			PX4_ERR("periodic read failed");
			return PX4_ERROR;
		}

		print_message(report);
	}

	/* reset the sensor polling to default rate */
	if (OK != ioctl(fd, SENSORIOCSPOLLRATE, SENSOR_POLLRATE_DEFAULT)) {
		PX4_ERR("failed to set default poll rate");
		return PX4_ERROR;
	}

	px4_close(fd);

	PX4_INFO("PASS");
	return PX4_OK;
}
Exemplo n.º 26
0
int
dataman_main(int argc, char *argv[])
{
	if (argc < 2) {
		usage();
		return -1;
	}

	if (!strcmp(argv[1], "start")) {

		if (g_fd >= 0) {
			PX4_WARN("dataman already running");
			return -1;
		}

		if (argc == 4 && strcmp(argv[2], "-f") == 0) {
			k_data_manager_device_path = strdup(argv[3]);
			PX4_INFO("dataman file set to: %s", k_data_manager_device_path);

		} else {
			k_data_manager_device_path = strdup(default_device_path);
		}

		start();

		if (g_fd < 0) {
			PX4_ERR("dataman start failed");
			free(k_data_manager_device_path);
			k_data_manager_device_path = NULL;
			return -1;
		}

		return 0;
	}

	/* Worker thread should be running for all other commands */
	if (g_fd < 0) {
		PX4_WARN("dataman worker thread not running");
		usage();
		return -1;
	}

	if (!strcmp(argv[1], "stop")) {
		stop();
		free(k_data_manager_device_path);
		k_data_manager_device_path = NULL;

	} else if (!strcmp(argv[1], "status")) {
		status();

	} else if (!strcmp(argv[1], "poweronrestart")) {
		dm_restart(DM_INIT_REASON_POWER_ON);

	} else if (!strcmp(argv[1], "inflightrestart")) {
		dm_restart(DM_INIT_REASON_IN_FLIGHT);

	} else {
		usage();
		return -1;
	}

	return 1;
}
Exemplo n.º 27
0
void Ekf2Replay::task_main()
{
	// formats
	const int _k_max_data_size = 1024;	// 16x16 bytes
	uint8_t data[_k_max_data_size] = {};
	const char param_file[] = "./rootfs/replay_params.txt";

	// Open log file from which we read data
	// TODO Check if file exists
	int fd = ::open(_file_name, O_RDONLY);

	// create path to write a replay file
	char *replay_log_name;
	replay_log_name = strtok(_file_name, ".");
	char tmp[] = "_replayed.px4log";
	char *path_to_replay_log = (char *) malloc(1 + strlen(tmp) + strlen(replay_log_name));
	strcpy(path_to_replay_log, ".");
	strcat(path_to_replay_log, replay_log_name);
	strcat(path_to_replay_log, tmp);

	// create path which tells user location of replay file
	char tmp2[] = "./build_posix_sitl_replay/src/firmware/posix";
	char *replay_file_location = (char *) malloc(1 + strlen(tmp) + strlen(tmp2) + strlen(replay_log_name));
	strcat(replay_file_location, tmp2);
	strcat(replay_file_location, replay_log_name);
	strcat(replay_file_location, tmp);

	// open logfile to write
	_write_fd = ::open(path_to_replay_log, O_WRONLY | O_CREAT, S_IRWXU);

	std::ifstream tmp_file;
	tmp_file.open(param_file);

	std::string line;
	bool set_default_params_in_file = false;

	if (tmp_file.is_open() && ! tmp_file.eof()) {
		getline(tmp_file, line);

		if (line.empty()) {
			// the parameter file is empty so write the default values to it
			set_default_params_in_file = true;
		}
	}

	tmp_file.close();

	std::ofstream myfile(param_file, std::ios::app);

	// subscribe to estimator topics
	_att_sub = orb_subscribe(ORB_ID(vehicle_attitude));
	_estimator_status_sub = orb_subscribe(ORB_ID(estimator_status));
	_innov_sub = orb_subscribe(ORB_ID(ekf2_innovations));
	_lpos_sub = orb_subscribe(ORB_ID(vehicle_local_position));
	_control_state_sub = orb_subscribe(ORB_ID(control_state));

	// we use attitude updates from the estimator for synchronisation
	_fds[0].fd = _att_sub;
	_fds[0].events = POLLIN;

	bool read_first_header = false;
	bool set_user_params = false;

	PX4_INFO("Replay in progress... \n");
	PX4_INFO("Log data will be written to %s\n", replay_file_location);

	while (!_task_should_exit) {
		_message_counter++;
		uint8_t header[3] = {};

		if (::read(fd, header, 3) != 3) {
			if (!read_first_header) {
				PX4_WARN("error reading log file, is the path printed above correct?");

			} else {
				PX4_INFO("Done!");
			}

			_task_should_exit = true;
			continue;
		}

		read_first_header = true;

		if ((header[0] != HEAD_BYTE1 || header[1] != HEAD_BYTE2)) {
			// we assume that the log file is finished here
			PX4_WARN("Done!");
			_task_should_exit = true;
			continue;
		}

		// write header but only for messages which are not generated by the estimator
		if (needToSaveMessage(header[2])) {
			writeMessage(_write_fd, &header[0], 3);
		}

		if (header[2] == LOG_FORMAT_MSG) {
			// format message
			struct log_format_s f;

			if (::read(fd, &f.type, sizeof(f)) != sizeof(f)) {
				PRINT_READ_ERROR;
				_task_should_exit = true;
				continue;
			}

			writeMessage(_write_fd, &f.type, sizeof(log_format_s));

			memcpy(&_formats[f.type], &f, sizeof(f));

		} else if (header[2] == LOG_PARM_MSG) {
			// parameter message
			if (::read(fd, &data[0], sizeof(log_PARM_s)) != sizeof(log_PARM_s)) {
				PRINT_READ_ERROR;
				_task_should_exit = true;
				continue;
			}

			writeMessage(_write_fd, &data[0], sizeof(log_PARM_s));

			// apply the parameters
			char param_name[16];

			for (unsigned i = 0; i < 16; i++) {
				param_name[i] = data[i];

				if (data[i] == '\0') {
					break;
				}
			}

			float param_data = 0;
			memcpy(&param_data, &data[16], sizeof(float));
			param_t handle = param_find(param_name);
			param_type_t param_format = param_type(handle);

			if (param_format == PARAM_TYPE_INT32) {
				int32_t value = 0;
				value = (int32_t)param_data;
				param_set(handle, (const void *)&value);

			} else if (param_format == PARAM_TYPE_FLOAT) {
				param_set(handle, (const void *)&param_data);
			}

			// if the user param file was empty then we fill it with the ekf2 parameter values from
			// the log file
			if (set_default_params_in_file) {
				if (strncmp(param_name, "EKF2", 4) == 0) {
					std::ostringstream os;
					double value = (double)param_data;
					os << std::string(param_name) << " ";
					os << value << "\n";
					myfile << os.str();
				}
			}

		} else if (header[2] == LOG_VER_MSG) {
			// version message
			if (::read(fd, &data[0], sizeof(log_VER_s)) != sizeof(log_VER_s)) {
				PRINT_READ_ERROR;
				_task_should_exit = true;
				continue;
			}

			writeMessage(_write_fd, &data[0], sizeof(log_VER_s));

		} else if (header[2] == LOG_TIME_MSG) {
			// time message
			if (::read(fd, &data[0], sizeof(log_TIME_s)) != sizeof(log_TIME_s)) {
				// assume that this is because we have reached the end of the file
				PX4_INFO("Done!");
				_task_should_exit = true;
				continue;
			}

			writeMessage(_write_fd, &data[0], sizeof(log_TIME_s));

		} else {
			// the first time we arrive here we should apply the parameters specified in the user file
			// this makes sure they are applied after the parameter values of the log file
			if (!set_user_params) {
				myfile.close();
				setUserParams(param_file);
				set_user_params = true;
			}

			// data message
			if (::read(fd, &data[0], _formats[header[2]].length - 3) != _formats[header[2]].length - 3) {
				PX4_INFO("Done!");
				_task_should_exit = true;
				continue;
			}

			// all messages which we are not getting from the estimator are written
			// back into the replay log file
			if (needToSaveMessage(header[2])) {
				writeMessage(_write_fd, &data[0], _formats[header[2]].length - 3);
			}

			if (header[2] == LOG_RPL1_MSG && _part1_counter_ref > 0) {
				// we have found another imu replay message while we still have one waiting to be published.
				// so publish that now
				publishAndWaitForEstimator();
			}

			// set estimator input data
			setEstimatorInput(&data[0], header[2]);

			// we have read the imu replay message (part 1) and have waited 3 more cycles for other replay message parts
			// e.g. flow, gps or range. we know that in case they were written to the log file they should come right after
			// the first replay message, therefore, we can kick the estimator now
			if (_part1_counter_ref > 0 && _part1_counter_ref < _message_counter - 3) {
				publishAndWaitForEstimator();
			}
		}
	}

	::close(_write_fd);
	::close(fd);
	delete ekf2_replay::instance;
	ekf2_replay::instance = nullptr;
}
Exemplo n.º 28
0
int
test_mount(int argc, char *argv[])
{
    const unsigned iterations = 2000;
    const unsigned alignments = 10;

    const char *cmd_filename = "/fs/microsd/mount_test_cmds.txt";


    /* check if microSD card is mounted */
    struct stat buffer;

    if (stat(PX4_ROOTFSDIR "/fs/microsd/", &buffer)) {
        PX4_ERR("no microSD card mounted, aborting file test");
        return 1;
    }

    /* list directory */
    DIR		*d;
    struct dirent	*dir;
    d = opendir(PX4_ROOTFSDIR "/fs/microsd");

    if (d) {

        while ((dir = readdir(d)) != NULL) {
            //printf("%s\n", dir->d_name);
        }

        closedir(d);

        PX4_INFO("directory listing ok (FS mounted and readable)");

    } else {
        /* failed opening dir */
        PX4_ERR("FAILED LISTING MICROSD ROOT DIRECTORY");

        if (stat(cmd_filename, &buffer) == OK) {
            (void)unlink(cmd_filename);
        }

        return 1;
    }

    /* read current test status from file, write test instructions for next round */

    /* initial values */
    int it_left_fsync = fsync_tries;
    int it_left_abort = abort_tries;

    int cmd_fd;

    if (stat(cmd_filename, &buffer) == OK) {

        /* command file exists, read off state */
        cmd_fd = open(cmd_filename, O_RDWR | O_NONBLOCK);
        char buf[64];
        int ret = read(cmd_fd, buf, sizeof(buf));

        if (ret > 0) {
            int count = 0;
            ret = sscanf(buf, "TEST: %u %u %n", &it_left_fsync, &it_left_abort, &count);

        } else {
            buf[0] = '\0';
        }

        if (it_left_fsync > fsync_tries) {
            it_left_fsync = fsync_tries;
        }

        if (it_left_abort > abort_tries) {
            it_left_abort = abort_tries;
        }

        PX4_INFO("Iterations left: #%d / #%d of %d / %d\n(%s)", it_left_fsync, it_left_abort,
                 fsync_tries, abort_tries, buf);

        int it_left_fsync_prev = it_left_fsync;

        /* now write again what to do next */
        if (it_left_fsync > 0) {
            it_left_fsync--;
        }

        if (it_left_fsync == 0 && it_left_abort > 0) {

            it_left_abort--;

            /* announce mode switch */
            if (it_left_fsync_prev != it_left_fsync && it_left_fsync == 0) {
                PX4_INFO("\n SUCCESSFULLY PASSED FSYNC'ED WRITES, CONTINUTING WITHOUT FSYNC");
                fsync(fileno(stdout));
                fsync(fileno(stderr));
                usleep(20000);
            }

        }

        if (it_left_abort == 0) {
            (void)unlink(cmd_filename);
            return 0;
        }

    } else {

        /* this must be the first iteration, do something */
        cmd_fd = open(cmd_filename, O_TRUNC | O_WRONLY | O_CREAT, PX4_O_MODE_666);

        PX4_INFO("First iteration of file test\n");
    }

    char buf[64];
    (void)sprintf(buf, "TEST: %d %d ", it_left_fsync, it_left_abort);
    lseek(cmd_fd, 0, SEEK_SET);
    write(cmd_fd, buf, strlen(buf) + 1);
    fsync(cmd_fd);

    /* perform tests for a range of chunk sizes */
    unsigned chunk_sizes[] = {32, 64, 128, 256, 512, 600, 1200};

    for (unsigned c = 0; c < (sizeof(chunk_sizes) / sizeof(chunk_sizes[0])); c++) {

        printf("\n\n====== FILE TEST: %u bytes chunks (%s) ======\n", chunk_sizes[c],
               (it_left_fsync > 0) ? "FSYNC" : "NO FSYNC");
        printf("unpower the system immediately (within 0.5s) when the hash (#) sign appears\n");
        fsync(fileno(stdout));
        fsync(fileno(stderr));
        usleep(50000);

        for (unsigned a = 0; a < alignments; a++) {

            printf(".");

            uint8_t write_buf[chunk_sizes[c] + alignments] __attribute__((aligned(64)));

            /* fill write buffer with known values */
            for (unsigned i = 0; i < sizeof(write_buf); i++) {
                /* this will wrap, but we just need a known value with spacing */
                write_buf[i] = i + 11;
            }

            uint8_t read_buf[chunk_sizes[c] + alignments] __attribute__((aligned(64)));

            int fd = px4_open(PX4_ROOTFSDIR "/fs/microsd/testfile", O_TRUNC | O_WRONLY | O_CREAT);

            for (unsigned i = 0; i < iterations; i++) {

                int wret = write(fd, write_buf + a, chunk_sizes[c]);

                if (wret != (int)chunk_sizes[c]) {
                    PX4_ERR("WRITE ERROR!");

                    if ((0x3 & (uintptr_t)(write_buf + a))) {
                        PX4_ERR("memory is unaligned, align shift: %d", a);
                    }

                    return 1;

                }

                if (it_left_fsync > 0) {
                    fsync(fd);

                } else {
                    printf("#");
                    fsync(fileno(stdout));
                    fsync(fileno(stderr));
                }
            }

            if (it_left_fsync > 0) {
                printf("#");
            }

            printf(".");
            fsync(fileno(stdout));
            fsync(fileno(stderr));
            usleep(200000);

            px4_close(fd);
            fd = px4_open(PX4_ROOTFSDIR "/fs/microsd/testfile", O_RDONLY);

            /* read back data for validation */
            for (unsigned i = 0; i < iterations; i++) {
                int rret = read(fd, read_buf, chunk_sizes[c]);

                if (rret != (int)chunk_sizes[c]) {
                    PX4_ERR("READ ERROR!");
                    return 1;
                }

                /* compare value */
                bool compare_ok = true;

                for (unsigned j = 0; j < chunk_sizes[c]; j++) {
                    if (read_buf[j] != write_buf[j + a]) {
                        PX4_WARN("COMPARISON ERROR: byte %d, align shift: %d", j, a);
                        compare_ok = false;
                        break;
                    }
                }

                if (!compare_ok) {
                    PX4_ERR("ABORTING FURTHER COMPARISON DUE TO ERROR");
                    return 1;
                }

            }

            int ret = unlink(PX4_ROOTFSDIR "/fs/microsd/testfile");
            px4_close(fd);

            if (ret) {
                px4_close(cmd_fd);
                PX4_ERR("UNLINKING FILE FAILED");
                return 1;
            }

        }
    }

    fsync(fileno(stdout));
    fsync(fileno(stderr));
    usleep(20000);

    px4_close(cmd_fd);

    /* we always reboot for the next test if we get here */
    PX4_INFO("Iteration done, rebooting..");
    fsync(fileno(stdout));
    fsync(fileno(stderr));
    usleep(50000);
    px4_systemreset(false);

    /* never going to get here */
    return 0;
}
Exemplo n.º 29
0
int
ist8310_main(int argc, char *argv[])
{
	IST8310_BUS i2c_busid = IST8310_BUS_ALL;
	int i2c_addr = IST8310_BUS_I2C_ADDR; /* 7bit */

	enum Rotation rotation = ROTATION_NONE;
	bool calibrate = false;
	int myoptind = 1;
	int ch;
	const char *myoptarg = nullptr;

	while ((ch = px4_getopt(argc, argv, "R:Ca:b:", &myoptind, &myoptarg)) != EOF) {
		switch (ch) {
		case 'R':
			rotation = (enum Rotation)atoi(myoptarg);
			break;

		case 'a':
			i2c_addr = (int)strtol(myoptarg, NULL, 0);
			break;

		case 'b':
			i2c_busid = (IST8310_BUS)strtol(myoptarg, NULL, 0);
			break;

		case 'C':
			calibrate = true;
			break;

		default:
			ist8310::usage();
			exit(0);
		}
	}

	if (myoptind >= argc) {
		ist8310::usage();
		return 1;
	}

	const char *verb = argv[myoptind];

	/*
	 * Start/load the driver.
	 */
	if (!strcmp(verb, "start")) {
		ist8310::start(i2c_busid, i2c_addr, rotation);

		if (i2c_busid == IST8310_BUS_ALL) {
			PX4_ERR("calibration only feasible against one bus");
			return 1;

		} else if (calibrate && (ist8310::calibrate(i2c_busid) != 0)) {
			PX4_ERR("calibration failed");
			return 1;
		}

		return 0;
	}

	/*
	 * Test the driver/device.
	 */
	if (!strcmp(verb, "test")) {
		ist8310::test(i2c_busid);
	}

	/*
	 * Reset the driver.
	 */
	if (!strcmp(verb, "reset")) {
		ist8310::reset(i2c_busid);
	}

	/*
	 * Print driver information.
	 */
	if (!strcmp(verb, "info") || !strcmp(verb, "status")) {
		ist8310::info(i2c_busid);
	}

	/*
	 * Autocalibrate the scaling
	 */
	if (!strcmp(verb, "calibrate")) {
		if (ist8310::calibrate(i2c_busid) == 0) {
			PX4_INFO("calibration successful");
			return 0;

		} else {
			PX4_ERR("calibration failed");
			return 1;
		}
	}

	ist8310::usage();
	return 1;
}
Exemplo n.º 30
0
static int
do_accel(int argc, char *argv[])
{
	int	fd;

	fd = open(argv[1], 0);

	if (fd < 0) {
		PX4_ERR("open %s failed (%i)", argv[1], errno);
		return 1;

	} else {

		int ret;

		if (argc == 3 && !strcmp(argv[0], "sampling")) {

			/* set the accel internal sampling rate up to at least i Hz */
			ret = ioctl(fd, ACCELIOCSSAMPLERATE, strtoul(argv[2], NULL, 0));

			if (ret) {
				PX4_ERR("sampling rate could not be set");
				return 1;
			}

		} else if (argc == 3 && !strcmp(argv[0], "rate")) {

			/* set the driver to poll at i Hz */
			ret = ioctl(fd, SENSORIOCSPOLLRATE, strtoul(argv[2], NULL, 0));

			if (ret) {
				PX4_ERR("pollrate could not be set");
				return 1;
			}

		} else if (argc == 3 && !strcmp(argv[0], "range")) {

			/* set the range to i G */
			ret = ioctl(fd, ACCELIOCSRANGE, strtoul(argv[2], NULL, 0));

			if (ret) {
				PX4_ERR("range could not be set");
				return 1;
			}

		} else {
			print_usage();
			return 1;
		}

		int srate = ioctl(fd, ACCELIOCGSAMPLERATE, 0);
		int prate = ioctl(fd, SENSORIOCGPOLLRATE, 0);
		int range = ioctl(fd, ACCELIOCGRANGE, 0);
		int id = ioctl(fd, DEVIOCGDEVICEID, 0);
		int32_t calibration_id = 0;

		param_get(param_find("CAL_ACC0_ID"), &(calibration_id));

		PX4_INFO("accel: \n\tdevice id:\t0x%X\t(calibration is for device id 0x%X)\n\tsample rate:\t%d Hz\n\tread rate:\t%d Hz\n\trange:\t%d G",
			 id, calibration_id, srate, prate, range);

		close(fd);
	}

	return 0;
}