mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-30 12:16:17 +08:00
improve end to end control latency measurement (#9388)
This commit is contained in:
@@ -271,8 +271,6 @@ private:
|
|||||||
|
|
||||||
enum Rotation _rotation;
|
enum Rotation _rotation;
|
||||||
|
|
||||||
perf_counter_t _controller_latency_perf;
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
/**
|
/**
|
||||||
* Report conversation with in the ADIS16448, including command byte and interrupt status.
|
* Report conversation with in the ADIS16448, including command byte and interrupt status.
|
||||||
@@ -524,8 +522,7 @@ ADIS16448::ADIS16448(int bus, const char *path_accel, const char *path_gyro, con
|
|||||||
_mag_filter_z(ADIS16448_MAG_DEFAULT_RATE, ADIS16448_MAG_DEFAULT_DRIVER_FILTER_FREQ),
|
_mag_filter_z(ADIS16448_MAG_DEFAULT_RATE, ADIS16448_MAG_DEFAULT_DRIVER_FILTER_FREQ),
|
||||||
_accel_int(1000000 / ADIS16448_ACCEL_MAX_OUTPUT_RATE, false),
|
_accel_int(1000000 / ADIS16448_ACCEL_MAX_OUTPUT_RATE, false),
|
||||||
_gyro_int(1000000 / ADIS16448_GYRO_MAX_OUTPUT_RATE, true),
|
_gyro_int(1000000 / ADIS16448_GYRO_MAX_OUTPUT_RATE, true),
|
||||||
_rotation(rotation),
|
_rotation(rotation)
|
||||||
_controller_latency_perf(perf_alloc_once(PC_ELAPSED, "ctrl_latency"))
|
|
||||||
{
|
{
|
||||||
// disable debug() calls
|
// disable debug() calls
|
||||||
_debug_enabled = false;
|
_debug_enabled = false;
|
||||||
@@ -1567,8 +1564,6 @@ ADIS16448::measure()
|
|||||||
_mag->parent_poll_notify();
|
_mag->parent_poll_notify();
|
||||||
|
|
||||||
if (accel_notify && !(_pub_blocked)) {
|
if (accel_notify && !(_pub_blocked)) {
|
||||||
/* log the time of this report */
|
|
||||||
perf_begin(_controller_latency_perf);
|
|
||||||
/* publish it */
|
/* publish it */
|
||||||
orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb);
|
orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -269,7 +269,6 @@ protected:
|
|||||||
perf_counter_t _good_transfers;
|
perf_counter_t _good_transfers;
|
||||||
perf_counter_t _reset_retries;
|
perf_counter_t _reset_retries;
|
||||||
perf_counter_t _duplicates;
|
perf_counter_t _duplicates;
|
||||||
perf_counter_t _controller_latency_perf;
|
|
||||||
|
|
||||||
uint8_t _register_wait;
|
uint8_t _register_wait;
|
||||||
uint64_t _reset_wait;
|
uint64_t _reset_wait;
|
||||||
|
|||||||
@@ -783,8 +783,6 @@ BMI055_accel::measure()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (accel_notify && !(_pub_blocked)) {
|
if (accel_notify && !(_pub_blocked)) {
|
||||||
/* log the time of this report */
|
|
||||||
perf_begin(_controller_latency_perf);
|
|
||||||
/* publish it */
|
/* publish it */
|
||||||
orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb);
|
orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -753,8 +753,6 @@ BMI055_gyro::measure()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (gyro_notify && !(_pub_blocked)) {
|
if (gyro_notify && !(_pub_blocked)) {
|
||||||
/* log the time of this report */
|
|
||||||
perf_begin(_controller_latency_perf);
|
|
||||||
/* publish it */
|
/* publish it */
|
||||||
orb_publish(ORB_ID(sensor_gyro), _gyro_topic, &grb);
|
orb_publish(ORB_ID(sensor_gyro), _gyro_topic, &grb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -442,7 +442,6 @@ BMI055::BMI055(const char *name, const char *devname, int bus, uint32_t device,
|
|||||||
_good_transfers(perf_alloc(PC_COUNT, "bmi055_good_transfers")),
|
_good_transfers(perf_alloc(PC_COUNT, "bmi055_good_transfers")),
|
||||||
_reset_retries(perf_alloc(PC_COUNT, "bmi055_reset_retries")),
|
_reset_retries(perf_alloc(PC_COUNT, "bmi055_reset_retries")),
|
||||||
_duplicates(perf_alloc(PC_COUNT, "bmi055_duplicates")),
|
_duplicates(perf_alloc(PC_COUNT, "bmi055_duplicates")),
|
||||||
_controller_latency_perf(perf_alloc_once(PC_ELAPSED, "ctrl_latency")),
|
|
||||||
_register_wait(0),
|
_register_wait(0),
|
||||||
_reset_wait(0),
|
_reset_wait(0),
|
||||||
_rotation(rotation),
|
_rotation(rotation),
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ BMI160::BMI160(int bus, const char *path_accel, const char *path_gyro, uint32_t
|
|||||||
_good_transfers(perf_alloc(PC_COUNT, "bmi160_good_transfers")),
|
_good_transfers(perf_alloc(PC_COUNT, "bmi160_good_transfers")),
|
||||||
_reset_retries(perf_alloc(PC_COUNT, "bmi160_reset_retries")),
|
_reset_retries(perf_alloc(PC_COUNT, "bmi160_reset_retries")),
|
||||||
_duplicates(perf_alloc(PC_COUNT, "bmi160_duplicates")),
|
_duplicates(perf_alloc(PC_COUNT, "bmi160_duplicates")),
|
||||||
_controller_latency_perf(perf_alloc_once(PC_ELAPSED, "ctrl_latency")),
|
|
||||||
_register_wait(0),
|
_register_wait(0),
|
||||||
_reset_wait(0),
|
_reset_wait(0),
|
||||||
_accel_filter_x(BMI160_ACCEL_DEFAULT_RATE, BMI160_ACCEL_DEFAULT_DRIVER_FILTER_FREQ),
|
_accel_filter_x(BMI160_ACCEL_DEFAULT_RATE, BMI160_ACCEL_DEFAULT_DRIVER_FILTER_FREQ),
|
||||||
@@ -1246,8 +1245,6 @@ BMI160::measure()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (accel_notify && !(_pub_blocked)) {
|
if (accel_notify && !(_pub_blocked)) {
|
||||||
/* log the time of this report */
|
|
||||||
perf_begin(_controller_latency_perf);
|
|
||||||
/* publish it */
|
/* publish it */
|
||||||
orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb);
|
orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -307,7 +307,6 @@ private:
|
|||||||
perf_counter_t _good_transfers;
|
perf_counter_t _good_transfers;
|
||||||
perf_counter_t _reset_retries;
|
perf_counter_t _reset_retries;
|
||||||
perf_counter_t _duplicates;
|
perf_counter_t _duplicates;
|
||||||
perf_counter_t _controller_latency_perf;
|
|
||||||
|
|
||||||
uint8_t _register_wait;
|
uint8_t _register_wait;
|
||||||
uint64_t _reset_wait;
|
uint64_t _reset_wait;
|
||||||
|
|||||||
@@ -208,7 +208,6 @@ private:
|
|||||||
perf_counter_t _good_transfers;
|
perf_counter_t _good_transfers;
|
||||||
perf_counter_t _reset_retries;
|
perf_counter_t _reset_retries;
|
||||||
perf_counter_t _duplicates;
|
perf_counter_t _duplicates;
|
||||||
perf_counter_t _controller_latency_perf;
|
|
||||||
|
|
||||||
uint8_t _register_wait;
|
uint8_t _register_wait;
|
||||||
uint64_t _reset_wait;
|
uint64_t _reset_wait;
|
||||||
@@ -510,7 +509,6 @@ MPU6000::MPU6000(device::Device *interface, const char *path_accel, const char *
|
|||||||
_good_transfers(perf_alloc(PC_COUNT, "mpu6k_good_trans")),
|
_good_transfers(perf_alloc(PC_COUNT, "mpu6k_good_trans")),
|
||||||
_reset_retries(perf_alloc(PC_COUNT, "mpu6k_reset")),
|
_reset_retries(perf_alloc(PC_COUNT, "mpu6k_reset")),
|
||||||
_duplicates(perf_alloc(PC_COUNT, "mpu6k_duplicates")),
|
_duplicates(perf_alloc(PC_COUNT, "mpu6k_duplicates")),
|
||||||
_controller_latency_perf(perf_alloc_once(PC_ELAPSED, "ctrl_latency")),
|
|
||||||
_register_wait(0),
|
_register_wait(0),
|
||||||
_reset_wait(0),
|
_reset_wait(0),
|
||||||
_accel_filter_x(MPU6000_ACCEL_DEFAULT_RATE, MPU6000_ACCEL_DEFAULT_DRIVER_FILTER_FREQ),
|
_accel_filter_x(MPU6000_ACCEL_DEFAULT_RATE, MPU6000_ACCEL_DEFAULT_DRIVER_FILTER_FREQ),
|
||||||
@@ -2076,8 +2074,6 @@ MPU6000::measure()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (accel_notify && !(_pub_blocked)) {
|
if (accel_notify && !(_pub_blocked)) {
|
||||||
/* log the time of this report */
|
|
||||||
perf_begin(_controller_latency_perf);
|
|
||||||
/* publish it */
|
/* publish it */
|
||||||
orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb);
|
orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,6 @@ MPU9250::MPU9250(device::Device *interface, device::Device *mag_interface, const
|
|||||||
_good_transfers(perf_alloc(PC_COUNT, "mpu9250_good_trans")),
|
_good_transfers(perf_alloc(PC_COUNT, "mpu9250_good_trans")),
|
||||||
_reset_retries(perf_alloc(PC_COUNT, "mpu9250_reset")),
|
_reset_retries(perf_alloc(PC_COUNT, "mpu9250_reset")),
|
||||||
_duplicates(perf_alloc(PC_COUNT, "mpu9250_dupe")),
|
_duplicates(perf_alloc(PC_COUNT, "mpu9250_dupe")),
|
||||||
_controller_latency_perf(perf_alloc_once(PC_ELAPSED, "ctrl_latency")),
|
|
||||||
_register_wait(0),
|
_register_wait(0),
|
||||||
_reset_wait(0),
|
_reset_wait(0),
|
||||||
_accel_filter_x(MPU9250_ACCEL_DEFAULT_RATE, MPU9250_ACCEL_DEFAULT_DRIVER_FILTER_FREQ),
|
_accel_filter_x(MPU9250_ACCEL_DEFAULT_RATE, MPU9250_ACCEL_DEFAULT_DRIVER_FILTER_FREQ),
|
||||||
@@ -1487,8 +1486,6 @@ MPU9250::measure()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (accel_notify && !(_pub_blocked)) {
|
if (accel_notify && !(_pub_blocked)) {
|
||||||
/* log the time of this report */
|
|
||||||
perf_begin(_controller_latency_perf);
|
|
||||||
/* publish it */
|
/* publish it */
|
||||||
orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb);
|
orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -320,7 +320,6 @@ private:
|
|||||||
perf_counter_t _good_transfers;
|
perf_counter_t _good_transfers;
|
||||||
perf_counter_t _reset_retries;
|
perf_counter_t _reset_retries;
|
||||||
perf_counter_t _duplicates;
|
perf_counter_t _duplicates;
|
||||||
perf_counter_t _controller_latency_perf;
|
|
||||||
|
|
||||||
uint8_t _register_wait;
|
uint8_t _register_wait;
|
||||||
uint64_t _reset_wait;
|
uint64_t _reset_wait;
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
#include <lib/mixer/mixer_load.h>
|
#include <lib/mixer/mixer_load.h>
|
||||||
#include <parameters/param.h>
|
#include <parameters/param.h>
|
||||||
#include <systemlib/pwm_limit/pwm_limit.h>
|
#include <systemlib/pwm_limit/pwm_limit.h>
|
||||||
|
#include <perf/perf_counter.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "navio_sysfs.h"
|
#include "navio_sysfs.h"
|
||||||
@@ -77,6 +78,8 @@ int _armed_sub = -1;
|
|||||||
orb_advert_t _outputs_pub = nullptr;
|
orb_advert_t _outputs_pub = nullptr;
|
||||||
orb_advert_t _rc_pub = nullptr;
|
orb_advert_t _rc_pub = nullptr;
|
||||||
|
|
||||||
|
perf_counter_t _perf_control_latency = nullptr;
|
||||||
|
|
||||||
// topic structures
|
// topic structures
|
||||||
actuator_controls_s _controls[actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS];
|
actuator_controls_s _controls[actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS];
|
||||||
orb_id_t _controls_topics[actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS];
|
orb_id_t _controls_topics[actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS];
|
||||||
@@ -212,6 +215,8 @@ void task_main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
_is_running = true;
|
_is_running = true;
|
||||||
|
|
||||||
|
_perf_control_latency = perf_alloc(PC_ELAPSED, "linux_pwm_out control latency");
|
||||||
|
|
||||||
// Set up mixer
|
// Set up mixer
|
||||||
if (initialize_mixer(_mixer_filename) < 0) {
|
if (initialize_mixer(_mixer_filename) < 0) {
|
||||||
PX4_ERR("Mixer initialization failed.");
|
PX4_ERR("Mixer initialization failed.");
|
||||||
@@ -240,6 +245,7 @@ void task_main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
_mixer_group->groups_required(_groups_required);
|
_mixer_group->groups_required(_groups_required);
|
||||||
|
|
||||||
// subscribe and set up polling
|
// subscribe and set up polling
|
||||||
subscribe();
|
subscribe();
|
||||||
|
|
||||||
@@ -321,7 +327,6 @@ void task_main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_mixer_group != nullptr) {
|
if (_mixer_group != nullptr) {
|
||||||
_outputs.timestamp = hrt_absolute_time();
|
|
||||||
/* do mixing */
|
/* do mixing */
|
||||||
_outputs.noutputs = _mixer_group->mix(_outputs.output, actuator_outputs_s::NUM_ACTUATOR_OUTPUTS);
|
_outputs.noutputs = _mixer_group->mix(_outputs.output, actuator_outputs_s::NUM_ACTUATOR_OUTPUTS);
|
||||||
|
|
||||||
@@ -379,6 +384,8 @@ void task_main(int argc, char *argv[])
|
|||||||
pwm_out->send_output_pwm(pwm, _outputs.noutputs);
|
pwm_out->send_output_pwm(pwm, _outputs.noutputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_outputs.timestamp = hrt_absolute_time();
|
||||||
|
|
||||||
if (_outputs_pub != nullptr) {
|
if (_outputs_pub != nullptr) {
|
||||||
orb_publish(ORB_ID(actuator_outputs), _outputs_pub, &_outputs);
|
orb_publish(ORB_ID(actuator_outputs), _outputs_pub, &_outputs);
|
||||||
|
|
||||||
@@ -386,6 +393,17 @@ void task_main(int argc, char *argv[])
|
|||||||
_outputs_pub = orb_advertise(ORB_ID(actuator_outputs), &_outputs);
|
_outputs_pub = orb_advertise(ORB_ID(actuator_outputs), &_outputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use first valid timestamp_sample for latency tracking
|
||||||
|
for (int i = 0; i < actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS; i++) {
|
||||||
|
const bool required = _groups_required & (1 << i);
|
||||||
|
const hrt_abstime ×tamp_sample = _controls[i].timestamp_sample;
|
||||||
|
|
||||||
|
if (required && (timestamp_sample > 0)) {
|
||||||
|
perf_set_elapsed(_perf_control_latency, _outputs.timestamp - timestamp_sample);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PX4_ERR("Could not mix output! Exiting...");
|
PX4_ERR("Could not mix output! Exiting...");
|
||||||
_task_should_exit = true;
|
_task_should_exit = true;
|
||||||
@@ -424,6 +442,8 @@ void task_main(int argc, char *argv[])
|
|||||||
orb_unsubscribe(params_sub);
|
orb_unsubscribe(params_sub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
perf_free(_perf_control_latency);
|
||||||
|
|
||||||
_is_running = false;
|
_is_running = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,8 @@
|
|||||||
#include "PWMSim.hpp"
|
#include "PWMSim.hpp"
|
||||||
|
|
||||||
PWMSim::PWMSim() :
|
PWMSim::PWMSim() :
|
||||||
CDev("pwm_out_sim", PWM_OUTPUT0_DEVICE_PATH)
|
CDev("pwm_out_sim", PWM_OUTPUT0_DEVICE_PATH),
|
||||||
|
_perf_control_latency(perf_alloc(PC_ELAPSED, "pwm_out_sim control latency"))
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < MAX_ACTUATORS; i++) {
|
for (unsigned i = 0; i < MAX_ACTUATORS; i++) {
|
||||||
_pwm_min[i] = PWM_SIM_PWM_MIN_MAGIC;
|
_pwm_min[i] = PWM_SIM_PWM_MIN_MAGIC;
|
||||||
@@ -56,6 +57,11 @@ PWMSim::PWMSim() :
|
|||||||
set_mode(MODE_16PWM);
|
set_mode(MODE_16PWM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PWMSim::~PWMSim()
|
||||||
|
{
|
||||||
|
perf_free(_perf_control_latency);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PWMSim::set_mode(Mode mode)
|
PWMSim::set_mode(Mode mode)
|
||||||
{
|
{
|
||||||
@@ -232,7 +238,6 @@ PWMSim::run()
|
|||||||
/* do mixing */
|
/* do mixing */
|
||||||
unsigned num_outputs = _mixers->mix(&_actuator_outputs.output[0], _num_outputs);
|
unsigned num_outputs = _mixers->mix(&_actuator_outputs.output[0], _num_outputs);
|
||||||
_actuator_outputs.noutputs = num_outputs;
|
_actuator_outputs.noutputs = num_outputs;
|
||||||
_actuator_outputs.timestamp = hrt_absolute_time();
|
|
||||||
|
|
||||||
/* disable unused ports by setting their output to NaN */
|
/* disable unused ports by setting their output to NaN */
|
||||||
for (size_t i = 0; i < sizeof(_actuator_outputs.output) / sizeof(_actuator_outputs.output[0]); i++) {
|
for (size_t i = 0; i < sizeof(_actuator_outputs.output) / sizeof(_actuator_outputs.output[0]); i++) {
|
||||||
@@ -284,7 +289,19 @@ PWMSim::run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* and publish for anyone that cares to see */
|
/* and publish for anyone that cares to see */
|
||||||
|
_actuator_outputs.timestamp = hrt_absolute_time();
|
||||||
orb_publish(ORB_ID(actuator_outputs), _outputs_pub, &_actuator_outputs);
|
orb_publish(ORB_ID(actuator_outputs), _outputs_pub, &_actuator_outputs);
|
||||||
|
|
||||||
|
// use first valid timestamp_sample for latency tracking
|
||||||
|
for (int i = 0; i < actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS; i++) {
|
||||||
|
const bool required = _groups_required & (1 << i);
|
||||||
|
const hrt_abstime ×tamp_sample = _controls[i].timestamp_sample;
|
||||||
|
|
||||||
|
if (required && (timestamp_sample > 0)) {
|
||||||
|
perf_set_elapsed(_perf_control_latency, _actuator_outputs.timestamp - timestamp_sample);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* how about an arming update? */
|
/* how about an arming update? */
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include <drivers/drv_mixer.h>
|
#include <drivers/drv_mixer.h>
|
||||||
#include <drivers/drv_pwm_output.h>
|
#include <drivers/drv_pwm_output.h>
|
||||||
#include <lib/mixer/mixer.h>
|
#include <lib/mixer/mixer.h>
|
||||||
|
#include <perf/perf_counter.h>
|
||||||
#include <px4_common.h>
|
#include <px4_common.h>
|
||||||
#include <px4_config.h>
|
#include <px4_config.h>
|
||||||
#include <px4_module.h>
|
#include <px4_module.h>
|
||||||
@@ -67,7 +68,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
PWMSim();
|
PWMSim();
|
||||||
virtual ~PWMSim() = default;
|
virtual ~PWMSim();
|
||||||
|
|
||||||
/** @see ModuleBase */
|
/** @see ModuleBase */
|
||||||
static int task_spawn(int argc, char *argv[]);
|
static int task_spawn(int argc, char *argv[]);
|
||||||
@@ -132,6 +133,8 @@ private:
|
|||||||
|
|
||||||
bool _airmode{false}; ///< multicopter air-mode
|
bool _airmode{false}; ///< multicopter air-mode
|
||||||
|
|
||||||
|
perf_counter_t _perf_control_latency;
|
||||||
|
|
||||||
static int control_callback(uintptr_t handle, uint8_t control_group, uint8_t control_index, float &input);
|
static int control_callback(uintptr_t handle, uint8_t control_group, uint8_t control_index, float &input);
|
||||||
|
|
||||||
void subscribe();
|
void subscribe();
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ private:
|
|||||||
float _thr_mdl_fac; // thrust to pwm modelling factor
|
float _thr_mdl_fac; // thrust to pwm modelling factor
|
||||||
bool _airmode; // multicopter air-mode
|
bool _airmode; // multicopter air-mode
|
||||||
|
|
||||||
perf_counter_t _ctl_latency;
|
perf_counter_t _perf_control_latency;
|
||||||
|
|
||||||
static bool arm_nothrottle()
|
static bool arm_nothrottle()
|
||||||
{
|
{
|
||||||
@@ -387,7 +387,7 @@ PX4FMU::PX4FMU(bool run_as_task) :
|
|||||||
_mot_t_max(0.0f),
|
_mot_t_max(0.0f),
|
||||||
_thr_mdl_fac(0.0f),
|
_thr_mdl_fac(0.0f),
|
||||||
_airmode(false),
|
_airmode(false),
|
||||||
_ctl_latency(perf_alloc(PC_ELAPSED, "ctl_lat"))
|
_perf_control_latency(perf_alloc(PC_ELAPSED, "fmu control latency"))
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < _max_actuators; i++) {
|
for (unsigned i = 0; i < _max_actuators; i++) {
|
||||||
_min_pwm[i] = PWM_DEFAULT_MIN;
|
_min_pwm[i] = PWM_DEFAULT_MIN;
|
||||||
@@ -465,7 +465,7 @@ PX4FMU::~PX4FMU()
|
|||||||
/* clean up the alternate device node */
|
/* clean up the alternate device node */
|
||||||
unregister_class_devname(PWM_OUTPUT_BASE_DEVICE_PATH, _class_instance);
|
unregister_class_devname(PWM_OUTPUT_BASE_DEVICE_PATH, _class_instance);
|
||||||
|
|
||||||
perf_free(_ctl_latency);
|
perf_free(_perf_control_latency);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -1238,8 +1238,6 @@ PX4FMU::cycle()
|
|||||||
// PX4_WARN("no PWM: failsafe");
|
// PX4_WARN("no PWM: failsafe");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
perf_begin(_ctl_latency);
|
|
||||||
|
|
||||||
if (_mixers != nullptr) {
|
if (_mixers != nullptr) {
|
||||||
/* get controls for required topics */
|
/* get controls for required topics */
|
||||||
unsigned poll_id = 0;
|
unsigned poll_id = 0;
|
||||||
@@ -1358,13 +1356,21 @@ PX4FMU::cycle()
|
|||||||
motor_limits.timestamp = hrt_absolute_time();
|
motor_limits.timestamp = hrt_absolute_time();
|
||||||
motor_limits.saturation_status = saturation_status.value;
|
motor_limits.saturation_status = saturation_status.value;
|
||||||
|
|
||||||
orb_publish_auto(ORB_ID(multirotor_motor_limits), &_to_mixer_status, &motor_limits, &_class_instance,
|
orb_publish_auto(ORB_ID(multirotor_motor_limits), &_to_mixer_status, &motor_limits, &_class_instance, ORB_PRIO_DEFAULT);
|
||||||
ORB_PRIO_DEFAULT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_mixers->set_airmode(_airmode);
|
_mixers->set_airmode(_airmode);
|
||||||
|
|
||||||
perf_end(_ctl_latency);
|
// use first valid timestamp_sample for latency tracking
|
||||||
|
for (int i = 0; i < actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS; i++) {
|
||||||
|
const bool required = _groups_required & (1 << i);
|
||||||
|
const hrt_abstime ×tamp_sample = _controls[i].timestamp_sample;
|
||||||
|
|
||||||
|
if (required && (timestamp_sample > 0)) {
|
||||||
|
perf_set_elapsed(_perf_control_latency, actuator_outputs.timestamp - timestamp_sample);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -468,7 +468,7 @@ PX4IO::PX4IO(device::Device *interface) :
|
|||||||
_mavlink_log_pub(nullptr),
|
_mavlink_log_pub(nullptr),
|
||||||
_perf_update(perf_alloc(PC_ELAPSED, "io update")),
|
_perf_update(perf_alloc(PC_ELAPSED, "io update")),
|
||||||
_perf_write(perf_alloc(PC_ELAPSED, "io write")),
|
_perf_write(perf_alloc(PC_ELAPSED, "io write")),
|
||||||
_perf_sample_latency(perf_alloc(PC_ELAPSED, "io latency")),
|
_perf_sample_latency(perf_alloc(PC_ELAPSED, "io control latency")),
|
||||||
_status(0),
|
_status(0),
|
||||||
_alarms(0),
|
_alarms(0),
|
||||||
_last_written_arming_s(0),
|
_last_written_arming_s(0),
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
#include <lib/mixer/mixer_load.h>
|
#include <lib/mixer/mixer_load.h>
|
||||||
#include <lib/mixer/mixer_multirotor_normalized.generated.h>
|
#include <lib/mixer/mixer_multirotor_normalized.generated.h>
|
||||||
#include <parameters/param.h>
|
#include <parameters/param.h>
|
||||||
|
#include <perf/perf_counter.h>
|
||||||
#include <systemlib/pwm_limit/pwm_limit.h>
|
#include <systemlib/pwm_limit/pwm_limit.h>
|
||||||
#include <dev_fs_lib_pwm.h>
|
#include <dev_fs_lib_pwm.h>
|
||||||
|
|
||||||
@@ -113,6 +114,7 @@ int32_t _pwm_max;
|
|||||||
|
|
||||||
MultirotorMixer *_mixer = nullptr;
|
MultirotorMixer *_mixer = nullptr;
|
||||||
|
|
||||||
|
perf_counter_t _perf_control_latency = nullptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* forward declaration
|
* forward declaration
|
||||||
@@ -338,8 +340,6 @@ void send_outputs_pwm(const uint16_t *pwm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void task_main(int argc, char *argv[])
|
void task_main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (pwm_initialize(_device) < 0) {
|
if (pwm_initialize(_device) < 0) {
|
||||||
@@ -368,6 +368,8 @@ void task_main(int argc, char *argv[])
|
|||||||
// set max min pwm
|
// set max min pwm
|
||||||
pwm_limit_init(&_pwm_limit);
|
pwm_limit_init(&_pwm_limit);
|
||||||
|
|
||||||
|
_perf_control_latency = perf_alloc(PC_ELAPSED, "snapdragon_pwm_out control latency");
|
||||||
|
|
||||||
_is_running = true;
|
_is_running = true;
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
@@ -421,8 +423,6 @@ void task_main(int argc, char *argv[])
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_outputs.timestamp = hrt_absolute_time();
|
|
||||||
|
|
||||||
/* do mixing for virtual control group */
|
/* do mixing for virtual control group */
|
||||||
_outputs.noutputs = _mixer->mix(_outputs.output, _outputs.NUM_ACTUATOR_OUTPUTS);
|
_outputs.noutputs = _mixer->mix(_outputs.output, _outputs.NUM_ACTUATOR_OUTPUTS);
|
||||||
|
|
||||||
@@ -453,6 +453,8 @@ void task_main(int argc, char *argv[])
|
|||||||
send_outputs_pwm(pwm);
|
send_outputs_pwm(pwm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_outputs.timestamp = hrt_absolute_time();
|
||||||
|
|
||||||
if (_outputs_pub != nullptr) {
|
if (_outputs_pub != nullptr) {
|
||||||
orb_publish(ORB_ID(actuator_outputs), _outputs_pub, &_outputs);
|
orb_publish(ORB_ID(actuator_outputs), _outputs_pub, &_outputs);
|
||||||
|
|
||||||
@@ -460,6 +462,17 @@ void task_main(int argc, char *argv[])
|
|||||||
_outputs_pub = orb_advertise(ORB_ID(actuator_outputs), &_outputs);
|
_outputs_pub = orb_advertise(ORB_ID(actuator_outputs), &_outputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use first valid timestamp_sample for latency tracking
|
||||||
|
for (int i = 0; i < actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS; i++) {
|
||||||
|
const bool required = _groups_required & (1 << i);
|
||||||
|
const hrt_abstime ×tamp_sample = _controls[i].timestamp_sample;
|
||||||
|
|
||||||
|
if (required && (timestamp_sample > 0)) {
|
||||||
|
perf_set_elapsed(_perf_control_latency, _outputs.timestamp - timestamp_sample);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* check for parameter updates */
|
/* check for parameter updates */
|
||||||
bool param_updated = false;
|
bool param_updated = false;
|
||||||
orb_check(params_sub, ¶m_updated);
|
orb_check(params_sub, ¶m_updated);
|
||||||
@@ -481,8 +494,10 @@ void task_main(int argc, char *argv[])
|
|||||||
|
|
||||||
orb_unsubscribe(_armed_sub);
|
orb_unsubscribe(_armed_sub);
|
||||||
orb_unsubscribe(params_sub);
|
orb_unsubscribe(params_sub);
|
||||||
_is_running = false;
|
|
||||||
|
|
||||||
|
perf_free(_perf_control_latency);
|
||||||
|
|
||||||
|
_is_running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void task_main_trampoline(int argc, char *argv[])
|
void task_main_trampoline(int argc, char *argv[])
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
#include <lib/mathlib/mathlib.h>
|
#include <lib/mathlib/mathlib.h>
|
||||||
#include <drivers/device/device.h>
|
#include <drivers/device/device.h>
|
||||||
|
#include <perf/perf_counter.h>
|
||||||
#include <px4_module_params.h>
|
#include <px4_module_params.h>
|
||||||
#include <uORB/uORB.h>
|
#include <uORB/uORB.h>
|
||||||
#include <uORB/topics/actuator_controls.h>
|
#include <uORB/topics/actuator_controls.h>
|
||||||
@@ -118,6 +119,8 @@ private:
|
|||||||
actuator_outputs_s _outputs = {};
|
actuator_outputs_s _outputs = {};
|
||||||
actuator_armed_s _armed = {};
|
actuator_armed_s _armed = {};
|
||||||
|
|
||||||
|
perf_counter_t _perf_control_latency;
|
||||||
|
|
||||||
int _control_subs[actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS];
|
int _control_subs[actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS];
|
||||||
actuator_controls_s _controls[actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS];
|
actuator_controls_s _controls[actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS];
|
||||||
orb_id_t _control_topics[actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS];
|
orb_id_t _control_topics[actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS];
|
||||||
@@ -153,6 +156,7 @@ const uint8_t TAP_ESC::_device_dir_map[TAP_ESC_MAX_MOTOR_NUM] = ESC_DIR;
|
|||||||
TAP_ESC::TAP_ESC(char const *const device, uint8_t channels_count):
|
TAP_ESC::TAP_ESC(char const *const device, uint8_t channels_count):
|
||||||
CDev("tap_esc", TAP_ESC_DEVICE_PATH),
|
CDev("tap_esc", TAP_ESC_DEVICE_PATH),
|
||||||
ModuleParams(nullptr),
|
ModuleParams(nullptr),
|
||||||
|
_perf_control_latency(perf_alloc(PC_ELAPSED, "tap_esc control latency")),
|
||||||
_channels_count(channels_count)
|
_channels_count(channels_count)
|
||||||
{
|
{
|
||||||
strncpy(_device, device, sizeof(_device));
|
strncpy(_device, device, sizeof(_device));
|
||||||
@@ -196,6 +200,8 @@ TAP_ESC::~TAP_ESC()
|
|||||||
tap_esc_common::deinitialise_uart(_uart_fd);
|
tap_esc_common::deinitialise_uart(_uart_fd);
|
||||||
|
|
||||||
DEVICE_LOG("stopping");
|
DEVICE_LOG("stopping");
|
||||||
|
|
||||||
|
perf_free(_perf_control_latency);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @see ModuleBase */
|
/** @see ModuleBase */
|
||||||
@@ -447,7 +453,6 @@ void TAP_ESC::cycle()
|
|||||||
/* do mixing */
|
/* do mixing */
|
||||||
num_outputs = _mixers->mix(&_outputs.output[0], num_outputs);
|
num_outputs = _mixers->mix(&_outputs.output[0], num_outputs);
|
||||||
_outputs.noutputs = num_outputs;
|
_outputs.noutputs = num_outputs;
|
||||||
_outputs.timestamp = hrt_absolute_time();
|
|
||||||
|
|
||||||
/* publish mixer status */
|
/* publish mixer status */
|
||||||
multirotor_motor_limits_s multirotor_motor_limits = {};
|
multirotor_motor_limits_s multirotor_motor_limits = {};
|
||||||
@@ -546,6 +551,8 @@ void TAP_ESC::cycle()
|
|||||||
motor_out[i] = RPMSTOPPED;
|
motor_out[i] = RPMSTOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_outputs.timestamp = hrt_absolute_time();
|
||||||
|
|
||||||
send_esc_outputs(motor_out, num_outputs);
|
send_esc_outputs(motor_out, num_outputs);
|
||||||
tap_esc_common::read_data_from_uart(_uart_fd, &_uartbuf);
|
tap_esc_common::read_data_from_uart(_uart_fd, &_uartbuf);
|
||||||
|
|
||||||
@@ -571,6 +578,17 @@ void TAP_ESC::cycle()
|
|||||||
/* and publish for anyone that cares to see */
|
/* and publish for anyone that cares to see */
|
||||||
orb_publish(ORB_ID(actuator_outputs), _outputs_pub, &_outputs);
|
orb_publish(ORB_ID(actuator_outputs), _outputs_pub, &_outputs);
|
||||||
|
|
||||||
|
// use first valid timestamp_sample for latency tracking
|
||||||
|
for (int i = 0; i < actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS; i++) {
|
||||||
|
const bool required = _groups_required & (1 << i);
|
||||||
|
const hrt_abstime ×tamp_sample = _controls[i].timestamp_sample;
|
||||||
|
|
||||||
|
if (required && (timestamp_sample > 0)) {
|
||||||
|
perf_set_elapsed(_perf_control_latency, _outputs.timestamp - timestamp_sample);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool updated;
|
bool updated;
|
||||||
|
|||||||
@@ -164,7 +164,6 @@ private:
|
|||||||
MultirotorMixer::saturation_status _saturation_status{};
|
MultirotorMixer::saturation_status _saturation_status{};
|
||||||
|
|
||||||
perf_counter_t _loop_perf; /**< loop performance counter */
|
perf_counter_t _loop_perf; /**< loop performance counter */
|
||||||
perf_counter_t _controller_latency_perf;
|
|
||||||
|
|
||||||
math::LowPassFilter2p _lp_filters_d[3]; /**< low-pass filters for D-term (roll, pitch & yaw) */
|
math::LowPassFilter2p _lp_filters_d[3]; /**< low-pass filters for D-term (roll, pitch & yaw) */
|
||||||
static constexpr const float initial_update_rate_hz = 250.f; /**< loop update rate used for initialization */
|
static constexpr const float initial_update_rate_hz = 250.f; /**< loop update rate used for initialization */
|
||||||
|
|||||||
@@ -100,8 +100,6 @@ To reduce control latency, the module directly polls on the gyro topic published
|
|||||||
MulticopterAttitudeControl::MulticopterAttitudeControl() :
|
MulticopterAttitudeControl::MulticopterAttitudeControl() :
|
||||||
ModuleParams(nullptr),
|
ModuleParams(nullptr),
|
||||||
_loop_perf(perf_alloc(PC_ELAPSED, "mc_att_control")),
|
_loop_perf(perf_alloc(PC_ELAPSED, "mc_att_control")),
|
||||||
_controller_latency_perf(perf_alloc_once(PC_ELAPSED, "ctrl_latency")),
|
|
||||||
|
|
||||||
_lp_filters_d{
|
_lp_filters_d{
|
||||||
{initial_update_rate_hz, 50.f},
|
{initial_update_rate_hz, 50.f},
|
||||||
{initial_update_rate_hz, 50.f},
|
{initial_update_rate_hz, 50.f},
|
||||||
@@ -757,7 +755,6 @@ MulticopterAttitudeControl::run()
|
|||||||
if (_actuators_0_pub != nullptr) {
|
if (_actuators_0_pub != nullptr) {
|
||||||
|
|
||||||
orb_publish(_actuators_id, _actuators_0_pub, &_actuators);
|
orb_publish(_actuators_id, _actuators_0_pub, &_actuators);
|
||||||
perf_end(_controller_latency_perf);
|
|
||||||
|
|
||||||
} else if (_actuators_id) {
|
} else if (_actuators_id) {
|
||||||
_actuators_0_pub = orb_advertise(_actuators_id, &_actuators);
|
_actuators_0_pub = orb_advertise(_actuators_id, &_actuators);
|
||||||
@@ -799,7 +796,6 @@ MulticopterAttitudeControl::run()
|
|||||||
if (_actuators_0_pub != nullptr) {
|
if (_actuators_0_pub != nullptr) {
|
||||||
|
|
||||||
orb_publish(_actuators_id, _actuators_0_pub, &_actuators);
|
orb_publish(_actuators_id, _actuators_0_pub, &_actuators);
|
||||||
perf_end(_controller_latency_perf);
|
|
||||||
|
|
||||||
} else if (_actuators_id) {
|
} else if (_actuators_id) {
|
||||||
_actuators_0_pub = orb_advertise(_actuators_id, &_actuators);
|
_actuators_0_pub = orb_advertise(_actuators_id, &_actuators);
|
||||||
|
|||||||
@@ -168,7 +168,6 @@ private:
|
|||||||
perf_counter_t _sample_perf;
|
perf_counter_t _sample_perf;
|
||||||
perf_counter_t _good_transfers;
|
perf_counter_t _good_transfers;
|
||||||
perf_counter_t _reset_retries;
|
perf_counter_t _reset_retries;
|
||||||
perf_counter_t _controller_latency_perf;
|
|
||||||
|
|
||||||
Integrator _accel_int;
|
Integrator _accel_int;
|
||||||
Integrator _gyro_int;
|
Integrator _gyro_int;
|
||||||
@@ -323,7 +322,6 @@ GYROSIM::GYROSIM(const char *path_accel, const char *path_gyro, enum Rotation ro
|
|||||||
_sample_perf(perf_alloc(PC_ELAPSED, "gyrosim_read")),
|
_sample_perf(perf_alloc(PC_ELAPSED, "gyrosim_read")),
|
||||||
_good_transfers(perf_alloc(PC_COUNT, "gyrosim_good_transfers")),
|
_good_transfers(perf_alloc(PC_COUNT, "gyrosim_good_transfers")),
|
||||||
_reset_retries(perf_alloc(PC_COUNT, "gyrosim_reset_retries")),
|
_reset_retries(perf_alloc(PC_COUNT, "gyrosim_reset_retries")),
|
||||||
_controller_latency_perf(perf_alloc_once(PC_ELAPSED, "ctrl_latency")),
|
|
||||||
_accel_int(1000000 / GYROSIM_ACCEL_DEFAULT_RATE, true),
|
_accel_int(1000000 / GYROSIM_ACCEL_DEFAULT_RATE, true),
|
||||||
_gyro_int(1000000 / GYROSIM_GYRO_DEFAULT_RATE, true),
|
_gyro_int(1000000 / GYROSIM_GYRO_DEFAULT_RATE, true),
|
||||||
_rotation(rotation),
|
_rotation(rotation),
|
||||||
@@ -1093,8 +1091,6 @@ GYROSIM::_measure()
|
|||||||
|
|
||||||
if (accel_notify) {
|
if (accel_notify) {
|
||||||
if (!(_pub_blocked)) {
|
if (!(_pub_blocked)) {
|
||||||
/* log the time of this report */
|
|
||||||
perf_begin(_controller_latency_perf);
|
|
||||||
/* publish it */
|
/* publish it */
|
||||||
orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb);
|
orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,9 +86,9 @@ UavcanNode::UavcanNode(uavcan::ICanDriver &can_driver, uavcan::ISystemClock &sys
|
|||||||
_time_sync_master(_node),
|
_time_sync_master(_node),
|
||||||
_time_sync_slave(_node),
|
_time_sync_slave(_node),
|
||||||
_node_status_monitor(_node),
|
_node_status_monitor(_node),
|
||||||
|
_perf_control_latency(perf_alloc(PC_ELAPSED, "uavcan control latency")),
|
||||||
_master_timer(_node),
|
_master_timer(_node),
|
||||||
_setget_response(0)
|
_setget_response(0)
|
||||||
|
|
||||||
{
|
{
|
||||||
_task_should_exit = false;
|
_task_should_exit = false;
|
||||||
_fw_server_action = None;
|
_fw_server_action = None;
|
||||||
@@ -162,6 +162,8 @@ UavcanNode::~UavcanNode()
|
|||||||
if (_mixers != nullptr) {
|
if (_mixers != nullptr) {
|
||||||
delete _mixers;
|
delete _mixers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
perf_free(_perf_control_latency);
|
||||||
}
|
}
|
||||||
|
|
||||||
int UavcanNode::getHardwareVersion(uavcan::protocol::HardwareVersion &hwver)
|
int UavcanNode::getHardwareVersion(uavcan::protocol::HardwareVersion &hwver)
|
||||||
@@ -964,8 +966,19 @@ int UavcanNode::run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Output to the bus
|
// Output to the bus
|
||||||
_outputs.timestamp = hrt_absolute_time();
|
|
||||||
_esc_controller.update_outputs(_outputs.output, _outputs.noutputs);
|
_esc_controller.update_outputs(_outputs.output, _outputs.noutputs);
|
||||||
|
_outputs.timestamp = hrt_absolute_time();
|
||||||
|
|
||||||
|
// use first valid timestamp_sample for latency tracking
|
||||||
|
for (int i = 0; i < actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS; i++) {
|
||||||
|
const bool required = _groups_required & (1 << i);
|
||||||
|
const hrt_abstime ×tamp_sample = _controls[i].timestamp_sample;
|
||||||
|
|
||||||
|
if (required && (timestamp_sample > 0)) {
|
||||||
|
perf_set_elapsed(_perf_control_latency, _outputs.timestamp - timestamp_sample);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -208,6 +208,8 @@ private:
|
|||||||
|
|
||||||
actuator_outputs_s _outputs = {};
|
actuator_outputs_s _outputs = {};
|
||||||
|
|
||||||
|
perf_counter_t _perf_control_latency;
|
||||||
|
|
||||||
bool _airmode = false;
|
bool _airmode = false;
|
||||||
|
|
||||||
// index into _poll_fds for each _control_subs handle
|
// index into _poll_fds for each _control_subs handle
|
||||||
|
|||||||
@@ -398,7 +398,8 @@ void Standard::update_fw_state()
|
|||||||
void Standard::fill_actuator_outputs()
|
void Standard::fill_actuator_outputs()
|
||||||
{
|
{
|
||||||
// multirotor controls
|
// multirotor controls
|
||||||
_actuators_out_0->timestamp = _actuators_mc_in->timestamp;
|
_actuators_out_0->timestamp = hrt_absolute_time();
|
||||||
|
_actuators_out_0->timestamp_sample = _actuators_mc_in->timestamp_sample;
|
||||||
|
|
||||||
// roll
|
// roll
|
||||||
_actuators_out_0->control[actuator_controls_s::INDEX_ROLL] =
|
_actuators_out_0->control[actuator_controls_s::INDEX_ROLL] =
|
||||||
@@ -415,7 +416,8 @@ void Standard::fill_actuator_outputs()
|
|||||||
|
|
||||||
|
|
||||||
// fixed wing controls
|
// fixed wing controls
|
||||||
_actuators_out_1->timestamp = _actuators_fw_in->timestamp;
|
_actuators_out_1->timestamp = hrt_absolute_time();
|
||||||
|
_actuators_out_1->timestamp_sample = _actuators_fw_in->timestamp_sample;
|
||||||
|
|
||||||
if (_vtol_schedule.flight_mode != MC_MODE) {
|
if (_vtol_schedule.flight_mode != MC_MODE) {
|
||||||
// roll
|
// roll
|
||||||
|
|||||||
@@ -271,9 +271,14 @@ void Tailsitter::update_fw_state()
|
|||||||
*/
|
*/
|
||||||
void Tailsitter::fill_actuator_outputs()
|
void Tailsitter::fill_actuator_outputs()
|
||||||
{
|
{
|
||||||
|
_actuators_out_0->timestamp = hrt_absolute_time();
|
||||||
|
_actuators_out_0->timestamp_sample = _actuators_mc_in->timestamp_sample;
|
||||||
|
|
||||||
|
_actuators_out_1->timestamp = hrt_absolute_time();
|
||||||
|
_actuators_out_1->timestamp_sample = _actuators_fw_in->timestamp_sample;
|
||||||
|
|
||||||
switch (_vtol_mode) {
|
switch (_vtol_mode) {
|
||||||
case ROTARY_WING:
|
case ROTARY_WING:
|
||||||
_actuators_out_0->timestamp = _actuators_mc_in->timestamp;
|
|
||||||
_actuators_out_0->control[actuator_controls_s::INDEX_ROLL] = _actuators_mc_in->control[actuator_controls_s::INDEX_ROLL];
|
_actuators_out_0->control[actuator_controls_s::INDEX_ROLL] = _actuators_mc_in->control[actuator_controls_s::INDEX_ROLL];
|
||||||
_actuators_out_0->control[actuator_controls_s::INDEX_PITCH] =
|
_actuators_out_0->control[actuator_controls_s::INDEX_PITCH] =
|
||||||
_actuators_mc_in->control[actuator_controls_s::INDEX_PITCH];
|
_actuators_mc_in->control[actuator_controls_s::INDEX_PITCH];
|
||||||
@@ -281,8 +286,6 @@ void Tailsitter::fill_actuator_outputs()
|
|||||||
_actuators_out_0->control[actuator_controls_s::INDEX_THROTTLE] =
|
_actuators_out_0->control[actuator_controls_s::INDEX_THROTTLE] =
|
||||||
_actuators_mc_in->control[actuator_controls_s::INDEX_THROTTLE];
|
_actuators_mc_in->control[actuator_controls_s::INDEX_THROTTLE];
|
||||||
|
|
||||||
_actuators_out_1->timestamp = _actuators_mc_in->timestamp;
|
|
||||||
|
|
||||||
if (_params->elevons_mc_lock) {
|
if (_params->elevons_mc_lock) {
|
||||||
_actuators_out_1->control[0] = 0;
|
_actuators_out_1->control[0] = 0;
|
||||||
_actuators_out_1->control[1] = 0;
|
_actuators_out_1->control[1] = 0;
|
||||||
@@ -299,7 +302,6 @@ void Tailsitter::fill_actuator_outputs()
|
|||||||
|
|
||||||
case FIXED_WING:
|
case FIXED_WING:
|
||||||
// in fixed wing mode we use engines only for providing thrust, no moments are generated
|
// in fixed wing mode we use engines only for providing thrust, no moments are generated
|
||||||
_actuators_out_0->timestamp = _actuators_fw_in->timestamp;
|
|
||||||
_actuators_out_0->control[actuator_controls_s::INDEX_ROLL] = 0;
|
_actuators_out_0->control[actuator_controls_s::INDEX_ROLL] = 0;
|
||||||
_actuators_out_0->control[actuator_controls_s::INDEX_PITCH] = 0;
|
_actuators_out_0->control[actuator_controls_s::INDEX_PITCH] = 0;
|
||||||
_actuators_out_0->control[actuator_controls_s::INDEX_YAW] = 0;
|
_actuators_out_0->control[actuator_controls_s::INDEX_YAW] = 0;
|
||||||
@@ -319,8 +321,6 @@ void Tailsitter::fill_actuator_outputs()
|
|||||||
case TRANSITION_TO_FW:
|
case TRANSITION_TO_FW:
|
||||||
case TRANSITION_TO_MC:
|
case TRANSITION_TO_MC:
|
||||||
// in transition engines are mixed by weight (BACK TRANSITION ONLY)
|
// in transition engines are mixed by weight (BACK TRANSITION ONLY)
|
||||||
_actuators_out_0->timestamp = _actuators_mc_in->timestamp;
|
|
||||||
_actuators_out_1->timestamp = _actuators_mc_in->timestamp;
|
|
||||||
_actuators_out_0->control[actuator_controls_s::INDEX_ROLL] = _actuators_mc_in->control[actuator_controls_s::INDEX_ROLL]
|
_actuators_out_0->control[actuator_controls_s::INDEX_ROLL] = _actuators_mc_in->control[actuator_controls_s::INDEX_ROLL]
|
||||||
* _mc_roll_weight;
|
* _mc_roll_weight;
|
||||||
_actuators_out_0->control[actuator_controls_s::INDEX_PITCH] =
|
_actuators_out_0->control[actuator_controls_s::INDEX_PITCH] =
|
||||||
|
|||||||
@@ -336,7 +336,9 @@ void Tiltrotor::waiting_on_tecs()
|
|||||||
*/
|
*/
|
||||||
void Tiltrotor::fill_actuator_outputs()
|
void Tiltrotor::fill_actuator_outputs()
|
||||||
{
|
{
|
||||||
_actuators_out_0->timestamp = _actuators_mc_in->timestamp;
|
_actuators_out_0->timestamp = hrt_absolute_time();
|
||||||
|
_actuators_out_0->timestamp_sample = _actuators_mc_in->timestamp_sample;
|
||||||
|
|
||||||
_actuators_out_0->control[actuator_controls_s::INDEX_ROLL] = _actuators_mc_in->control[actuator_controls_s::INDEX_ROLL]
|
_actuators_out_0->control[actuator_controls_s::INDEX_ROLL] = _actuators_mc_in->control[actuator_controls_s::INDEX_ROLL]
|
||||||
* _mc_roll_weight;
|
* _mc_roll_weight;
|
||||||
_actuators_out_0->control[actuator_controls_s::INDEX_PITCH] =
|
_actuators_out_0->control[actuator_controls_s::INDEX_PITCH] =
|
||||||
@@ -359,7 +361,9 @@ void Tiltrotor::fill_actuator_outputs()
|
|||||||
_actuators_mc_in->control[actuator_controls_s::INDEX_THROTTLE];
|
_actuators_mc_in->control[actuator_controls_s::INDEX_THROTTLE];
|
||||||
}
|
}
|
||||||
|
|
||||||
_actuators_out_1->timestamp = _actuators_fw_in->timestamp;
|
_actuators_out_1->timestamp = hrt_absolute_time();
|
||||||
|
_actuators_out_1->timestamp_sample = _actuators_fw_in->timestamp_sample;
|
||||||
|
|
||||||
_actuators_out_1->control[actuator_controls_s::INDEX_ROLL] =
|
_actuators_out_1->control[actuator_controls_s::INDEX_ROLL] =
|
||||||
-_actuators_fw_in->control[actuator_controls_s::INDEX_ROLL];
|
-_actuators_fw_in->control[actuator_controls_s::INDEX_ROLL];
|
||||||
_actuators_out_1->control[actuator_controls_s::INDEX_PITCH] =
|
_actuators_out_1->control[actuator_controls_s::INDEX_PITCH] =
|
||||||
|
|||||||
Reference in New Issue
Block a user