mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-06-27 18:10:34 +08:00
Merge branch 'master' into ekf_voting
This commit is contained in:
@@ -1220,13 +1220,17 @@ int commander_thread_main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Run preflight check
|
||||
int32_t rc_in_off = 0;
|
||||
param_get(_param_autostart_id, &autostart_id);
|
||||
if (is_hil_setup(autostart_id)) {
|
||||
// HIL configuration selected: real sensors will be disabled
|
||||
status.condition_system_sensors_initialized = false;
|
||||
set_tune_override(TONE_STARTUP_TUNE); //normal boot tune
|
||||
} else {
|
||||
status.condition_system_sensors_initialized = Commander::preflightCheck(mavlink_fd, true, true, true, true, checkAirspeed, !status.rc_input_mode, !status.circuit_breaker_engaged_gpsfailure_check);
|
||||
param_get(_param_rc_in_off, &rc_in_off);
|
||||
status.rc_input_mode = rc_in_off;
|
||||
status.condition_system_sensors_initialized = Commander::preflightCheck(mavlink_fd, true, true, true, true,
|
||||
checkAirspeed, (status.rc_input_mode == vehicle_status_s::RC_IN_MODE_DEFAULT), !status.circuit_breaker_engaged_gpsfailure_check);
|
||||
if (!status.condition_system_sensors_initialized) {
|
||||
set_tune_override(TONE_GPS_WARNING_TUNE); //sensor fail tune
|
||||
}
|
||||
@@ -1242,7 +1246,6 @@ int commander_thread_main(int argc, char *argv[])
|
||||
int32_t datalink_loss_enabled = false;
|
||||
int32_t datalink_loss_timeout = 10;
|
||||
float rc_loss_timeout = 0.5;
|
||||
int32_t rc_in_off = 0;
|
||||
int32_t datalink_regain_timeout = 0;
|
||||
|
||||
/* Thresholds for engine failure detection */
|
||||
@@ -1863,17 +1866,16 @@ int commander_thread_main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* RC input check */
|
||||
if (!(status.rc_input_mode == vehicle_status_s::RC_IN_MODE_OFF) && !status.rc_input_blocked && sp_man.timestamp != 0 &&
|
||||
hrt_absolute_time() < sp_man.timestamp + (uint64_t)(rc_loss_timeout * 1e6f)) {
|
||||
if (!status.rc_input_blocked && sp_man.timestamp != 0 &&
|
||||
(hrt_absolute_time() < sp_man.timestamp + (uint64_t)(rc_loss_timeout * 1e6f))) {
|
||||
/* handle the case where RC signal was regained */
|
||||
if (!status.rc_signal_found_once) {
|
||||
status.rc_signal_found_once = true;
|
||||
mavlink_log_info(mavlink_fd, "Detected radio control");
|
||||
status_changed = true;
|
||||
|
||||
} else {
|
||||
if (status.rc_signal_lost) {
|
||||
mavlink_log_info(mavlink_fd, "RC SIGNAL REGAINED after %llums",
|
||||
mavlink_log_info(mavlink_fd, "MANUAL CONTROL REGAINED after %llums",
|
||||
(hrt_absolute_time() - status.rc_signal_lost_timestamp) / 1000);
|
||||
status_changed = true;
|
||||
}
|
||||
@@ -1913,8 +1915,7 @@ int commander_thread_main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* check if left stick is in lower right position and we're in MANUAL mode -> arm */
|
||||
if (status.arming_state == vehicle_status_s::ARMING_STATE_STANDBY &&
|
||||
sp_man.r > STICK_ON_OFF_LIMIT && sp_man.z < 0.1f) {
|
||||
if (sp_man.r > STICK_ON_OFF_LIMIT && sp_man.z < 0.1f) {
|
||||
if (stick_on_counter > STICK_ON_OFF_COUNTER_LIMIT) {
|
||||
|
||||
/* we check outside of the transition function here because the requirement
|
||||
@@ -1925,13 +1926,15 @@ int commander_thread_main(int argc, char *argv[])
|
||||
(status.main_state != vehicle_status_s::MAIN_STATE_STAB)) {
|
||||
print_reject_arm("NOT ARMING: Switch to MANUAL mode first.");
|
||||
|
||||
} else {
|
||||
} else if (status.arming_state == vehicle_status_s::ARMING_STATE_STANDBY) {
|
||||
arming_ret = arming_state_transition(&status, &safety, vehicle_status_s::ARMING_STATE_ARMED, &armed, true /* fRunPreArmChecks */,
|
||||
mavlink_fd);
|
||||
|
||||
if (arming_ret == TRANSITION_CHANGED) {
|
||||
arming_state_changed = true;
|
||||
}
|
||||
} else {
|
||||
print_reject_arm("NOT ARMING: Configuration error");
|
||||
}
|
||||
|
||||
stick_on_counter = 0;
|
||||
@@ -1978,8 +1981,8 @@ int commander_thread_main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!status.rc_signal_lost) {
|
||||
mavlink_log_critical(mavlink_fd, "RC SIGNAL LOST (at t=%llums)", hrt_absolute_time() / 1000);
|
||||
if (!status.rc_input_blocked && !status.rc_signal_lost) {
|
||||
mavlink_log_critical(mavlink_fd, "MANUAL CONTROL LOST (at t=%llums)", hrt_absolute_time() / 1000);
|
||||
status.rc_signal_lost = true;
|
||||
status.rc_signal_lost_timestamp = sp_man.timestamp;
|
||||
status_changed = true;
|
||||
|
||||
@@ -245,9 +245,7 @@ arming_state_transition(struct vehicle_status_s *status, ///< current vehicle s
|
||||
(new_arming_state == vehicle_status_s::ARMING_STATE_STANDBY) &&
|
||||
(status->arming_state != vehicle_status_s::ARMING_STATE_STANDBY_ERROR) &&
|
||||
(!status->condition_system_sensors_initialized)) {
|
||||
if (!fRunPreArmChecks) {
|
||||
mavlink_and_console_log_critical(mavlink_fd, "Not ready to fly: Sensors need inspection");
|
||||
}
|
||||
mavlink_and_console_log_critical(mavlink_fd, "Not ready to fly: Sensors need inspection");
|
||||
feedback_provided = true;
|
||||
valid_transition = false;
|
||||
status->arming_state = vehicle_status_s::ARMING_STATE_STANDBY_ERROR;
|
||||
|
||||
@@ -214,23 +214,23 @@ PARAM_DEFINE_FLOAT(PE_ACC_PNOISE, 0.25f);
|
||||
* Generic defaults: 1e-07f, multicopters: 1e-07f, ground vehicles: 1e-07f.
|
||||
* Increasing this value will make the gyro bias converge faster but noisier.
|
||||
*
|
||||
* @min 0.0000001
|
||||
* @min 0.00000005
|
||||
* @max 0.00001
|
||||
* @group Position Estimator
|
||||
*/
|
||||
PARAM_DEFINE_FLOAT(PE_GBIAS_PNOISE, 1e-06f);
|
||||
PARAM_DEFINE_FLOAT(PE_GBIAS_PNOISE, 1e-07f);
|
||||
|
||||
/**
|
||||
* Accelerometer bias estimate process noise
|
||||
*
|
||||
* Generic defaults: 0.0001f, multicopters: 0.0001f, ground vehicles: 0.0001f.
|
||||
* Generic defaults: 0.00001f, multicopters: 0.00001f, ground vehicles: 0.00001f.
|
||||
* Increasing this value makes the bias estimation faster and noisier.
|
||||
*
|
||||
* @min 0.00001
|
||||
* @max 0.001
|
||||
* @group Position Estimator
|
||||
*/
|
||||
PARAM_DEFINE_FLOAT(PE_ABIAS_PNOISE, 0.0002f);
|
||||
PARAM_DEFINE_FLOAT(PE_ABIAS_PNOISE, 1e-05f);
|
||||
|
||||
/**
|
||||
* Magnetometer earth frame offsets process noise
|
||||
|
||||
@@ -648,8 +648,8 @@ FixedwingAttitudeControl::task_main()
|
||||
vehicle_manual_poll();
|
||||
vehicle_status_poll();
|
||||
|
||||
/* wakeup source(s) */
|
||||
struct pollfd fds[2];
|
||||
/* wakeup source */
|
||||
px4_pollfd_struct_t fds[2];
|
||||
|
||||
/* Setup of loop */
|
||||
fds[0].fd = _params_sub;
|
||||
@@ -660,11 +660,10 @@ FixedwingAttitudeControl::task_main()
|
||||
_task_running = true;
|
||||
|
||||
while (!_task_should_exit) {
|
||||
|
||||
static int loop_counter = 0;
|
||||
|
||||
/* wait for up to 500ms for data */
|
||||
int pret = poll(&fds[0], (sizeof(fds) / sizeof(fds[0])), 100);
|
||||
int pret = px4_poll(&fds[0], (sizeof(fds) / sizeof(fds[0])), 100);
|
||||
|
||||
/* timed out - periodic check for _task_should_exit, etc. */
|
||||
if (pret == 0) {
|
||||
@@ -691,7 +690,6 @@ FixedwingAttitudeControl::task_main()
|
||||
|
||||
/* only run controller if attitude changed */
|
||||
if (fds[1].revents & POLLIN) {
|
||||
|
||||
static uint64_t last_run = 0;
|
||||
float deltaT = (hrt_absolute_time() - last_run) / 1000000.0f;
|
||||
last_run = hrt_absolute_time();
|
||||
@@ -703,6 +701,7 @@ FixedwingAttitudeControl::task_main()
|
||||
/* load local copies */
|
||||
orb_copy(ORB_ID(vehicle_attitude), _att_sub, &_att);
|
||||
|
||||
|
||||
if (_vehicle_status.is_vtol && _parameters.vtol_type == 0) {
|
||||
/* vehicle is a tailsitter, we need to modify the estimated attitude for fw mode
|
||||
*
|
||||
|
||||
@@ -1719,7 +1719,7 @@ FixedwingPositionControl::task_main()
|
||||
}
|
||||
|
||||
/* wakeup source(s) */
|
||||
struct pollfd fds[2];
|
||||
px4_pollfd_struct_t fds[2];
|
||||
|
||||
/* Setup of loop */
|
||||
fds[0].fd = _params_sub;
|
||||
@@ -1732,7 +1732,7 @@ FixedwingPositionControl::task_main()
|
||||
while (!_task_should_exit) {
|
||||
|
||||
/* wait for up to 500ms for data */
|
||||
int pret = poll(&fds[0], (sizeof(fds) / sizeof(fds[0])), 100);
|
||||
int pret = px4_poll(&fds[0], (sizeof(fds) / sizeof(fds[0])), 100);
|
||||
|
||||
/* timed out - periodic check for _task_should_exit, etc. */
|
||||
if (pret == 0) {
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
#endif
|
||||
static const int ERROR = -1;
|
||||
|
||||
#define DEFAULT_REMOTE_PORT_UDP 14550 ///< GCS port per MAVLink spec
|
||||
#define DEFAULT_DEVICE_NAME "/dev/ttyS1"
|
||||
#define MAX_DATA_RATE 10000000 ///< max data rate in bytes/s
|
||||
#define MAIN_LOOP_DELAY 10000 ///< 100 Hz @ 1000 bytes/s data rate
|
||||
@@ -153,7 +154,6 @@ Mavlink::Mavlink() :
|
||||
_receive_thread {},
|
||||
_verbose(false),
|
||||
_forwarding_on(false),
|
||||
_passing_on(false),
|
||||
_ftp_on(false),
|
||||
#ifndef __PX4_POSIX
|
||||
_uart_fd(-1),
|
||||
@@ -885,6 +885,7 @@ Mavlink::send_message(const uint8_t msgid, const void *msg, uint8_t component_ID
|
||||
ret = sendto(_socket_fd, buf, packet_len, 0, (struct sockaddr *)&_src_addr, sizeof(_src_addr));
|
||||
} else if (get_protocol() == TCP) {
|
||||
// not implemented, but possible to do so
|
||||
warnx("TCP transport pending implementation");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -974,11 +975,12 @@ Mavlink::init_udp()
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char inbuf[256];
|
||||
socklen_t addrlen = sizeof(_src_addr);
|
||||
// set default target address
|
||||
memset((char *)&_src_addr, 0, sizeof(_src_addr));
|
||||
_src_addr.sin_family = AF_INET;
|
||||
inet_aton("127.0.0.1", &_src_addr.sin_addr);
|
||||
_src_addr.sin_port = htons(DEFAULT_REMOTE_PORT_UDP);
|
||||
|
||||
// wait for client to connect to socket
|
||||
recvfrom(_socket_fd,inbuf,sizeof(inbuf),0,(struct sockaddr *)&_src_addr,&addrlen);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1319,7 +1321,7 @@ Mavlink::message_buffer_mark_read(int n)
|
||||
void
|
||||
Mavlink::pass_message(const mavlink_message_t *msg)
|
||||
{
|
||||
if (_passing_on) {
|
||||
if (_forwarding_on) {
|
||||
/* size is 8 bytes plus variable payload */
|
||||
int size = MAVLINK_NUM_NON_PAYLOAD_BYTES + msg->len;
|
||||
pthread_mutex_lock(&_message_buffer_mutex);
|
||||
@@ -1494,10 +1496,6 @@ Mavlink::task_main(int argc, char *argv[])
|
||||
_forwarding_on = true;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
_passing_on = true;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
_verbose = true;
|
||||
break;
|
||||
@@ -1543,11 +1541,6 @@ Mavlink::task_main(int argc, char *argv[])
|
||||
/* flush stdout in case MAVLink is about to take it over */
|
||||
fflush(stdout);
|
||||
|
||||
/* init socket if necessary */
|
||||
if (get_protocol() == UDP) {
|
||||
init_udp();
|
||||
}
|
||||
|
||||
#ifndef __PX4_POSIX
|
||||
struct termios uart_config_original;
|
||||
|
||||
@@ -1568,7 +1561,7 @@ Mavlink::task_main(int argc, char *argv[])
|
||||
mavlink_logbuffer_init(&_logbuffer, 5);
|
||||
|
||||
/* if we are passing on mavlink messages, we need to prepare a buffer for this instance */
|
||||
if (_passing_on || _ftp_on) {
|
||||
if (_forwarding_on || _ftp_on) {
|
||||
/* initialize message buffer if multiplexing is on or its needed for FTP.
|
||||
* make space for two messages plus off-by-one space as we use the empty element
|
||||
* marker ring buffer approach.
|
||||
@@ -1724,6 +1717,11 @@ Mavlink::task_main(int argc, char *argv[])
|
||||
/* now the instance is fully initialized and we can bump the instance count */
|
||||
LL_APPEND(_mavlink_instances, this);
|
||||
|
||||
/* init socket if necessary */
|
||||
if (get_protocol() == UDP) {
|
||||
init_udp();
|
||||
}
|
||||
|
||||
/* if the protocol is serial, we send the system version blindly */
|
||||
if (get_protocol() == SERIAL) {
|
||||
send_autopilot_capabilites();
|
||||
@@ -1835,7 +1833,7 @@ Mavlink::task_main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* pass messages from other UARTs or FTP worker */
|
||||
if (_passing_on || _ftp_on) {
|
||||
if (_forwarding_on || _ftp_on) {
|
||||
|
||||
bool is_part;
|
||||
uint8_t *read_ptr;
|
||||
@@ -1944,7 +1942,7 @@ Mavlink::task_main(int argc, char *argv[])
|
||||
/* close mavlink logging device */
|
||||
px4_close(_mavlink_fd);
|
||||
|
||||
if (_passing_on || _ftp_on) {
|
||||
if (_forwarding_on || _ftp_on) {
|
||||
message_buffer_destroy();
|
||||
pthread_mutex_destroy(&_message_buffer_mutex);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <drivers/device/device.h>
|
||||
#endif
|
||||
#include <systemlib/param/param.h>
|
||||
@@ -333,7 +334,9 @@ public:
|
||||
unsigned short get_network_port() { return _network_port; }
|
||||
|
||||
int get_socket_fd () { return _socket_fd; };
|
||||
|
||||
#ifdef __PX4_POSIX
|
||||
struct sockaddr_in * get_client_source_address() {return &_src_addr;};
|
||||
#endif
|
||||
static bool boot_complete() { return _boot_complete; }
|
||||
|
||||
protected:
|
||||
@@ -376,7 +379,6 @@ private:
|
||||
|
||||
bool _verbose;
|
||||
bool _forwarding_on;
|
||||
bool _passing_on;
|
||||
bool _ftp_on;
|
||||
#ifndef __PX4_QURT
|
||||
int _uart_fd;
|
||||
|
||||
@@ -2057,7 +2057,14 @@ protected:
|
||||
msg.y = manual.y * 1000;
|
||||
msg.z = manual.z * 1000;
|
||||
msg.r = manual.r * 1000;
|
||||
unsigned shift = 2;
|
||||
msg.buttons = 0;
|
||||
msg.buttons |= (manual.mode_switch << (shift * 0));
|
||||
msg.buttons |= (manual.return_switch << (shift * 1));
|
||||
msg.buttons |= (manual.posctl_switch << (shift * 2));
|
||||
msg.buttons |= (manual.loiter_switch << (shift * 3));
|
||||
msg.buttons |= (manual.acro_switch << (shift * 4));
|
||||
msg.buttons |= (manual.offboard_switch << (shift * 5));
|
||||
|
||||
_mavlink->send_message(MAVLINK_MSG_ID_MANUAL_CONTROL, &msg);
|
||||
}
|
||||
|
||||
@@ -479,8 +479,6 @@ MavlinkMissionManager::handle_mission_request_list(const mavlink_message_t *msg)
|
||||
|
||||
} else {
|
||||
if (_verbose) { warnx("WPM: MISSION_REQUEST_LIST OK nothing to send, mission is empty"); }
|
||||
|
||||
_mavlink->send_statustext_info("WPM: mission is empty");
|
||||
}
|
||||
|
||||
send_mission_count(msg->sysid, msg->compid, _count);
|
||||
|
||||
@@ -990,8 +990,8 @@ MavlinkReceiver::handle_message_radio_status(mavlink_message_t *msg)
|
||||
switch_pos_t
|
||||
MavlinkReceiver::decode_switch_pos(uint16_t buttons, unsigned sw)
|
||||
{
|
||||
// XXX non-standard 3 pos switch decoding
|
||||
return (buttons >> (sw * 2)) & 3;
|
||||
// This 2-bit method should be used in the future: (buttons >> (sw * 2)) & 3;
|
||||
return (buttons & (1 << sw)) ? manual_control_setpoint_s::SWITCH_POS_ON : manual_control_setpoint_s::SWITCH_POS_OFF;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1101,26 +1101,10 @@ MavlinkReceiver::handle_message_manual_control(mavlink_message_t *msg)
|
||||
rc.values[0] = man.x / 2 + 1500;
|
||||
/* pitch */
|
||||
rc.values[1] = man.y / 2 + 1500;
|
||||
|
||||
/*
|
||||
* yaw needs special handling as some joysticks have a circular mechanical mask,
|
||||
* which makes the corner positions unreachable.
|
||||
* scale yaw up and clip it to overcome this.
|
||||
*/
|
||||
rc.values[2] = man.r / 1.1f + 1500;
|
||||
if (rc.values[2] > 2000) {
|
||||
rc.values[2] = 2000;
|
||||
} else if (rc.values[2] < 1000) {
|
||||
rc.values[2] = 1000;
|
||||
}
|
||||
|
||||
/* yaw */
|
||||
rc.values[2] = man.r / 2 + 1500;
|
||||
/* throttle */
|
||||
rc.values[3] = man.z / 0.9f + 1000;
|
||||
if (rc.values[3] > 2000) {
|
||||
rc.values[3] = 2000;
|
||||
} else if (rc.values[3] < 1000) {
|
||||
rc.values[3] = 1000;
|
||||
}
|
||||
rc.values[3] = man.z / 1 + 1000;
|
||||
|
||||
/* decode all switches which fit into the channel mask */
|
||||
unsigned max_switch = (sizeof(man.buttons) * 8);
|
||||
@@ -1762,10 +1746,17 @@ MavlinkReceiver::receive_thread(void *arg)
|
||||
#ifdef __PX4_POSIX
|
||||
struct sockaddr_in srcaddr;
|
||||
socklen_t addrlen = sizeof(srcaddr);
|
||||
|
||||
if (_mavlink->get_protocol() == UDP || _mavlink->get_protocol() == TCP) {
|
||||
// make sure mavlink app has booted before we start using the socket
|
||||
while (!_mavlink->boot_complete()) {
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
fds[0].fd = _mavlink->get_socket_fd();
|
||||
fds[0].events = POLLIN;
|
||||
}
|
||||
|
||||
#endif
|
||||
ssize_t nread = 0;
|
||||
|
||||
@@ -1780,13 +1771,19 @@ MavlinkReceiver::receive_thread(void *arg)
|
||||
}
|
||||
#ifdef __PX4_POSIX
|
||||
if (_mavlink->get_protocol() == UDP) {
|
||||
|
||||
if (fds[0].revents & POLLIN) {
|
||||
nread = recvfrom(_mavlink->get_socket_fd(), buf, sizeof(buf), 0, (struct sockaddr *)&srcaddr, &addrlen);
|
||||
}
|
||||
} else {
|
||||
// could be TCP or other protocol
|
||||
}
|
||||
|
||||
struct sockaddr_in * srcaddr_last = _mavlink->get_client_source_address();
|
||||
int localhost = (127 << 24) + 1;
|
||||
if (srcaddr_last->sin_addr.s_addr == htonl(localhost) && srcaddr.sin_addr.s_addr != htonl(localhost)) {
|
||||
// if we were sending to localhost before but have a new host then accept him
|
||||
memcpy(srcaddr_last, &srcaddr, sizeof(srcaddr));
|
||||
}
|
||||
#endif
|
||||
/* if read failed, this loop won't execute */
|
||||
for (ssize_t i = 0; i < nread; i++) {
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
* Parameters for multicopter attitude controller.
|
||||
*
|
||||
* @author Tobias Naegeli <naegelit@student.ethz.ch>
|
||||
* @author Lorenz Meier <lm@inf.ethz.ch>
|
||||
* @author Anton Babushkin <anton.babushkin@me.com>
|
||||
* @author Lorenz Meier <lorenz@px4.io>
|
||||
* @author Anton Babushkin <anton@px4.io>
|
||||
*/
|
||||
|
||||
#include <systemlib/param/param.h>
|
||||
@@ -60,7 +60,7 @@ PARAM_DEFINE_FLOAT(MC_ROLL_P, 6.5f);
|
||||
* @min 0.0
|
||||
* @group Multicopter Attitude Control
|
||||
*/
|
||||
PARAM_DEFINE_FLOAT(MC_ROLLRATE_P, 0.12f);
|
||||
PARAM_DEFINE_FLOAT(MC_ROLLRATE_P, 0.15f);
|
||||
|
||||
/**
|
||||
* Roll rate I gain
|
||||
@@ -111,7 +111,7 @@ PARAM_DEFINE_FLOAT(MC_PITCH_P, 6.5f);
|
||||
* @min 0.0
|
||||
* @group Multicopter Attitude Control
|
||||
*/
|
||||
PARAM_DEFINE_FLOAT(MC_PITCHRATE_P, 0.12f);
|
||||
PARAM_DEFINE_FLOAT(MC_PITCHRATE_P, 0.15f);
|
||||
|
||||
/**
|
||||
* Pitch rate I gain
|
||||
|
||||
@@ -1272,13 +1272,16 @@ int sdlog2_thread_main(int argc, char *argv[])
|
||||
|
||||
subs.sat_info_sub = -1;
|
||||
|
||||
/* close non-needed fd's */
|
||||
#ifdef __PX4_NUTTX
|
||||
/* close non-needed fd's. We cannot do this for posix since the file
|
||||
descriptors will also be closed for the parent process
|
||||
*/
|
||||
|
||||
/* close stdin */
|
||||
close(0);
|
||||
/* close stdout */
|
||||
close(1);
|
||||
|
||||
#endif
|
||||
/* initialize thread synchronization */
|
||||
pthread_mutex_init(&logbuffer_mutex, NULL);
|
||||
pthread_cond_init(&logbuffer_cond, NULL);
|
||||
|
||||
@@ -86,6 +86,11 @@ bool Simulator::getGPSSample(uint8_t *buf, int len)
|
||||
return _gps.copyData(buf, len);
|
||||
}
|
||||
|
||||
bool Simulator::getAirspeedSample(uint8_t *buf, int len)
|
||||
{
|
||||
return _airspeed.copyData(buf, len);
|
||||
}
|
||||
|
||||
void Simulator::write_MPU_data(void *buf) {
|
||||
_mpu.writeData(buf);
|
||||
}
|
||||
@@ -106,6 +111,10 @@ void Simulator::write_gps_data(void *buf) {
|
||||
_gps.writeData(buf);
|
||||
}
|
||||
|
||||
void Simulator::write_airspeed_data(void *buf) {
|
||||
_airspeed.writeData(buf);
|
||||
}
|
||||
|
||||
int Simulator::start(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <uORB/topics/manual_control_setpoint.h>
|
||||
#include <uORB/topics/actuator_outputs.h>
|
||||
#include <uORB/topics/vehicle_attitude.h>
|
||||
#include <uORB/topics/vehicle_status.h>
|
||||
#include <drivers/drv_accel.h>
|
||||
#include <drivers/drv_gyro.h>
|
||||
#include <drivers/drv_baro.h>
|
||||
@@ -93,6 +94,13 @@ struct RawBaroData {
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct RawAirspeedData {
|
||||
float temperature;
|
||||
float diff_pressure;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct RawGPSData {
|
||||
int32_t lat;
|
||||
@@ -190,12 +198,14 @@ public:
|
||||
bool getMPUReport(uint8_t *buf, int len);
|
||||
bool getBaroSample(uint8_t *buf, int len);
|
||||
bool getGPSSample(uint8_t *buf, int len);
|
||||
bool getAirspeedSample(uint8_t *buf, int len);
|
||||
|
||||
void write_MPU_data(void *buf);
|
||||
void write_accel_data(void *buf);
|
||||
void write_mag_data(void *buf);
|
||||
void write_baro_data(void *buf);
|
||||
void write_gps_data(void *buf);
|
||||
void write_airspeed_data(void *buf);
|
||||
|
||||
bool isInitialized() { return _initialized; }
|
||||
|
||||
@@ -206,6 +216,7 @@ private:
|
||||
_baro(1),
|
||||
_mag(1),
|
||||
_gps(1),
|
||||
_airspeed(1),
|
||||
_accel_pub(nullptr),
|
||||
_baro_pub(nullptr),
|
||||
_gyro_pub(nullptr),
|
||||
@@ -217,10 +228,12 @@ private:
|
||||
_actuator_outputs_sub(-1),
|
||||
_vehicle_attitude_sub(-1),
|
||||
_manual_sub(-1),
|
||||
_vehicle_status_sub(-1),
|
||||
_rc_input{},
|
||||
_actuators{},
|
||||
_attitude{},
|
||||
_manual{}
|
||||
_manual{},
|
||||
_vehicle_status{}
|
||||
#endif
|
||||
{}
|
||||
~Simulator() { _instance=NULL; }
|
||||
@@ -235,6 +248,7 @@ private:
|
||||
simulator::Report<simulator::RawBaroData> _baro;
|
||||
simulator::Report<simulator::RawMagData> _mag;
|
||||
simulator::Report<simulator::RawGPSData> _gps;
|
||||
simulator::Report<simulator::RawAirspeedData> _airspeed;
|
||||
|
||||
// uORB publisher handlers
|
||||
orb_advert_t _accel_pub;
|
||||
@@ -255,14 +269,16 @@ private:
|
||||
int _actuator_outputs_sub;
|
||||
int _vehicle_attitude_sub;
|
||||
int _manual_sub;
|
||||
int _vehicle_status_sub;
|
||||
|
||||
// uORB data containers
|
||||
struct rc_input_values _rc_input;
|
||||
struct actuator_outputs_s _actuators;
|
||||
struct vehicle_attitude_s _attitude;
|
||||
struct manual_control_setpoint_s _manual;
|
||||
struct vehicle_status_s _vehicle_status;
|
||||
|
||||
void poll_actuators();
|
||||
void poll_topics();
|
||||
void handle_message(mavlink_message_t *msg, bool publish);
|
||||
void send_controls();
|
||||
void pollForMAVLinkMessages(bool publish);
|
||||
|
||||
@@ -64,33 +64,46 @@ static socklen_t _addrlen = sizeof(_srcaddr);
|
||||
using namespace simulator;
|
||||
|
||||
void Simulator::pack_actuator_message(mavlink_hil_controls_t &actuator_msg) {
|
||||
float out[8];
|
||||
float out[8] = {};
|
||||
|
||||
const float pwm_center = (PWM_HIGHEST_MAX + PWM_LOWEST_MIN) / 2;
|
||||
|
||||
// for now we only support quadrotors
|
||||
unsigned n = 4;
|
||||
|
||||
for (unsigned i = 0; i < 8; i++) {
|
||||
if (_actuators.output[i] > PWM_LOWEST_MIN / 2) {
|
||||
if (i < n) {
|
||||
// scale PWM out 900..2100 us to 0..1 for rotors */
|
||||
out[i] = (_actuators.output[i] - PWM_LOWEST_MIN) / (PWM_HIGHEST_MAX - PWM_LOWEST_MIN);
|
||||
if (_vehicle_status.is_rotary_wing) {
|
||||
for (unsigned i = 0; i < 8; i++) {
|
||||
if (_actuators.output[i] > PWM_LOWEST_MIN / 2) {
|
||||
if (i < n) {
|
||||
// scale PWM out 900..2100 us to 0..1 for rotors */
|
||||
out[i] = (_actuators.output[i] - PWM_LOWEST_MIN) / (PWM_HIGHEST_MAX - PWM_LOWEST_MIN);
|
||||
|
||||
} else {
|
||||
// scale PWM out 900..2100 us to -1..1 for other channels */
|
||||
out[i] = (_actuators.output[i] - pwm_center) / ((PWM_HIGHEST_MAX - PWM_LOWEST_MIN) / 2);
|
||||
}
|
||||
|
||||
} else {
|
||||
// scale PWM out 900..2100 us to -1..1 for other channels */
|
||||
out[i] = (_actuators.output[i] - pwm_center) / ((PWM_HIGHEST_MAX - PWM_LOWEST_MIN) / 2);
|
||||
// send 0 when disarmed and for disabled channels */
|
||||
out[i] = 0.0f;
|
||||
}
|
||||
|
||||
} else {
|
||||
// send 0 when disarmed and for disabled channels */
|
||||
out[i] = 0.0f;
|
||||
}
|
||||
} else {
|
||||
// convert back to range [-1, 1]
|
||||
for (unsigned i = 0; i < 8; i++) {
|
||||
out[i] = (_actuators.output[i] - 1500) / 600.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// if vehicle status has not yet been updated, set actuator commands to zero
|
||||
// this is to prevent the simulation getting into a bad state
|
||||
if (_vehicle_status.timestamp == 0) {
|
||||
memset(out, 0, sizeof(out));
|
||||
}
|
||||
|
||||
actuator_msg.time_usec = hrt_absolute_time();
|
||||
actuator_msg.roll_ailerons = out[0];
|
||||
actuator_msg.pitch_elevator = out[1];
|
||||
actuator_msg.pitch_elevator = _vehicle_status.is_rotary_wing ? out[1] : -out[1];
|
||||
actuator_msg.yaw_rudder = out[2];
|
||||
actuator_msg.throttle = out[3];
|
||||
actuator_msg.aux1 = out[4];
|
||||
@@ -174,11 +187,17 @@ void Simulator::update_sensors(mavlink_hil_sensor_t *imu) {
|
||||
|
||||
RawBaroData baro;
|
||||
// calculate air pressure from altitude (valid for low altitude)
|
||||
baro.pressure = PRESS_GROUND - GRAVITY * DENSITY * imu->pressure_alt;
|
||||
baro.pressure = (PRESS_GROUND - GRAVITY * DENSITY * imu->pressure_alt) / 100.0f; // convert from Pa to mbar
|
||||
baro.altitude = imu->pressure_alt;
|
||||
baro.temperature = imu->temperature;
|
||||
|
||||
write_baro_data((void *)&baro);
|
||||
|
||||
RawAirspeedData airspeed;
|
||||
airspeed.temperature = imu->temperature;
|
||||
airspeed.diff_pressure = imu->diff_pressure;
|
||||
|
||||
write_airspeed_data((void *)&airspeed);
|
||||
}
|
||||
|
||||
void Simulator::update_gps(mavlink_hil_gps_t *gps_sim) {
|
||||
@@ -270,14 +289,18 @@ void Simulator::send_mavlink_message(const uint8_t msgid, const void *msg, uint8
|
||||
}
|
||||
}
|
||||
|
||||
void Simulator::poll_actuators() {
|
||||
void Simulator::poll_topics() {
|
||||
// copy new actuator data if available
|
||||
bool updated;
|
||||
orb_check(_actuator_outputs_sub, &updated);
|
||||
if(updated) {
|
||||
//PX4_WARN("Received actuator_output0 orb_topic");
|
||||
if (updated) {
|
||||
orb_copy(ORB_ID(actuator_outputs), _actuator_outputs_sub, &_actuators);
|
||||
}
|
||||
|
||||
orb_check(_vehicle_status_sub, &updated);
|
||||
if (updated) {
|
||||
orb_copy(ORB_ID(vehicle_status), _vehicle_status_sub, &_vehicle_status);
|
||||
}
|
||||
}
|
||||
|
||||
void *Simulator::sending_trampoline(void *) {
|
||||
@@ -310,7 +333,7 @@ void Simulator::send() {
|
||||
|
||||
if (fds[0].revents & POLLIN) {
|
||||
// got new data to read, update all topics
|
||||
poll_actuators();
|
||||
poll_topics();
|
||||
send_controls();
|
||||
}
|
||||
}
|
||||
@@ -419,6 +442,7 @@ void Simulator::pollForMAVLinkMessages(bool publish)
|
||||
|
||||
// subscribe to topics
|
||||
_actuator_outputs_sub = orb_subscribe_multi(ORB_ID(actuator_outputs), 0);
|
||||
_vehicle_status_sub = orb_subscribe(ORB_ID(vehicle_status));
|
||||
|
||||
// got data from simulator, now activate the sending thread
|
||||
pthread_create(&sender_thread, &sender_thread_attr, Simulator::sending_trampoline, NULL);
|
||||
|
||||
@@ -396,13 +396,12 @@ perf_print_counter_fd(int fd, perf_counter_t handle)
|
||||
case PC_ELAPSED: {
|
||||
struct perf_ctr_elapsed *pce = (struct perf_ctr_elapsed *)handle;
|
||||
float rms = sqrtf(pce->M2 / (pce->event_count-1));
|
||||
|
||||
dprintf(fd, "%s: %llu events, %llu overruns, %lluus elapsed, %lluus avg, min %lluus max %lluus %5.3fus rms\n",
|
||||
handle->name,
|
||||
(unsigned long long)pce->event_count,
|
||||
(unsigned long long)pce->event_overruns,
|
||||
(unsigned long long)pce->time_total,
|
||||
(unsigned long long)pce->time_total / pce->event_count,
|
||||
pce->event_count == 0 ? 0 : (unsigned long long)pce->time_total / pce->event_count,
|
||||
(unsigned long long)pce->time_least,
|
||||
(unsigned long long)pce->time_most,
|
||||
(double)(1e6f * rms));
|
||||
|
||||
Reference in New Issue
Block a user