37 #include <px4_platform_common/log.h> 38 #include <px4_platform_common/time.h> 39 #include <px4_platform_common/tasks.h> 41 #include <simulator_config.h> 45 #include <sys/socket.h> 46 #include <netinet/in.h> 47 #include <netinet/tcp.h> 50 #include <mathlib/mathlib.h> 54 #ifdef ENABLE_UART_RC_INPUT 56 #define B460800 460800 60 #define B921600 921600 63 static int openUart(
const char *uart_name,
int baud);
67 static unsigned char _buf[2048];
79 mavlink_hil_actuator_controls_t
msg{};
83 bool armed = (_vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED);
87 int _system_type = _param_mav_type.get();
90 if (_system_type == MAV_TYPE_QUADROTOR ||
91 _system_type == MAV_TYPE_HEXAROTOR ||
92 _system_type == MAV_TYPE_OCTOROTOR ||
93 _system_type == MAV_TYPE_VTOL_DUOROTOR ||
94 _system_type == MAV_TYPE_VTOL_QUADROTOR ||
95 _system_type == MAV_TYPE_VTOL_TILTROTOR ||
96 _system_type == MAV_TYPE_VTOL_RESERVED2) {
102 switch (_system_type) {
103 case MAV_TYPE_VTOL_DUOROTOR:
107 case MAV_TYPE_QUADROTOR:
108 case MAV_TYPE_VTOL_QUADROTOR:
109 case MAV_TYPE_VTOL_TILTROTOR:
113 case MAV_TYPE_VTOL_RESERVED2:
118 case MAV_TYPE_HEXAROTOR:
127 for (
unsigned i = 0; i < 16; i++) {
140 msg.controls[i] = 0.0f;
147 for (
unsigned i = 0; i < 16; i++) {
160 msg.controls[i] = 0.0f;
175 bool updated =
false;
176 orb_check(_actuator_outputs_sub, &updated);
180 orb_copy(
ORB_ID(actuator_outputs), _actuator_outputs_sub, &actuators);
182 if (actuators.timestamp > 0) {
183 const mavlink_hil_actuator_controls_t hil_act_control = actuator_controls_from_outputs(actuators);
185 mavlink_message_t message{};
186 mavlink_msg_hil_actuator_controls_encode(_param_mav_sys_id.get(), _param_mav_comp_id.get(), &message, &hil_act_control);
188 PX4_DEBUG(
"sending controls t=%ld (%ld)", actuators.timestamp, hil_act_control.time_usec);
190 send_mavlink_message(message);
200 rc->
rssi = rc_channels->rssi;
202 rc->
values[0] = rc_channels->chan1_raw;
203 rc->
values[1] = rc_channels->chan2_raw;
204 rc->
values[2] = rc_channels->chan3_raw;
205 rc->
values[3] = rc_channels->chan4_raw;
206 rc->
values[4] = rc_channels->chan5_raw;
207 rc->
values[5] = rc_channels->chan6_raw;
208 rc->
values[6] = rc_channels->chan7_raw;
209 rc->
values[7] = rc_channels->chan8_raw;
210 rc->
values[8] = rc_channels->chan9_raw;
211 rc->
values[9] = rc_channels->chan10_raw;
212 rc->
values[10] = rc_channels->chan11_raw;
213 rc->
values[11] = rc_channels->chan12_raw;
214 rc->
values[12] = rc_channels->chan13_raw;
215 rc->
values[13] = rc_channels->chan14_raw;
216 rc->
values[14] = rc_channels->chan15_raw;
217 rc->
values[15] = rc_channels->chan16_raw;
218 rc->
values[16] = rc_channels->chan17_raw;
219 rc->
values[17] = rc_channels->chan18_raw;
224 if ((imu.fields_updated & 0x1FFF) != 0x1FFF) {
225 PX4_DEBUG(
"All sensor fields in mavlink HIL_SENSOR packet not updated. Got %08x", imu.fields_updated);
230 static constexpr
float scaling = 1000.0f;
231 _px4_gyro.set_scale(1 / scaling);
232 _px4_gyro.set_temperature(imu.temperature);
233 _px4_gyro.update(time, imu.xgyro * scaling, imu.ygyro * scaling, imu.zgyro * scaling);
238 static constexpr
float scaling = 1000.0f;
239 _px4_accel.set_scale(1 / scaling);
240 _px4_accel.set_temperature(imu.temperature);
241 _px4_accel.update(time, imu.xacc * scaling, imu.yacc * scaling, imu.zacc * scaling);
246 static constexpr
float scaling = 1000.0f;
247 _px4_mag.set_scale(1 / scaling);
248 _px4_mag.set_temperature(imu.temperature);
249 _px4_mag.update(time, imu.xmag * scaling, imu.ymag * scaling, imu.zmag * scaling);
254 _px4_baro.set_temperature(imu.temperature);
255 _px4_baro.update(time, imu.abs_pressure);
262 report.temperature = imu.temperature;
263 report.differential_pressure_filtered_pa = imu.diff_pressure * 100.0f;
264 report.differential_pressure_raw_pa = imu.diff_pressure * 100.0f;
275 gps.
lat = gps_sim->lat;
276 gps.
lon = gps_sim->lon;
277 gps.
alt = gps_sim->alt;
278 gps.
eph = gps_sim->eph;
279 gps.
epv = gps_sim->epv;
280 gps.
vel = gps_sim->vel;
281 gps.
vn = gps_sim->vn;
282 gps.
ve = gps_sim->ve;
283 gps.
vd = gps_sim->vd;
284 gps.
cog = gps_sim->cog;
288 write_gps_data((
void *)&gps);
293 switch (msg->msgid) {
294 case MAVLINK_MSG_ID_HIL_SENSOR:
295 handle_message_hil_sensor(msg);
298 case MAVLINK_MSG_ID_HIL_OPTICAL_FLOW:
299 handle_message_optical_flow(msg);
302 case MAVLINK_MSG_ID_ODOMETRY:
303 handle_message_odometry(msg);
306 case MAVLINK_MSG_ID_VISION_POSITION_ESTIMATE:
307 handle_message_vision_position_estimate(msg);
310 case MAVLINK_MSG_ID_DISTANCE_SENSOR:
311 handle_message_distance_sensor(msg);
314 case MAVLINK_MSG_ID_HIL_GPS:
315 handle_message_hil_gps(msg);
318 case MAVLINK_MSG_ID_RC_CHANNELS:
319 handle_message_rc_channels(msg);
322 case MAVLINK_MSG_ID_LANDING_TARGET:
323 handle_message_landing_target(msg);
326 case MAVLINK_MSG_ID_HIL_STATE_QUATERNION:
327 handle_message_hil_state_quaternion(msg);
334 mavlink_distance_sensor_t dist;
335 mavlink_msg_distance_sensor_decode(msg, &dist);
336 publish_distance_topic(&dist);
341 mavlink_hil_gps_t gps_sim;
342 mavlink_msg_hil_gps_decode(msg, &gps_sim);
344 update_gps(&gps_sim);
349 mavlink_hil_sensor_t imu;
350 mavlink_msg_hil_sensor_decode(msg, &imu);
354 px4_clock_settime(CLOCK_MONOTONIC, &ts);
362 float step = diff / 4000.0f;
364 if (step > 1.1
f || step < 0.9
f) {
365 PX4_INFO(
"HIL_SENSOR: imu time_usec: %lu, time_usec: %lu, diff: %lu, step: %.2f", imu.time_usec, now_us, diff, step);
371 update_sensors(now_us, imu);
373 static float battery_percentage = 1.0f;
374 static uint64_t last_integration_us = 0;
379 const float discharge_interval_us = _param_sim_bat_drain.get() * 1000 * 1000;
381 bool armed = (_vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED);
384 if (last_integration_us != 0) {
385 battery_percentage -= (now_us - last_integration_us) / discharge_interval_us;
388 last_integration_us = now_us;
391 last_integration_us = 0;
396 battery_percentage =
math::max(battery_percentage, _battery_min_percentage.get() / 100.f);
397 float vbatt =
math::gradual(battery_percentage, 0.
f, 1.
f, _battery.empty_cell_voltage(), _battery.full_cell_voltage());
398 vbatt *= _battery.cell_count();
400 const float throttle = 0.0f;
401 _battery.updateBatteryStatus(now_us, vbatt, ibatt,
true,
true, 0, throttle, armed, &_battery_status);
412 mavlink_hil_state_quaternion_t hil_state;
413 mavlink_msg_hil_state_quaternion_decode(msg, &hil_state);
420 hil_angular_velocity.
timestamp = timestamp;
422 hil_angular_velocity.xyz[0] = hil_state.rollspeed;
423 hil_angular_velocity.xyz[1] = hil_state.pitchspeed;
424 hil_angular_velocity.xyz[2] = hil_state.yawspeed;
428 orb_publish_auto(
ORB_ID(vehicle_angular_velocity_groundtruth), &_vehicle_angular_velocity_pub, &hil_angular_velocity,
450 hil_gpos.lat = hil_state.lat / 1E7;
451 hil_gpos.lon = hil_state.lon / 1E7;
452 hil_gpos.alt = hil_state.alt / 1E3;
454 hil_gpos.vel_n = hil_state.vx / 100.0f;
455 hil_gpos.vel_e = hil_state.vy / 100.0f;
456 hil_gpos.vel_d = hil_state.vz / 100.0f;
468 double lat = hil_state.lat * 1e-7;
469 double lon = hil_state.lon * 1e-7;
471 if (!_hil_local_proj_inited) {
472 _hil_local_proj_inited =
true;
477 _hil_ref_alt = hil_state.alt / 1000.0f;
490 hil_lpos.
z = _hil_ref_alt - hil_state.alt / 1000.0f;
491 hil_lpos.
vx = hil_state.vx / 100.0f;
492 hil_lpos.
vy = hil_state.vy / 100.0f;
493 hil_lpos.
vz = hil_state.vz / 100.0f;
495 hil_lpos.
yaw = euler.
psi();
498 hil_lpos.
ref_lat = _hil_ref_lat;
499 hil_lpos.
ref_lon = _hil_ref_lon;
500 hil_lpos.
ref_alt = _hil_ref_alt;
502 hil_lpos.
vxy_max = std::numeric_limits<float>::infinity();
503 hil_lpos.
vz_max = std::numeric_limits<float>::infinity();
504 hil_lpos.
hagl_min = std::numeric_limits<float>::infinity();
505 hil_lpos.
hagl_max = std::numeric_limits<float>::infinity();
515 mavlink_landing_target_t landing_target_mavlink;
516 mavlink_msg_landing_target_decode(msg, &landing_target_mavlink);
521 report.
signature = landing_target_mavlink.target_num;
522 report.
pos_x = landing_target_mavlink.angle_x;
523 report.
pos_y = landing_target_mavlink.angle_y;
524 report.
size_x = landing_target_mavlink.size_x;
525 report.
size_y = landing_target_mavlink.size_y;
533 publish_odometry_topic(msg);
538 mavlink_hil_optical_flow_t flow;
539 mavlink_msg_hil_optical_flow_decode(msg, &flow);
540 publish_flow_topic(&flow);
546 mavlink_msg_rc_channels_decode(msg, &rc_channels);
556 publish_odometry_topic(msg);
561 uint8_t buf[MAVLINK_MAX_PACKET_LEN];
564 bufLen = mavlink_msg_to_send_buffer(buf, &aMsg);
568 if (_ip == InternetProtocol::UDP) {
569 len = ::sendto(
_fd, buf, bufLen, 0, (
struct sockaddr *)&
_srcaddr,
sizeof(_srcaddr));
576 PX4_WARN(
"Failed sending mavlink message: %s", strerror(errno));
583 bool updated =
false;
585 orb_check(_vehicle_status_sub, &updated);
588 orb_copy(
ORB_ID(vehicle_status), _vehicle_status_sub, &_vehicle_status);
601 pthread_setname_np(
"sim_send");
603 pthread_setname_np(pthread_self(),
"sim_send");
612 px4_pollfd_struct_t fds[1] = {};
613 fds[0].fd = _actuator_outputs_sub;
614 fds[0].events = POLLIN;
618 int pret =
px4_poll(&fds[0], (
sizeof(fds) /
sizeof(fds[0])), 100);
626 PX4_ERR(
"poll error %s", strerror(errno));
630 if (fds[0].revents & POLLIN) {
641 mavlink_command_long_t cmd_long = {};
642 mavlink_message_t message = {};
643 cmd_long.command = MAV_CMD_SET_MESSAGE_INTERVAL;
644 cmd_long.param1 = MAVLINK_MSG_ID_HIL_STATE_QUATERNION;
645 cmd_long.param2 = 5e3;
646 mavlink_msg_command_long_encode(_param_mav_sys_id.get(), _param_mav_comp_id.get(), &message, &cmd_long);
647 send_mavlink_message(message);
652 mavlink_heartbeat_t hb = {};
653 mavlink_message_t message = {};
655 hb.base_mode |= (_vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED) ? 128 : 0;
656 mavlink_msg_heartbeat_encode(_param_mav_sys_id.get(), _param_mav_comp_id.get(), &message, &hb);
657 send_mavlink_message(message);
663 pthread_setname_np(
"sim_rcv");
665 pthread_setname_np(pthread_self(),
"sim_rcv");
668 struct sockaddr_in _myaddr {};
669 _myaddr.sin_family = AF_INET;
670 _myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
671 _myaddr.sin_port = htons(_port);
673 if (_ip == InternetProtocol::UDP) {
675 if ((
_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
676 PX4_ERR(
"Creating UDP socket failed: %s", strerror(errno));
680 if (bind(
_fd, (
struct sockaddr *)&_myaddr,
sizeof(_myaddr)) < 0) {
681 PX4_ERR(
"bind for UDP port %i failed (%i)", _port, errno);
686 PX4_INFO(
"Waiting for simulator to connect on UDP port %u", _port);
701 PX4_INFO(
"Simulator connected on UDP port %u.", _port);
705 PX4_INFO(
"Waiting for simulator to connect on TCP port %u", _port);
708 if ((
_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
709 PX4_ERR(
"Creating TCP socket failed: %s", strerror(errno));
714 int ret = setsockopt(
_fd, IPPROTO_TCP, TCP_NODELAY, (
char *) &yes,
sizeof(
int));
717 PX4_ERR(
"setsockopt failed: %s", strerror(errno));
720 socklen_t myaddr_len =
sizeof(_myaddr);
721 ret = connect(
_fd, (
struct sockaddr *)&_myaddr, myaddr_len);
732 PX4_INFO(
"Simulator connected on TCP port %u.", _port);
737 pthread_t sender_thread;
739 pthread_attr_t sender_thread_attr;
740 pthread_attr_init(&sender_thread_attr);
741 pthread_attr_setstacksize(&sender_thread_attr, PX4_STACK_ADJUSTED(4000));
743 struct sched_param param;
744 (void)pthread_attr_getschedparam(&sender_thread_attr, ¶m);
748 param.sched_priority = SCHED_PRIORITY_ACTUATOR_OUTPUTS + 1;
749 (void)pthread_attr_setschedparam(&sender_thread_attr, ¶m);
751 struct pollfd fds[2] = {};
752 unsigned fd_count = 1;
754 fds[0].events = POLLIN;
756 #ifdef ENABLE_UART_RC_INPUT 758 int serial_fd = openUart(PIXHAWK_DEVICE, PIXHAWK_DEVICE_BAUD);
760 char serial_buf[1024];
762 if (serial_fd >= 0) {
763 fds[1].fd = serial_fd;
764 fds[1].events = POLLIN;
767 PX4_INFO(
"Start using %s for radio control input.", PIXHAWK_DEVICE);
770 PX4_INFO(
"Not using %s for radio control input. Assuming joystick input via MAVLink.", PIXHAWK_DEVICE);
782 pthread_attr_destroy(&sender_thread_attr);
784 mavlink_status_t mavlink_status = {};
787 request_hil_state_quaternion();
792 int pret = ::poll(&fds[0], fd_count, 1000);
800 PX4_ERR(
"poll error %d, %d", pret, errno);
804 if (fds[0].revents & POLLIN) {
809 mavlink_message_t
msg;
811 for (
int i = 0; i < len; i++) {
812 if (mavlink_parse_char(MAVLINK_COMM_0,
_buf[i], &msg, &mavlink_status)) {
813 handle_message(&msg);
819 #ifdef ENABLE_UART_RC_INPUT 822 if (fd_count > 1 && fds[1].revents & POLLIN) {
823 int len =
::read(serial_fd, serial_buf,
sizeof(serial_buf));
826 mavlink_message_t
msg;
828 mavlink_status_t serial_status = {};
830 for (
int i = 0; i < len; ++i) {
831 if (mavlink_parse_char(MAVLINK_COMM_1, serial_buf[i], &msg, &serial_status)) {
832 handle_message(&msg);
846 #ifdef ENABLE_UART_RC_INPUT 847 int openUart(
const char *uart_name,
int baud)
853 case 0: speed = B0;
break;
855 case 50: speed = B50;
break;
857 case 75: speed = B75;
break;
859 case 110: speed = B110;
break;
861 case 134: speed = B134;
break;
863 case 150: speed = B150;
break;
865 case 200: speed = B200;
break;
867 case 300: speed = B300;
break;
869 case 600: speed = B600;
break;
871 case 1200: speed = B1200;
break;
873 case 1800: speed = B1800;
break;
875 case 2400: speed = B2400;
break;
877 case 4800: speed = B4800;
break;
879 case 9600: speed = B9600;
break;
881 case 19200: speed = B19200;
break;
883 case 38400: speed = B38400;
break;
885 case 57600: speed = B57600;
break;
887 case 115200: speed = B115200;
break;
889 case 230400: speed = B230400;
break;
891 case 460800: speed =
B460800;
break;
893 case 921600: speed =
B921600;
break;
896 PX4_ERR(
"Unsupported baudrate: %d", baud);
901 int uart_fd = ::open(uart_name, O_RDWR | O_NOCTTY);
909 struct termios uart_config = {};
914 if ((termios_state = tcgetattr(uart_fd, &uart_config)) < 0) {
915 PX4_ERR(
"tcgetattr failed for %s: %s\n", uart_name, strerror(errno));
921 if (cfsetispeed(&uart_config, speed) < 0 || cfsetospeed(&uart_config, speed) < 0) {
922 PX4_ERR(
"cfsetispeed or cfsetospeed failed for %s: %s\n", uart_name, strerror(errno));
928 cfmakeraw(&uart_config);
930 if ((termios_state = tcsetattr(uart_fd, TCSANOW, &uart_config)) < 0) {
931 PX4_ERR(
"tcsetattr failed for %s: %s\n", uart_name, strerror(errno));
946 flow.
sensor_id = flow_mavlink->sensor_id;
959 flow.
quality = flow_mavlink->quality;
974 int32_t flow_rot_int;
978 float zeroval = 0.0f;
998 if (odom_mavlink->msgid == MAVLINK_MSG_ID_ODOMETRY) {
999 mavlink_odometry_t odom_msg;
1000 mavlink_msg_odometry_decode(odom_mavlink, &odom_msg);
1014 odom.
x = odom_msg.x;
1015 odom.
y = odom_msg.y;
1016 odom.
z = odom_msg.z;
1019 matrix::Quatf q(odom_msg.q[0], odom_msg.q[1], odom_msg.q[2], odom_msg.q[3]);
1024 static_assert(POS_URT_SIZE == (
sizeof(odom_msg.pose_covariance) /
sizeof(odom_msg.pose_covariance[0])),
1025 "Odometry Pose Covariance matrix URT array size mismatch");
1028 for (
size_t i = 0; i < POS_URT_SIZE; i++) {
1033 odom.
vx = linvel_local(0);
1034 odom.
vy = linvel_local(1);
1035 odom.
vz = linvel_local(2);
1043 static_assert(VEL_URT_SIZE == (
sizeof(odom_msg.velocity_covariance) /
sizeof(odom_msg.velocity_covariance[0])),
1044 "Odometry Velocity Covariance matrix URT array size mismatch");
1047 for (
size_t i = 0; i < VEL_URT_SIZE; i++) {
1051 }
else if (odom_mavlink->msgid == MAVLINK_MSG_ID_VISION_POSITION_ESTIMATE) {
1052 mavlink_vision_position_estimate_t ev;
1053 mavlink_msg_vision_position_estimate_decode(odom_mavlink, &ev);
1065 static_assert(POS_URT_SIZE == (
sizeof(ev.covariance) /
sizeof(ev.covariance[0])),
1066 "Vision Position Estimate Pose Covariance matrix URT array size mismatch");
1069 for (
size_t i = 0; i < POS_URT_SIZE; i++) {
1087 int instance_id = 0;
1102 dist.
min_distance = dist_mavlink->min_distance / 100.0f;
1103 dist.
max_distance = dist_mavlink->max_distance / 100.0f;
1105 dist.
type = dist_mavlink->type;
1106 dist.
id = dist_mavlink->id;
1108 dist.
variance = dist_mavlink->covariance * 1e-4
f;
1111 dist.
h_fov = dist_mavlink->horizontal_fov;
1112 dist.
v_fov = dist_mavlink->vertical_fov;
1113 dist.
q[0] = dist_mavlink->quaternion[0];
1114 dist.
q[1] = dist_mavlink->quaternion[1];
1115 dist.
q[2] = dist_mavlink->quaternion[2];
1116 dist.
q[3] = dist_mavlink->quaternion[3];
#define PWM_DEFAULT_MAX
Default maximum PWM in us.
void handle_message_distance_sensor(const mavlink_message_t *msg)
void handle_message_rc_channels(const mavlink_message_t *msg)
int orb_copy(const struct orb_metadata *meta, int handle, void *buffer)
void handle_message_landing_target(const mavlink_message_t *msg)
float gyro_x_rate_integral
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
Definition of geo / math functions to perform geodesic calculations.
void handle_message_optical_flow(const mavlink_message_t *msg)
void handle_message(const mavlink_message_t *msg)
float pixel_flow_y_integral
void handle_message_hil_gps(const mavlink_message_t *msg)
void send_mavlink_message(const mavlink_message_t &aMsg)
__EXPORT void rotate_3f(enum Rotation rot, float &x, float &y, float &z)
rotate a 3 element float vector in-place
static sockaddr_in _srcaddr
void handle_message_hil_sensor(const mavlink_message_t *msg)
This module interfaces via MAVLink to a software in the loop simulator (SITL) such as jMAVSim or Gaze...
uint16_t frame_count_since_last_readout
float min_ground_distance
float pixel_flow_x_integral
static void fill_rc_input_msg(input_rc_s *rc, mavlink_rc_channels_t *rc_channels)
void handle_message_hil_state_quaternion(const mavlink_message_t *msg)
void copyTo(Type dst[M *N]) const
uint32_t time_since_last_sonar_update
float velocity_covariance[21]
void handle_message_vision_position_estimate(const mavlink_message_t *msg)
const T gradual(const T &value, const T &x_low, const T &x_high, const T &y_low, const T &y_high)
uint8_t satellites_visible
static char msg[NUM_MSG][CONFIG_USART1_TXBUFSIZE]
float max_ground_distance
static void read(bootloader_app_shared_t *pshared)
int orb_subscribe(const struct orb_metadata *meta)
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
void request_hil_state_quaternion()
static unsigned char _buf[2048]
static void parameters_update()
update all parameters
Rotation
Enum for board and external compass rotations.
int orb_unsubscribe(int handle)
static struct actuator_armed_s armed
int publish_distance_topic(const mavlink_distance_sensor_t *dist)
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
static hrt_abstime hrt_elapsed_time(const hrt_abstime *then)
Compute the delta between a timestamp taken in the past and now.
const unsigned mode_flag_armed
void handle_message_odometry(const mavlink_message_t *msg)
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
void poll_for_MAVLink_messages()
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
constexpr _Tp max(_Tp a, _Tp b)
void update_gps(const mavlink_hil_gps_t *gps_sim)
Quaternion< float > Quatf
int map_projection_project(const struct map_projection_reference_s *ref, double lat, double lon, float *x, float *y)
int orb_check(int handle, bool *updated)
int orb_subscribe_multi(const struct orb_metadata *meta, unsigned instance)
float pose_covariance[21]
uint32_t integration_timespan
mavlink_hil_actuator_controls_t actuator_controls_from_outputs(const actuator_outputs_s &actuators)
__EXPORT void abstime_to_ts(struct timespec *ts, hrt_abstime abstime)
Convert absolute time to a timespec.
int publish_odometry_topic(const mavlink_message_t *odom_mavlink)
float gyro_z_rate_integral
float gyro_y_rate_integral
const unsigned mode_flag_custom
int map_projection_init(struct map_projection_reference_s *ref, double lat_0, double lon_0)
Initializes the map transformation given by the argument and sets the timestamp to now...
#define PWM_DEFAULT_MIN
Default minimum PWM in us.
int publish_flow_topic(const mavlink_hil_optical_flow_t *flow)
11 bits per channel * 16 channels = 22 bytes.
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
static int orb_publish_auto(const struct orb_metadata *meta, orb_advert_t *handle, const void *data, int *instance, int priority)
Advertise as the publisher of a topic.
static void * sending_trampoline(void *)
void update_sensors(const hrt_abstime &time, const mavlink_hil_sensor_t &imu)