[RFC] broadcast parameter changes and ModuleParams skip full updateParams() when possible

This commit is contained in:
Daniel Agar
2022-12-19 21:14:04 -05:00
parent b6157c89a0
commit 9586ad0006
54 changed files with 289 additions and 549 deletions
@@ -42,6 +42,8 @@
#include <containers/List.hpp>
#include "param.h"
#include <uORB/Subscription.hpp>
#include <uORB/topics/parameter_update.h>
class ModuleParams : public ListNode<ModuleParams *>
{
@@ -68,6 +70,8 @@ public:
virtual ~ModuleParams()
{
if (_parent) { _parent->_children.remove(this); }
_parameter_update_sub.unsubscribe();
}
// Disallow copy construction and move assignment.
@@ -83,20 +87,75 @@ protected:
*/
virtual void updateParams()
{
for (const auto &child : _children) {
child->updateParams();
bool update_all = true;
int parameter_updates = 0;
while (_parameter_update_sub.updated() && (parameter_updates < parameter_update_s::ORB_QUEUE_LENGTH)) {
parameter_updates++;
parameter_update_s parameter_update;
if (_parameter_update_sub.copy(&parameter_update)
&& (_parameter_update_instance > 0)
&& (parameter_update.instance == _parameter_update_instance + 1)
&& (parameter_update.changed_param.index >= 0)
&& (static_cast<uint16_t>(parameter_update.changed_param.index) != PARAM_INVALID)
) {
update_all = false;
for (const auto &child : _children) {
child->updateParams(parameter_update);
}
updateParamsImpl(parameter_update);
_parameter_update_instance = parameter_update.instance;
} else {
update_all = true;
break;
}
}
updateParamsImpl();
if (update_all) {
PX4_DEBUG("updateParams: updating all params");
parameter_update_s parameter_update;
if (_parameter_update_sub.copy(&parameter_update)) {
_parameter_update_instance = parameter_update.instance;
}
for (const auto &child : _children) {
child->updateParams();
}
updateParamsImpl();
} else {
PX4_DEBUG("updateParams: updating all params skipped");
}
}
virtual void updateParams(const parameter_update_s &parameter_update)
{
for (const auto &child : _children) {
child->updateParams(parameter_update);
}
updateParamsImpl(parameter_update);
}
/**
* @brief The implementation for this is generated with the macro DEFINE_PARAMETERS()
*/
virtual void updateParamsImpl() {}
virtual void updateParamsImpl(const parameter_update_s &parameter_update) {}
private:
/** @list _children The module parameter list of inheriting classes. */
List<ModuleParams *> _children;
ModuleParams *_parent{nullptr};
uORB::Subscription _parameter_update_sub{ORB_ID(parameter_update)};
uint32_t _parameter_update_instance{0};
};
@@ -44,11 +44,13 @@
#include <math.h>
#include <parameters/px4_parameters.hpp>
#include <uORB/topics/parameter.h>
#include <uORB/topics/parameter_update.h>
/**
* get the parameter handle from a parameter enum
*/
inline static param_t param_handle(px4::params p)
inline static constexpr param_t param_handle(px4::params p)
{
return (param_t)p;
}
@@ -62,6 +64,9 @@ inline static param_t param_handle(px4::params p)
#define _CALL_UPDATE(x) \
STRIP(x).update();
#define _SET_PARAMETER_UPDATE(x) \
case STRIP(x).handle(): STRIP(x).setValue(parameter_update.changed_param); return;
// define the parameter update method, which will update all parameters.
// It is marked as 'final', so that wrong usages lead to a compile error (see below)
#define _DEFINE_PARAMETER_UPDATE_METHOD(...) \
@@ -69,6 +74,11 @@ inline static param_t param_handle(px4::params p)
void updateParamsImpl() final { \
APPLY_ALL(_CALL_UPDATE, __VA_ARGS__) \
} \
void updateParamsImpl(const parameter_update_s &parameter_update) { \
switch(parameter_update.changed_param.index) { \
APPLY_ALL(_SET_PARAMETER_UPDATE, __VA_ARGS__) \
} \
} \
private:
// Define a list of parameters. This macro also creates code to update parameters.
@@ -88,6 +98,12 @@ inline static param_t param_handle(px4::params p)
parent_class::updateParamsImpl(); \
APPLY_ALL(_CALL_UPDATE, __VA_ARGS__) \
} \
void updateParamsImpl(const parameter_update_s &parameter_update) { \
parent_class::updateParamsImpl(parameter_update); \
switch(parameter_update.changed_param.index) { \
APPLY_ALL(_SET_PARAMETER_UPDATE, __VA_ARGS__) \
} \
} \
private:
#define DEFINE_PARAMETERS_CUSTOM_PARENT(parent_class, ...) \
@@ -118,7 +134,6 @@ public:
Param()
{
param_set_used(handle());
update();
}
@@ -126,29 +141,22 @@ public:
const float &reference() const { return _val; }
/// Store the parameter value to the parameter storage (@see param_set())
bool commit() const { return param_set(handle(), &_val) == 0; }
/// Store the parameter value to the parameter storage, w/o notifying the system (@see param_set_no_notification())
bool commit_no_notification() const { return param_set_no_notification(handle(), &_val) == 0; }
/// Set and commit a new value. Returns true if the value changed.
bool commit_no_notification(float val)
bool set(float val)
{
if (fabsf(val - _val) > FLT_EPSILON) {
set(val);
commit_no_notification();
return true;
_val = val;
return (param_set(handle(), &_val) == 0);
}
return false;
}
void set(float val) { _val = val; }
bool update() { return param_get(handle(), &_val) == 0; }
param_t handle() const { return param_handle(p); }
void setValue(const parameter_s &parameter_update) { _val = parameter_update.float32_value; }
static constexpr param_t handle() { return param_handle(p); }
private:
float _val;
};
@@ -164,7 +172,6 @@ public:
Param(float &external_val)
: _val(external_val)
{
param_set_used(handle());
update();
}
@@ -172,29 +179,18 @@ public:
const float &reference() const { return _val; }
/// Store the parameter value to the parameter storage (@see param_set())
bool commit() const { return param_set(handle(), &_val) == 0; }
/// Store the parameter value to the parameter storage, w/o notifying the system (@see param_set_no_notification())
bool commit_no_notification() const { return param_set_no_notification(handle(), &_val) == 0; }
/// Set and commit a new value. Returns true if the value changed.
bool commit_no_notification(float val)
bool set(float val)
{
if (fabsf(val - _val) > FLT_EPSILON) {
set(val);
commit_no_notification();
return true;
}
return false;
_val = val;
return (param_set(handle(), &_val) == 0);
}
void set(float val) { _val = val; }
bool update() { return param_get(handle(), &_val) == 0; }
param_t handle() const { return param_handle(p); }
void setValue(const parameter_s &parameter_update) { _val = parameter_update.float32_value; }
static constexpr param_t handle() { return param_handle(p); }
private:
float &_val;
};
@@ -208,7 +204,6 @@ public:
Param()
{
param_set_used(handle());
update();
}
@@ -216,29 +211,18 @@ public:
const int32_t &reference() const { return _val; }
/// Store the parameter value to the parameter storage (@see param_set())
bool commit() const { return param_set(handle(), &_val) == 0; }
/// Store the parameter value to the parameter storage, w/o notifying the system (@see param_set_no_notification())
bool commit_no_notification() const { return param_set_no_notification(handle(), &_val) == 0; }
/// Set and commit a new value. Returns true if the value changed.
bool commit_no_notification(int32_t val)
bool set(int32_t val)
{
if (val != _val) {
set(val);
commit_no_notification();
return true;
}
return false;
_val = val;
return (param_set(handle(), &_val) == 0);
}
void set(int32_t val) { _val = val; }
bool update() { return param_get(handle(), &_val) == 0; }
param_t handle() const { return param_handle(p); }
void setValue(const parameter_s &parameter_update) { _val = parameter_update.int32_value; }
static constexpr param_t handle() { return param_handle(p); }
private:
int32_t _val;
};
@@ -254,7 +238,6 @@ public:
Param(int32_t &external_val)
: _val(external_val)
{
param_set_used(handle());
update();
}
@@ -263,28 +246,17 @@ public:
const int32_t &reference() const { return _val; }
/// Store the parameter value to the parameter storage (@see param_set())
bool commit() const { return param_set(handle(), &_val) == 0; }
/// Store the parameter value to the parameter storage, w/o notifying the system (@see param_set_no_notification())
bool commit_no_notification() const { return param_set_no_notification(handle(), &_val) == 0; }
/// Set and commit a new value. Returns true if the value changed.
bool commit_no_notification(int32_t val)
bool set(int32_t val)
{
if (val != _val) {
set(val);
commit_no_notification();
return true;
}
return false;
_val = val;
return (param_set(handle(), &_val) == 0);
}
void set(int32_t val) { _val = val; }
bool update() { return param_get(handle(), &_val) == 0; }
param_t handle() const { return param_handle(p); }
void setValue(const parameter_s &parameter_update) { _val = parameter_update.int32_value; }
static constexpr param_t handle() { return param_handle(p); }
private:
int32_t &_val;
};
@@ -298,7 +270,6 @@ public:
Param()
{
param_set_used(handle());
update();
}
@@ -306,34 +277,14 @@ public:
const bool &reference() const { return _val; }
/// Store the parameter value to the parameter storage (@see param_set())
bool commit() const
{
int32_t value_int = (int32_t)_val;
return param_set(handle(), &value_int) == 0;
}
/// Store the parameter value to the parameter storage, w/o notifying the system (@see param_set_no_notification())
bool commit_no_notification() const
{
int32_t value_int = (int32_t)_val;
return param_set_no_notification(handle(), &value_int) == 0;
}
/// Set and commit a new value. Returns true if the value changed.
bool commit_no_notification(bool val)
bool set(bool val)
{
if (val != _val) {
set(val);
commit_no_notification();
return true;
}
return false;
_val = val;
int32_t value_int = (int32_t)_val;
return (param_set(handle(), &value_int) == 0);
}
void set(bool val) { _val = val; }
bool update()
{
int32_t value_int;
@@ -347,7 +298,9 @@ public:
return false;
}
param_t handle() const { return param_handle(p); }
void setValue(const parameter_s &parameter_update) { _val = parameter_update.int32_value; }
static constexpr param_t handle() { return param_handle(p); }
private:
bool _val;
};