mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-28 19:32:36 +08:00
Syntax change to improve readability; output scalers are now labelled O: instead of looking like control scalers.
Make mixer terminology more consistent; mixer inputs are 'controls'.
This commit is contained in:
@@ -81,7 +81,7 @@ struct mixer_scaler_s
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** mixer input */
|
/** mixer input */
|
||||||
struct mixer_input_s
|
struct mixer_control_s
|
||||||
{
|
{
|
||||||
uint8_t control_group; /**< group from which the input reads */
|
uint8_t control_group; /**< group from which the input reads */
|
||||||
uint8_t control_index; /**< index within the control group */
|
uint8_t control_index; /**< index within the control group */
|
||||||
@@ -91,12 +91,12 @@ struct mixer_input_s
|
|||||||
/** simple mixer */
|
/** simple mixer */
|
||||||
struct mixer_simple_s
|
struct mixer_simple_s
|
||||||
{
|
{
|
||||||
uint8_t input_count; /**< number of inputs */
|
uint8_t control_count; /**< number of inputs */
|
||||||
struct mixer_scaler_s output_scaler; /**< scaling for the output */
|
struct mixer_scaler_s output_scaler; /**< scaling for the output */
|
||||||
struct mixer_input_s inputs[0]; /**< actual size of the array is set by input_count */
|
struct mixer_control_s controls[0]; /**< actual size of the array is set by control_count */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MIXER_SIMPLE_SIZE(_icount) (sizeof(struct mixer_simple_s) + (_icount) * sizeof(struct mixer_input_s))
|
#define MIXER_SIMPLE_SIZE(_icount) (sizeof(struct mixer_simple_s) + (_icount) * sizeof(struct mixer_control_s))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add a simple mixer in (struct mixer_simple_s *)arg
|
* add a simple mixer in (struct mixer_simple_s *)arg
|
||||||
@@ -114,7 +114,7 @@ struct mixer_rotor_output_s
|
|||||||
struct mixer_multirotor_s
|
struct mixer_multirotor_s
|
||||||
{
|
{
|
||||||
uint8_t rotor_count;
|
uint8_t rotor_count;
|
||||||
struct mixer_input_s inputs[4]; /**< inputs are roll, pitch, yaw, thrust */
|
struct mixer_control_s controls[4]; /**< controls are roll, pitch, yaw, thrust */
|
||||||
struct mixer_rotor_output_s rotors[0]; /**< actual size of the array is set by rotor_count */
|
struct mixer_rotor_output_s rotors[0]; /**< actual size of the array is set by rotor_count */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -151,15 +151,15 @@ SimpleMixer::mix(float *outputs, unsigned space)
|
|||||||
if (space < 1)
|
if (space < 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < _info->input_count; i++) {
|
for (unsigned i = 0; i < _info->control_count; i++) {
|
||||||
float input;
|
float input;
|
||||||
|
|
||||||
_control_cb(_cb_handle,
|
_control_cb(_cb_handle,
|
||||||
_info->inputs[i].control_group,
|
_info->controls[i].control_group,
|
||||||
_info->inputs[i].control_index,
|
_info->controls[i].control_index,
|
||||||
input);
|
input);
|
||||||
|
|
||||||
sum += scale(_info->inputs[i].scaler, input);
|
sum += scale(_info->controls[i].scaler, input);
|
||||||
}
|
}
|
||||||
*outputs = scale(_info->output_scaler, sum);
|
*outputs = scale(_info->output_scaler, sum);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -168,8 +168,8 @@ SimpleMixer::mix(float *outputs, unsigned space)
|
|||||||
void
|
void
|
||||||
SimpleMixer::groups_required(uint32_t &groups)
|
SimpleMixer::groups_required(uint32_t &groups)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < _info->input_count; i++)
|
for (unsigned i = 0; i < _info->control_count; i++)
|
||||||
groups |= 1 << _info->inputs[i].control_group;
|
groups |= 1 << _info->controls[i].control_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -180,7 +180,7 @@ SimpleMixer::check()
|
|||||||
|
|
||||||
/* sanity that presumes that a mixer includes a control no more than once */
|
/* sanity that presumes that a mixer includes a control no more than once */
|
||||||
/* max of 32 groups due to groups_required API */
|
/* max of 32 groups due to groups_required API */
|
||||||
if (_info->input_count > 32)
|
if (_info->control_count > 32)
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
/* validate the output scaler */
|
/* validate the output scaler */
|
||||||
@@ -190,18 +190,18 @@ SimpleMixer::check()
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* validate input scalers */
|
/* validate input scalers */
|
||||||
for (unsigned i = 0; i < _info->input_count; i++) {
|
for (unsigned i = 0; i < _info->control_count; i++) {
|
||||||
|
|
||||||
/* verify that we can fetch the control */
|
/* verify that we can fetch the control */
|
||||||
if (_control_cb(_cb_handle,
|
if (_control_cb(_cb_handle,
|
||||||
_info->inputs[i].control_group,
|
_info->controls[i].control_group,
|
||||||
_info->inputs[i].control_index,
|
_info->controls[i].control_index,
|
||||||
junk) != 0) {
|
junk) != 0) {
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* validate the scaler */
|
/* validate the scaler */
|
||||||
ret = scale_check(_info->inputs[i].scaler);
|
ret = scale_check(_info->controls[i].scaler);
|
||||||
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return (10 * i + ret);
|
return (10 * i + ret);
|
||||||
|
|||||||
@@ -53,6 +53,9 @@
|
|||||||
|
|
||||||
#include "mixer.h"
|
#include "mixer.h"
|
||||||
|
|
||||||
|
#define debug(fmt, args...) do { } while(0)
|
||||||
|
//#define debug(fmt, args...) do { printf("[mixer] " fmt "\n", ##args); } while(0)
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -76,8 +79,10 @@ mixer_getline(int fd, char *line, unsigned maxlen)
|
|||||||
ret = read(fd, &c, 1);
|
ret = read(fd, &c, 1);
|
||||||
|
|
||||||
/* on error or EOF, return same */
|
/* on error or EOF, return same */
|
||||||
if (ret <= 0)
|
if (ret <= 0) {
|
||||||
|
debug("read: EOF");
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* ignore carriage returns */
|
/* ignore carriage returns */
|
||||||
if (c == '\r')
|
if (c == '\r')
|
||||||
@@ -94,6 +99,7 @@ mixer_getline(int fd, char *line, unsigned maxlen)
|
|||||||
|
|
||||||
/* terminate line as string and return */
|
/* terminate line as string and return */
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
debug("read: '%s'", line);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,17 +111,42 @@ mixer_getline(int fd, char *line, unsigned maxlen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a scaler from the buffer.
|
* Parse an output scaler from the buffer.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
mixer_parse_scaler(const char *buf, mixer_scaler_s &scaler, uint8_t &control_group, uint8_t &control_index)
|
mixer_parse_output_scaler(const char *buf, mixer_scaler_s &scaler)
|
||||||
|
{
|
||||||
|
int s[5];
|
||||||
|
|
||||||
|
if (sscanf(buf, "O: %d %d %d %d %d",
|
||||||
|
&s[0], &s[1], &s[2], &s[3], &s[4]) != 5) {
|
||||||
|
debug("scaler parse failed on '%s'", buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
scaler.negative_scale = s[0] / 10000.0f;
|
||||||
|
scaler.positive_scale = s[1] / 10000.0f;
|
||||||
|
scaler.offset = s[2] / 10000.0f;
|
||||||
|
scaler.min_output = s[3] / 10000.0f;
|
||||||
|
scaler.max_output = s[4] / 10000.0f;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a control scaler from the buffer.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mixer_parse_control_scaler(const char *buf, mixer_scaler_s &scaler, uint8_t &control_group, uint8_t &control_index)
|
||||||
{
|
{
|
||||||
unsigned u[2];
|
unsigned u[2];
|
||||||
int s[5];
|
int s[5];
|
||||||
|
|
||||||
if (sscanf(buf, "S: %u %u %d %d %d %d %d",
|
if (sscanf(buf, "S: %u %u %d %d %d %d %d",
|
||||||
&u[0], &u[1], &s[0], &s[1], &s[2], &s[3], &s[4]) != 7)
|
&u[0], &u[1], &s[0], &s[1], &s[2], &s[3], &s[4]) != 7) {
|
||||||
|
debug("scaler parse failed on '%s'", buf);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
control_group = u[0];
|
control_group = u[0];
|
||||||
control_index = u[1];
|
control_index = u[1];
|
||||||
@@ -133,7 +164,6 @@ mixer_load_simple(Mixer::ControlCallback control_cb, uintptr_t cb_handle, int fd
|
|||||||
{
|
{
|
||||||
mixer_simple_s *mixinfo = nullptr;
|
mixer_simple_s *mixinfo = nullptr;
|
||||||
char buf[60];
|
char buf[60];
|
||||||
uint8_t control_group, control_index;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* let's assume we're going to read a simple mixer */
|
/* let's assume we're going to read a simple mixer */
|
||||||
@@ -141,22 +171,30 @@ mixer_load_simple(Mixer::ControlCallback control_cb, uintptr_t cb_handle, int fd
|
|||||||
|
|
||||||
/* first, get the output scaler */
|
/* first, get the output scaler */
|
||||||
ret = mixer_getline(fd, buf, sizeof(buf));
|
ret = mixer_getline(fd, buf, sizeof(buf));
|
||||||
if (ret < 1)
|
if (ret < 1) {
|
||||||
|
debug("failed reading for output scaler");
|
||||||
goto fail;
|
goto fail;
|
||||||
if (mixer_parse_scaler(buf, mixinfo->output_scaler, control_group, control_index))
|
}
|
||||||
|
if (mixer_parse_output_scaler(buf, mixinfo->output_scaler)) {
|
||||||
|
debug("failed parsing output scaler");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* now get any inputs */
|
/* now get any inputs */
|
||||||
for (unsigned i = 0; i < inputs; i++) {
|
for (unsigned i = 0; i < inputs; i++) {
|
||||||
ret = mixer_getline(fd, buf, sizeof(buf));
|
ret = mixer_getline(fd, buf, sizeof(buf));
|
||||||
if (ret < 1)
|
if (ret < 1) {
|
||||||
goto fail;
|
debug("failed reading for control scaler");
|
||||||
if (mixer_parse_scaler(buf,
|
|
||||||
mixinfo->inputs[i].scaler,
|
|
||||||
mixinfo->inputs[i].control_group,
|
|
||||||
mixinfo->inputs[i].control_index)) {
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
if (mixer_parse_control_scaler(buf,
|
||||||
|
mixinfo->controls[i].scaler,
|
||||||
|
mixinfo->controls[i].control_group,
|
||||||
|
mixinfo->controls[i].control_index)) {
|
||||||
|
debug("failed parsing control scaler");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
debug("got control %d", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX should be a factory that validates the mixinfo ... */
|
/* XXX should be a factory that validates the mixinfo ... */
|
||||||
@@ -172,27 +210,32 @@ mixer_load(Mixer::ControlCallback control_cb, uintptr_t cb_handle, int fd, Mixer
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char buf[60];
|
char buf[60];
|
||||||
unsigned scalers;
|
unsigned inputs;
|
||||||
|
|
||||||
ret = mixer_getline(fd, buf, sizeof(buf));
|
ret = mixer_getline(fd, buf, sizeof(buf));
|
||||||
|
|
||||||
/* end of file or error ?*/
|
/* end of file or error ?*/
|
||||||
if (ret < 1)
|
if (ret < 1) {
|
||||||
|
debug("getline %d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* slot is empty - allocate a null mixer */
|
/* slot is empty - allocate a null mixer */
|
||||||
if (buf[0] == 'Z') {
|
if (buf[0] == 'Z') {
|
||||||
|
debug("got null mixer");
|
||||||
mixer = new NullMixer();
|
mixer = new NullMixer();
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is it a simple mixer? */
|
/* is it a simple mixer? */
|
||||||
if (sscanf(buf, "M: %u", &scalers) == 1) {
|
if (sscanf(buf, "M: %u", &inputs) == 1) {
|
||||||
mixer = mixer_load_simple(control_cb, cb_handle, fd, scalers);
|
debug("got simple mixer with %d inputs", inputs);
|
||||||
return (mixer == nullptr) ? -1 : 0;
|
mixer = mixer_load_simple(control_cb, cb_handle, fd, inputs);
|
||||||
|
return (mixer == nullptr) ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we don't recognise the mixer type */
|
/* we don't recognise the mixer type */
|
||||||
|
debug("unrecognized mixer type '%c'", buf[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,10 +303,12 @@ MixerGroup::load_from_file(const char *path)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int fd = open(path, O_RDONLY);
|
int fd = open(path, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0) {
|
||||||
|
debug("failed to open %s", path);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (unsigned count = 0;; count++) {
|
||||||
int result;
|
int result;
|
||||||
Mixer *mixer;
|
Mixer *mixer;
|
||||||
|
|
||||||
@@ -273,13 +318,19 @@ MixerGroup::load_from_file(const char *path)
|
|||||||
mixer);
|
mixer);
|
||||||
|
|
||||||
/* error? */
|
/* error? */
|
||||||
if (result < 0)
|
if (result < 0) {
|
||||||
|
debug("error");
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF or error */
|
/* EOF or error */
|
||||||
if (result < 1)
|
if (result < 1) {
|
||||||
|
printf("[mixer] loaded %u mixers\n", count);
|
||||||
|
debug("EOF");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("loaded mixer %p", mixer);
|
||||||
add_mixer(mixer);
|
add_mixer(mixer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user