/Behaviors |
The NG Behavior Control
Contents
- Introduction
- Behavior Conditions
- Behavior Actions
- Behavior Rules
-
Example Behavior Rules
- Old Style Infligth Calibration
- Inflight HAL Change on a tristate switch
- Teacher/Student with two RC and two receivers on a binary switch
- GPS Position Hold on a binary switch
- Closed-Loop PT1 Compensation on a binary switch
- Nick/Roll override of attitude compensated cam-holder
- Setting controller parameters by behaviors
Introduction
In essence every UAV has a known set of behaviors and you expect it to behave according to these! This is nothing new.
Now imagine that these behaviors are not a fix set of rules, but imagine you could customize these behaviors according to your needs. Let's say a behavior rule consists of a behavior condition, which when it evaluated as true makes sure that an associated behavior action gets executed. If you think it through you will see that every and all of the current UAV features can be mapped to behaviors! You need calibration on channel 5? You want your cam to make a photo when channel 8 goes to 100%? You would like to turn on the lights, when you have reached 10m or more... and... and... and...
I think you got the point...
... we can model every and all UAV features to one or more behavior rules.
We implemented the concept on the NG. You can define arbitrary behavior rules. Each behavior rule consist of a behavior condition, which when it evaluates to true will trigger an associated behavior action.
Conditions and actions are arbitrary functions implemented seperate in the NG framework. The implemented console commands show behaviors, show conditions and show actions are used to inspect the currently defined behaviors as well as the predefined conditions and actions. Users are able to define custom new behaviors using the predefined conditions and actions with the command behavior add <...> Each condition and action can receive user chosen parameters. These allow further customization.
Behavior conditions and actions are simple methods. Implementing them is a simple job for developers.
Behavior Conditions
The command list conditions lists all currently available behavior conditions.
This will look similar to:
# list conditions Condition Description when.rc.throttle.changed() TRUE if rc[throttle!=rc_prev[throttle] when.rc.pot.lt(x,y) TRUE if rc[pot]<[val] when.rc.pot.gt(x,y) TRUE if rc[pot]>[val] when.rc.pot.changed(x) TRUE if rc[pot]!=rc_prev[pot] when.rc.pot.binary(x,y) TRUE if [val]?rc[pot]>75%:rc[pot]<25% when.rc.pot.tristate(x,y) TRUE if button [pot] goes to state [val] when.rc.stick.left(x,y) TRUE if rc left stick is at [left|center|right] [top|center|bottom] when.rc.stick.right(x,y) TRUE if rc right stick is at [left|center|right] [top|center|bottom] when.landed.rc.stick.left(x,y) TRUE if landed rc left stick is at [left|center|right] [top|center|bottom] when.landed.rc.stick.right(x,y) TRUE if landed rc right stick is at [left|center|right] [top|center|bottom] when.rc.signal.lost(x) TRUE if rc signal is lost for x*20ms when.ctrl.entering.fs(x) TRUE when entering flight state [landed|spinup|flying] when.ctrl.leaving.fs(x) TRUE when leaving flight state [landed|spinup|flying] while.battery.low() TRUE if battery voltage is below globally defined limit when.rc.pri.pot.binary(x,y) TRUE if [val]?rc_pri[pot]<25%:rc_pri[pot]>75% while.rc.signal.lost(x) TRUE if rc signal is lost for x*20ms while.rc.pot.binary(x,y) TRUE if [val]?rc[pot]<25%:rc[pot]>75% when.flying.rc.signal.lost(x) TRUE if rc signal is lost for x*20ms while not landed while.flying.rc.signal.lost(x) TRUE if rc signal is lost for x*20ms while not landed var.equal(x,y) TRUE if [var] == [val] var.not.equal(x,y) TRUE if [var] != [val] var.gt(x,y) TRUE if [var] > [val] var.lt(x,y) TRUE if [var] < [val] var.bit.true(x,y) TRUE if [var][bit] == 1 var.bit.false(x,y) TRUE if [var][bit] == 0 var.bit.op.and.true(x,y) TRUE if and([var], [bitno]) == 1 var.bit.op.and.false(x,y) TRUE if and([var], [bitno]) == 0 var.bit.op.or.true(x,y) TRUE if or([var], [bitno]) == 1 var.bit.op.or.false(x,y) TRUE if or([var], [bitno]) == 0 var.equal.clear(x,y) TRUE if [var] == [val], reset [var] to 0 when.rc.sticks.both(x,y) TRUE if rc left and right stick is at [xy] [xy] position x,y can be a=ANY,l=LEFT,r=RIGHT,t=TOP,b=BOTTOM,c=CENTER when.landed.rc.sticks.both(x,y) TRUE if landed rc left and right stick is at [xy] [xy] position x,y can be a=ANY,l=LEFT,r=RIGHT,t=TOP,b=BOTTOM,c=CENTR when.rc.sticks.both.delay(x,y,z) TRUE if rc left and right stick is at [xy] [xy] position x,y can be a=ANY,l=LEFT,r=RIGHT,t=TOP,b=BOTTOM,c=CENTER, wit] when.landed.rc.sticks.both.delay(x,y,z) TRUE if landed rc left and right stick is at [xy] [xy] position x,y can be a=ANY,l=LEFT,r=RIGHT,t=TOP,b=BOTTO] when.rc.stick.left.delay(x,y,z) TRUE if rc left stick is at [left|center|right] [top|center|bottom] with delay [val] when.rc.stick.right.delay(x,y,z) TRUE if rc right stick is at [left|center|right] [top|center|bottom] with delay [val] when.landed.rc.stick.left.delay(x,y,z) TRUE if landed rc left stick is at [left|center|right] [top|center|bottom] with delay [val] when.landed.rc.stick.right.delay(x,y,z) TRUE if landed rc right stick is at [left|center|right] [top|center|bottom] with delay [val] when.flying.rc.pot.binary(x,y) TRUE if [val]?rc[pot]>75%:rc[pot]<25% while.flying.rc.pot.binary(x,y) TRUE if [val]?rc[pot]<25%:rc[pot]>75% when.landed.rc.stick.edge(x,y) TRUE if rc left stick is at [left|right] [top|bottom|left|right] when.rc.stick.edge.and.pot(x,y,z) TRUE if rc left stick is at [left|right] [top|bottom|left|right] while rc[pot]>75%
The output can differ on your NG version or configuration!
You can use each of these conditions to build Behavior Rules. Every condition can receive zero to two integer arguments.
Behavior Actions
The command list actions lists all currently available behavior actions.
This will look similar to:
# list actions Action Description ctrl.calibrate(x) calibrate [gyro|all] ctrl.switch.ctrl(x) switch to prev[0]/next[1] ctrl ctrl.switch.conf(x) switch to prev[0]/next[1] conf ctrl.hover() set throttle to stored hover value ctrl.ascend(x) set throttle to stored hover + delta[0] ctrl.descend(x) set throttle to stored hover + delta[0] actor.motors(x) motor control [on|off] actor.play.melody(x) play melody [melody] rc.calibrate.bearing() calibrate rc nick, roll and yaw rc.calibrate.throttle() calibrate rc throttle rc.fact.change.bearing(x) change rc.fact.[nick|roll] relatively rc.fact.change.yaw(x) change rc.fact.yaw relatively var.set(x,y) set [var] = val var.bit.set(x,y) set [var][bit] = 1 var.bit.clear(x,y) set [var][bit] = 0 gps.track(x) GPS tracking [on|off] conf.store(x) store configuration in [slot-number] rc.trainer.mode(x) set teacher/student mode [teacher|student] ctrl.altitude.hold(x) set altitude fix [on|off] ctrl.set.hw.hal(x) set HW.HAL hardware abstraction layer conf.load(x) load configuration from [slot] rcctrl.set.nick.corr(x) set servo correction to pos[0] on the rcctrl rcctrl.set.roll.corr(x) set servo correction on pos[0] on the rcctrl rcctrl.set.servo(x,y) set the servo[0] pos to pos[1] on the rcctrl rcctrl.set.servo.opmode(x) set the servo operation mode[0] ctrl.set.pt1.comp(x) set use_pt1_comp [on|off] rc.clear.bearing() clear rc nick, roll and yaw bearing ctrl.set.bat.minimum(x) set bat.minimum to arg[0]/10 nav.position.hold(x) navigation position hold (PH) (needs GPS & compass) nav.coming.home(x) navigation coming home (CH) (needs GPS & compass) nav.store.target() navigation store current position as target nav.set.target(x,y) navigation store position (lon,lat) as target conf.load.store(x,y) load configuration from [slot] and store to slot [slot] conf.store.last.loaded() store configuration to slot last loaded from actor.port.playpattern(x,y) play pattern on port id 0..3 = P0.12|P0.13|P1.16|P1.18 [id][pattern] actor.port.set(x,y) set port by id 0..3 = P0.12|P0.13|P1.16|P1.18 [id][0|1] ctrl.wobble(x,y) wobble (sinus on throttle) with A[0], T[1] in [10ms] ctrl.wink.nick(x,y) wink on nick (sinus on nick) with A[0] in [8bit rc], T[1] in [100ms] ctrl.wink.roll(x,y) wink on roll (sinus on roll) with A[0] in [8bit rc], T[1] in [100ms] ctrl.calibrate.acc.by.stick(x) calibrate [left|right] actor.pca9685.set.light(x,y) set channel x to duty cycle y [0..127] actor.pca9685.dim.light(x,y) dim channel x to pot[y] actor.pca9685.set.scheme(x) Load scheme x to channels 0-11 actor.pca9685.set.sequence(x,y) Set sequence y to group x ctrl.hh(x) set heading hold flight mode [on|off]
The output can differ on your NG version or configuration!
Each of these actions can be used to build Behavior Rules. Every action can receive zero to two integer arguments.
Behavior Rules
Inspecting the current Behavior Rules
The command list behaviors displays the list of currently defined behavior rules. A behavior rule consists of a behavior condition and a behavior action. Arbitrary behavior conditions and behavior actions can be programmed and implemented in a modular way by developers. The user is able to manipulate the behavior rules by adding and deleting behavior rules shown in this list.
The output of the command list behaviors looks like this:
# list behaviors List of currently defined behaviors: No Condition Action 00 when.rc.landed.stick.left(left,top) => ctrl.calibrate(gyro) 01 when.rc.landed.stick.left(right,top) => ctrl.calibrate(all) 02 when.rc.stick.left(left,bottom) => actor.motors(off) 03 when.rc.landed.stick.left(right,bottom) => actor.motors(on) 04 when.rc.landed.stick.left(right,center) => conf.store(0) 05 when.rc.pot.binary(0,1) => rc.calibrate.bearing() 06 when.rc.pot.binary(0,1) => rc.calibrate.throttle() 07 while.rc.signal.lost(25) => ctrl.descend(10) 08 while.battery.low() => actor.play.melody(14) 09 when.ctrl.entering.fs(flying) => gps.track(on) 10 when.ctrl.leaving.fs(flying) => gps.track(off) 11 behavior rules defined. 19 behavior slots free.
The output can differ on your NG version or configuration!
Adding a Behavior Rule
The command behavior add <condition>([arg1][,arg2]]) <action>([arg1[,arg2]]) defines a new behavior rule. The required argument <condition> represents a behavior condition as shown by the command list conditions. The required argument <action> represents a behavior action as shown by the command list actions. Both, condition and action, can optionally receive one or two integer arguments.
Adding a new behavior rule is simple and looks like this:
# behavior add while.battery.low() actor.play.melody(14)
Deleting a Behavior Rule
The command behavior delete [index] removes one of the existing behavior rules shown by the command list behaviors. The argument [index] represents the behavior slot number of the behavior rule to delete.
The output of the command delete behavior 14 looks like this:
# behavior delete 14 Deleted behavior at index 14
Example Behavior Rules
Old Style Infligth Calibration
Infligth calibration rc.calibrate.bearing() stores the current output of your remote-control stick (for nick/roll) as leading to a stable flight position. After Calibration, if you don't touch the nick/roll stick, the NG will behave as in the moment you inflight-calibrated it.
To trigger infligth calibration, you need a free remote control-channel with a switch on your remote. I had such a switch on channel 5, so I set pot0 to channel 5 (swapped it against channel8/pot3):
# set RC.ch.pot3 8 Setting integer 'RC.ch.pot3' to '8' # set RC.ch.pot0 5 Setting integer 'RC.ch.pot0' to '5'
My switch has two positions, it delivers (according to loop dsl dsl0) -100% or -100% depending on its position. So we use the when.flying.rc.pot.binary() behavior condition:
# behavior add when.flying.rc.pot.binary(0,1) rc.calibrate.bearing() # behavior add when.flying.rc.pot.binary(0,1) rc.calibrate.throttle()
http://vimeo.com/15107083 shows this in action.
As feedback, you get a double beep when you trigger this action during fligth. For debugging, you can of course use the actor.play.melody(x) action.
Inflight HAL Change on a tristate switch
The be able to change the used HAL in-flight, you could add the following behaviors:
# behavior add when.rc.pot.tristate(3,2) ctrl.set.hw.hal(quadX) # behavior add when.rc.pot.tristate(3,1) ctrl.set.hw.hal(quad) # behavior add when.rc.pot.tristate(3,0) ctrl.set.hw.hal(quadR)
These behaviors allow you to use a tristate button on pot3 to change the HAL used in-flight.
Teacher/Student with two RC and two receivers on a binary switch
If you attach two receivers to your NG, you may do teacher/student without a teacher/student cable and without changes to your remote control.
Just add the following behavior rules and attach two receivers:
# behavior add when.rc.pri.pot.binary(1,0) rc.trainer.mode(teacher) # behavior add when.rc.pri.pot.binary(1,1) rc.trainer.mode(student)
This will allow you to switch between teacher and student control by using pot1.
GPS Position Hold on a binary switch
If you have a compass and a GPS attached, you can activate GPS position hold at the current position using the following behavior rules:
behavior add when.rc.pri.pot.binary(2,0) nav.position.hold(off) behavior add when.rc.pri.pot.binary(2,1) nav.store.and.position.hold(on)
These behaviors allow you to activate GPS position hold by switching pot2.
Closed-Loop PT1 Compensation on a binary switch
To be able to switch PT1-compensation on and off in-flight, you can add the following behaviors:
behavior add when.rc.pri.pot.binary(5,0) ctrl.set.pt1.comp(off) behavior add when.rc.pri.pot.binary(5,1) ctrl.set.pt1.comp(on)
This will allow you to switch PT1-compensation by using pot5.
Nick/Roll override of attitude compensated cam-holder
To be able to change nick and roll angles of your attitude compensated cam-holder on servo1 + servo2 of your CAMC or RCC you can define two channels to override the nick/roll angles.
behavior add when.rc.pot.changed(4) rcctrl.set.nick.corr(4) behavior add when.rc.pot.changed(5) rcctrl.set.nick.corr(5)
These behaviors allow you to change nick and roll angles of your cam-holder on servo1 + servo2 using pot4 and pot5 which should be preferably potentiometers.
Setting controller parameters by behaviors
Release >=0.66 allows you to change any global or controller parameters by behavior.
The following command switches off the compass by binary switch.
behavior add when.rc.pot.binary(3,0) param.set(CTRL.use.compass,0)
With the following commands you can raise or lower I.z with the left stick
behavior add when.landed.rc.stick.right.delay(center,bottom,0) param.add(I.z,-10) behavior add when.landed.rc.stick.right.delay(center,top,0) param.add(I.z,10)
It is also possible to control a parameter by a poti on your remote control. The following command lets you control the parameter P.z with a poti on channel 4 in range 0 to 1000.
behavior add when.rc.pot.changed(4) param.map.rc(P.z,4,0,1000)
