39 #include <px4_platform_common/log.h> 46 bool support_esc_calibration,
bool ramp_up)
47 : ModuleParams(&interface),
49 {&interface,
ORB_ID(actuator_controls_0)},
50 {&interface,
ORB_ID(actuator_controls_1)},
51 {&interface,
ORB_ID(actuator_controls_2)},
52 {&interface,
ORB_ID(actuator_controls_3)}
71 px4_sem_init(&
_lock, 0, 1);
76 test_motor_pub.publish(
test);
84 px4_sem_destroy(&
_lock);
90 PX4_INFO(
"Switched to rate_ctrl work queue: %i", (
int)
_wq_switched);
91 PX4_INFO(
"Mixer loaded: %s",
_mixers ?
"yes" :
"no");
94 PX4_INFO(
"Channel Configuration:");
98 PX4_INFO(
"Channel %i: value: %i, failsafe: %d, disarmed: %d, min: %d, max: %d", reordered_i,
_current_output_value[i],
105 ModuleParams::updateParams();
136 if (allow_wq_switch && !
_wq_switched && (sub_group_0 || sub_group_1)) {
137 if (
_interface.ChangeWorkQeue(px4::wq_configurations::rate_ctrl)) {
147 for (
unsigned i = 0; i < actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS; i++) {
149 PX4_DEBUG(
"subscribe to actuator_controls_%d", i);
152 PX4_ERR(
"actuator_controls_%d register callback failed!", i);
179 for (
unsigned i = 0; i < actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS; i++) {
217 control_sub.unregisterCallback();
229 const float delta_out_max = 2.0f * 1000.0f * dt / (
_max_value[0] -
_min_value[0]) / _param_mot_slew_max.get();
237 bool had_update =
false;
246 bool in_test_mode = test_motor.
action == test_motor_s::ACTION_RUN;
259 if (test_motor.
value < 0.f) {
325 if (num_motor_test > 0) {
340 unsigned n_updates = 0;
343 for (
unsigned i = 0; i < actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS; i++) {
374 for (
size_t i = 0; i < mixed_num_outputs; i++) {
383 for (
size_t i = 0; i < mixed_num_outputs; i++) {
410 actuator_outputs.
noutputs = num_outputs;
412 for (
size_t i = 0; i < num_outputs; ++i) {
439 for (
int i = 0; i < actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS; i++) {
443 if (required && (timestamp_sample > 0)) {
453 if (MAX_ACTUATORS < 4) {
464 const uint16_t value_tmp[4] = {values[0], values[1], values[2], values[3] };
465 values[0] = value_tmp[3];
466 values[1] = value_tmp[0];
467 values[2] = value_tmp[1];
468 values[3] = value_tmp[2];
505 }
else if (input < -1.0
f) {
511 if ((control_group == actuator_controls_s::GROUP_INDEX_ATTITUDE ||
512 control_group == actuator_controls_s::GROUP_INDEX_ATTITUDE_ALTERNATE) &&
513 control_index == actuator_controls_s::INDEX_THROTTLE) {
523 if ((control_group == actuator_controls_s::GROUP_INDEX_ATTITUDE ||
524 control_group == actuator_controls_s::GROUP_INDEX_ATTITUDE_ALTERNATE) &&
525 control_index == actuator_controls_s::INDEX_THROTTLE) {
559 PX4_ERR(
"mixer load failed with %d", ret);
567 PX4_DEBUG(
"loaded mixers \n%s\n", buf);
603 PX4_ERR(
"Command not None");
627 PX4_ERR(
"Command not None");
int load_from_buf(Mixer::ControlCallback control_cb, uintptr_t cb_handle, const char *buf, unsigned &buflen)
Adds mixers to the group based on a text description in a buffer.
constexpr _Tp constrain(_Tp val, _Tp min_val, _Tp max_val)
bool _ignore_lockdown
if true, ignore the _armed.lockdown flag (for HIL outputs)
Queued publication with queue length set as a message constant (ORB_QUEUE_LENGTH) ...
perf_counter_t _control_latency_perf
actuator_controls_s _controls[actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS]
void output_limit_calc(const bool armed, const bool pre_armed, const unsigned num_channels, const uint16_t reverse_mask, const uint16_t *disarmed_output, const uint16_t *min_output, const uint16_t *max_output, const float *output, uint16_t *effective_output, output_limit_t *limit)
uORB::Subscription test_motor_sub
uint16_t get_saturation_status()
uint16_t _current_output_value[MAX_ACTUATORS]
current output values (reordered)
void updateOutputSlewrate()
measure the time elapsed performing an event
int loadMixer(const char *buf, unsigned len)
bool ramp_up
if true, motors will ramp up from disarmed to min_output after arming
void updateParams() override
void setMaxTopicUpdateRate(unsigned max_topic_update_interval_us)
void perf_set_elapsed(perf_counter_t handle, int64_t elapsed)
Register a measurement.
bool update()
Call this regularly from Run().
px4::atomic< int > command
unsigned _max_topic_update_interval_us
max _control_subs topic update interval (0=unlimited)
static int controlCallback(uintptr_t handle, uint8_t control_group, uint8_t control_index, float &input)
static constexpr int MAX_ACTUATORS
hrt_abstime _time_last_mix
void set_interval_us(uint32_t interval)
Set the interval in microseconds.
bool updateSubscriptions(bool allow_wq_switch)
Check for subscription updates (e.g.
void publishMixerStatus(const actuator_outputs_s &actuator_outputs)
uORB::SubscriptionCallbackWorkItem _control_subs[actuator_controls_s::NUM_ACTUATOR_CONTROL_GROUPS]
const SchedulingPolicy _scheduling_policy
Command _command
incoming commands (from another thread)
uint16_t _failsafe_value[MAX_ACTUATORS]
void set_max_delta_out_once(float delta_out_max)
Update slew rate parameter.
void updateLatencyPerfCounter(const actuator_outputs_s &actuator_outputs)
uORB::Subscription _armed_sub
bool in_esc_calibration_mode
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
uint16_t saturation_status
enum output_limit_state state
void reorderOutputs(uint16_t values[MAX_ACTUATORS])
Reorder outputs according to _param_mot_ordering.
Drive scheduling based on subscribed actuator controls topics (via uORB callbacks) ...
uint16_t _max_value[MAX_ACTUATORS]
void perf_free(perf_counter_t handle)
Free a counter.
uint8_t _driver_instance
for boards that supports multiple outputs (e.g. PX4IO + FMU)
OutputModuleInterface & _interface
void setAndPublishActuatorOutputs(unsigned num_outputs, actuator_outputs_s &actuator_outputs)
void set_thrust_factor(float val)
Sets the thrust factor used to calculate mapping from desired thrust to motor control signal output...
virtual void mixerChanged()
called whenever the mixer gets updated/reset
void setAllFailsafeValues(uint16_t value)
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.
uORB::PublicationMulti< actuator_outputs_s > _outputs_pub
void resetMixerThreadSafe()
Reset (unload) the complete mixer, called from another thread.
void test(enum LPS25H_BUS busid)
Perform some basic functional tests on the driver; make sure we can collect data from the sensor in p...
uint64_t timestamp_sample
int reorderedMotorIndex(int index) const
Get the motor index that maps from PX4 convention to the configured one.
Base class for an output module.
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
int loadMixerThreadSafe(const char *buf, unsigned len)
Load (append) a new mixer from a buffer, called from another thread.
uint16_t _reverse_output_mask
reverses the interval [min, max] -> [max, min], NOT motor direction
uint16_t _disarmed_value[MAX_ACTUATORS]
bool armNoThrottle() const
void setAllMaxValues(uint16_t value)
void groups_required(uint32_t &groups)
uint32_t _groups_required
void set_airmode(Mixer::Airmode airmode)
uint32_t _groups_subscribed
initialize to a different value than _groups_required and outside of (1 << NUM_ACTUATOR_CONTROL_GROUP...
px4_sem_t _lock
lock to protect access to work queue changes (includes ScheduleNow calls from another thread) ...
void perf_print_counter(perf_counter_t handle)
Print one performance counter to stdout.
void output_limit_init(output_limit_t *limit)
void setAllDisarmedValues(uint16_t value)
unsigned mix(float *outputs, unsigned space)
uint16_t _min_value[MAX_ACTUATORS]
bool update(void *dst)
Update the struct.
virtual bool updateOutputs(bool stop_motors, uint16_t outputs[MAX_ACTUATORS], unsigned num_outputs, unsigned num_control_groups_updated)=0
Callback to update the (physical) actuator outputs in the driver.
Group of mixers, built up from single mixers and processed in order when mixing.
void unregister()
unregister uORB subscription callbacks
uORB::PublicationMulti< multirotor_motor_limits_s > _to_mixer_status
mixer status flags
bool publish(const T &data)
Publish the struct.
unsigned mixer_buf_length
MixingOutput(uint8_t max_num_outputs, OutputModuleInterface &interface, SchedulingPolicy scheduling_policy, bool support_esc_calibration, bool ramp_up=true)
Contructor.
const uint8_t _max_num_outputs
This handles the mixing, arming/disarming and all subscriptions required for that.
struct MultirotorMixer::saturation_status::@66 flags
output_limit_t _output_limit
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
const bool _support_esc_calibration
void setAllMinValues(uint16_t value)