From 59962bc3da97a102117e3d4e5c90b9062beb7180 Mon Sep 17 00:00:00 2001 From: px4dev Date: Sun, 5 Aug 2012 16:30:28 -0700 Subject: Add a sample mixer definition and documentation. Add support for comments in mixer definitions. --- ROMFS/Makefile | 3 +- ROMFS/mixers/FMU_delta.mix | 51 ++++++++++++++++++++++++++ ROMFS/mixers/README | 90 ++++++++++++++++++++++++++++++++++++++++++++++ apps/systemlib/mixer.c | 58 ++++++++++++++++++------------ 4 files changed, 179 insertions(+), 23 deletions(-) create mode 100644 ROMFS/mixers/FMU_delta.mix create mode 100644 ROMFS/mixers/README diff --git a/ROMFS/Makefile b/ROMFS/Makefile index cc5a3ccd3..3f7d4484f 100644 --- a/ROMFS/Makefile +++ b/ROMFS/Makefile @@ -20,7 +20,8 @@ ROMFS_FSSPEC := $(SRCROOT)/scripts/rcS~init.d/rcS \ $(SRCROOT)/scripts/rc.logging~init.d/rc.logging \ $(SRCROOT)/scripts/rc.standalone~init.d/rc.standalone \ $(SRCROOT)/scripts/rc.PX4IO~init.d/rc.PX4IO \ - $(SRCROOT)/scripts/rc.PX4IOAR~init.d/rc.PX4IOAR + $(SRCROOT)/scripts/rc.PX4IOAR~init.d/rc.PX4IOAR \ + $(SRCROOT)/mixers/FMU_delta.mix~mixers/FMU_delta.mix # # Add the PX4IO firmware to the spec if someone has dropped it into the diff --git a/ROMFS/mixers/FMU_delta.mix b/ROMFS/mixers/FMU_delta.mix new file mode 100644 index 000000000..75493c578 --- /dev/null +++ b/ROMFS/mixers/FMU_delta.mix @@ -0,0 +1,51 @@ +Delta-wing mixer for PX4FMU +=========================== + +Lines in this file that begin with a capital letter and a colon are interpreted +as mixer commands. All other lines are ignored. + +This delta-wing mixer assumes the elevon servos are connected to PX4FMU servo +outputs 0 and 1 and the motor speed control to output 2. Output 3 is assumed to +be unused. + +Inputs to the mixer come from channel group 0 (vehicle attitude), channels 0 +(roll), 1 (pitch) and 3 (thrust). + +See the README for more information on the scaler format. + +Elevon mixers +------------- +Three scalers total (output, roll, pitch). + +On the assumption that the two elevon servos are physically reversed, the pitch +input is inverted between the two servos. + +The scaling factor for roll inputs is adjusted to implement differential travel +for the elevons. + +M: 3 +S: 0 0 10000 10000 0 -10000 10000 +S: 0 0 3000 5000 0 -10000 10000 +S: 0 1 5000 5000 0 -10000 10000 + +M: 3 +S: 0 0 10000 10000 0 -10000 10000 +S: 0 0 5000 3000 0 -10000 10000 +S: 0 1 -5000 -5000 0 -10000 10000 + + +Motor speed mixer +----------------- +Two scalers total (output, thrust). + +This mixer generates a full-range output (-1 to 1) from an input in the (0 - 1) +range. Inputs below zero are treated as zero. + +M: 2 +S: 0 0 10000 10000 0 -10000 10000 +S: 0 2 0 20000 -10000 -10000 10000 + + +We leave the fourth mixer empty. + +M: 0 diff --git a/ROMFS/mixers/README b/ROMFS/mixers/README new file mode 100644 index 000000000..482478fa7 --- /dev/null +++ b/ROMFS/mixers/README @@ -0,0 +1,90 @@ +PX4 mixer definitions +===================== + +Files in this directory implement example mixers that can be used as a basis +for customisation, or for general testing purposes. + +Mixer basics +------------ + +Mixers combine control values from various sources (control tasks, user inputs, +etc.) and produce output values suitable for controlling actuators; servos, +motors, switches and so on. + +An actuator derives its value from the combination of one or more control +values. Each of the control values is scaled according to the actuator's +configuration and then combined to produce the actuator value, which may then be +further scaled to suit the specific output type. + +Internally, all scaling is performed using floating point values. Inputs and +outputs are clamped to the range -1.0 to 1.0. + +control control control + | | | + v v v + scale scale scale + | | | + | v | + +-------> mix <------+ + | + scale + | + v + out + +Scaling +------- + +Basic scalers provide linear scaling of the input to the output. + +Each scaler allows the input value to be scaled independently for inputs +greater/less than zero. An offset can be applied to the output, and lower and +upper boundary constraints can be applied. Negative scaling factors cause the +output to be inverted (negative input produces positive output). + +Scaler pseudocode: + +if (input < 0) + output = (input * NEGATIVE_SCALE) + OFFSET +else + output = (input * POSITIVE_SCALE) + OFFSET + +if (output < LOWER_LIMIT) + output = LOWER_LIMIT +if (output > UPPER_LIMIT) + output = UPPER_LIMIT + +Syntax +------ + +Mixer definitions are text files; lines beginning with a single capital letter +followed by a colon are significant. All other lines are ignored, meaning that +explanatory text can be freely mixed with the definitions. + +Each file may define more than one mixer; the allocation of mixers to actuators +is specific to the device reading the mixer definition. + +A mixer begins with a line of the form + + M: + +If the scaler count is zero, the mixer is a placeholder and the device will not +allocate a mixer for this position. Otherwise, this line is followed by scaler +definitions matching the given count. + +A scaler definition is a line of the form: + + S: <-ve scale> <+ve scale> + +The first scaler definition following the M: line configures the output scaler. +The and fields are ignored in this case. + +For the remaining scalers, the value identifies the control group from +which the scaler will read. Control group 0 is the vehicle attitude control +group; other group numbers may be assigned for other purposes. The value +selects the control within the group that will be scaled. + +The remaining fields on the line represent the scaler parameters as discussed +above. Whilst the calculations are performed as floating-point operations, the +values stored in the definition file are scaled by a factor of 10000; i.e. an +offset of -0.5 is encoded as -5000. diff --git a/apps/systemlib/mixer.c b/apps/systemlib/mixer.c index 8b1dcc054..25cf80160 100644 --- a/apps/systemlib/mixer.c +++ b/apps/systemlib/mixer.c @@ -163,29 +163,43 @@ mixer_mix(struct mixer_s *mixer, float **controls) static int mixer_getline(int fd, char *line, unsigned maxlen) { - int ret; - char c; - - while (--maxlen) { - ret = read(fd, &c, 1); - - if (ret <= 0) - return ret; - - if (c == '\r') - continue; - - if (c == '\n') { - *line = '\0'; - return 1; + /* reduce line budget by 1 to account for terminal NUL */ + maxlen--; + + /* loop looking for a non-comment line */ + for (;;) { + int ret; + char c; + char *p = line; + + /* loop reading characters for this line */ + for (;;) { + ret = read(fd, &c, 1); + + /* on error or EOF, return same */ + if (ret <= 0) + return ret; + + /* ignore carriage returns */ + if (c == '\r') + continue; + + /* line termination */ + if (c == '\n') { + /* ignore malformed lines */ + if (line[1] != ':') + break; + + /* terminate line as string and return */ + *p = '\0'; + return 1; + } + + /* if we have space, accumulate the byte and go on */ + if ((p - line) < maxlen) + *p++ = c; } - - *line++ = c; } - - /* line too long */ - puts("line too long"); - return -1; } static int @@ -214,7 +228,7 @@ mixer_load(int fd, struct mixer_s **mp) { int ret, result = -1; struct mixer_s *mixer = NULL; - char buf[100]; + char buf[60]; unsigned scalers; ret = mixer_getline(fd, buf, sizeof(buf)); -- cgit v1.2.3