Conversation
Co-authored-by: orzechow <5220714+orzechow@users.noreply.github.com>
orzechow
left a comment
There was a problem hiding this comment.
Thanks, that's a great starting point!
Please consider my suggestions and comments. Fix them and improve the code accordingly.
| protected: | ||
| using OptionFlags = SequenceArbitrator<DummyEnvironmentModel, DummyCommand>::Option::Flags; | ||
|
|
||
| // Behaviors: first two have invocation=false (unavailable), remaining have invocation=true |
There was a problem hiding this comment.
| // Behaviors: first two have invocation=false (unavailable), remaining have invocation=true | |
| // Behaviors: first two have commitment=false (unavailable), remaining have invocation=true |
| // First call: A has commitment=false → immediately advances to B | ||
| // B has commitment=false → immediately advances to C | ||
| // C has commitment=true → executes C | ||
| EXPECT_EQ("BehaviorC", testSequenceArbitrator.getCommand(time, environmentModel)); |
There was a problem hiding this comment.
You didn't get the general arbitration logic right.
A behavior with true invocation condition can become active. The commitment condition only hints its arbitrator if this behavior should be continued. A behavior with false CC but true IC still can be called multiple times in a row, but needs a round of loseControl/gainControl in between.
For this sequence arbitrator test case this means:
The first call to getCommand (w.r.t. the time step) activates and calls BehaviorA (A.gainControl and A.getCommand) → testSequenceArbitrator.getCommand returns behaviorA
The second call to getCommand (w.r.t. the time step) deactivates A as of if its CC (A.loseControl), then activates and calls BehaviorB (B.gainControl and B.getCommand) → testSequenceArbitrator.getCommand returns behaviorB
The third call to getCommand (w.r.t. the time step) deactivates B as of if its CC (B.loseControl), then activates and calls BehaviorC (C.gainControl and C.getCommand) → testSequenceArbitrator.getCommand returns behaviorC
Following calls to getCommand (w.r.t. the time step) keep C active as of if its CC (no loseControl) and call BehaviorC (C.getCommand) → testSequenceArbitrator.getCommand returns behaviorC
There was a problem hiding this comment.
Fixed in 98e2bd4. The getCommand logic now matches Lauer's definition:
gainControlonly resets state; sub-behavior activation is deferred- Each
getCommandcall activates the current sub-behavior (if not yet active) and executes it - Advancement to the next sub-behavior happens at most one step per call — only when the current sub-behavior's CC is false on the following call
With A(CC=false), B(CC=false), C(CC=true):
- Call 1:
gainControl A→getCommand A→ "BehaviorA" - Call 2:
loseControl A,gainControl B→getCommand B→ "BehaviorB" - Call 3:
loseControl B,gainControl C→getCommand C→ "BehaviorC" - Subsequent:
getCommand C→ "BehaviorC"
…getCommand call Co-authored-by: orzechow <5220714+orzechow@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. |
include/arbitration_graphs/sequence_arbitrator.hpp(main header)include/arbitration_graphs/internal/sequence_arbitrator_io.hpp(IO/display)test/sequence_arbitrator.cpp(unit tests)python_bindings/include/arbitration_graphs_py/sequence_arbitrator.hpp(Python bindings)python_bindings/src/bindings.cppto register the new arbitratorgetCommandlogic: sub-behaviors are activated lazily; advance at most one step per call (per Lauer 2010 definition)Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.