-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add sequence dispatcher component #2731
Conversation
Hello, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fantastic @zimri-leisher! Looks like the exact architecture I would have recommended. I threw in a few minor comments for consideration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I am impressed! I'll ask @timcanham to look over it too.
@timcanham want to take a look, it is a sequence dispatcher! |
Thanks for all the comments. Sorry that there are a lot of things that are idiomatic to our code that I didn't remove from here, but honestly part of the reason why I wanted to put this in front of you guys was to get exactly this feedback. I have a question: where would you recommend storing the |
Since CMD_SEQUENCERS_COUNT/SeqDispatcherSequencerCount is a per deployment config option, I'd add a |
Err, since we don't want folks to modify CmdSequencerState, |
Alright to the With regards to using Fw::Wait, I'd prefer not to, as CmdSequencerState has three values instead of two: |
@zimri-leisher my bad, I got CmdSequencerState and For component internal enums, you can either add it in the hpp as you suggested, or add it as a standalone type to the The concern we were discussing does arise for the |
Good point, maybe I should change the argument of the RUN command to just take a boolean: blocking or non-blocking. No need for a two-valued enum to exist when we have bools I guess :P |
I'd recommend using an enum like FW:Wait (WAIT and NO_WAIT) instead of a bool, because that can make the sequence files more readable I'd be curious to get folks opinion on what is the clearest.... WAIT/NO_WAIT, BLOCK/NO_BLOCK, TRUE/FALSE |
IMHO not TRUE/FALSE for the reasons @Joshua-Anderson says, WAIT/NO_WAIT seems a little more understandable in plain English. |
Ok, will make these changes. However just want to mention that I'm out of office for 2 weeks starting this Friday so they might not happen until then. The idea of this PR is that you shouldn't have to know which sequencer you're running a sequence on ahead of time. However, this means that commands inside of the sequence file don't know either. This is a problem if these commands want to modify something about the sequencer--in our case, we want to change which line the sequencer is on based on some runtime criteria inside of a command. Is there some way that a command handler can tell from which sequencer a command came from? This would solve my problem. I couldn't find a way and so came up with a really gross solution. Hoping one of you has some input on this. |
The way I've seen this approached on past missions is a concept of sequence directives. Effectively these are special commands/opcodes that are only valid within a command sequence, and they dispatch a command to the command sequencer executing the sequence. Ex: Fprime doesn't have any concept of sequence directives yet, but it's something on our roadmap that we want to add. It probably requires a change to the sequence binary format to add a flag indicating if the "command" opcode is a standard fprime command or if it should be dispatched as a sequence directive instead. What do you think about a sequence directive approach? Would that solve your use cases? Have a fantastic vacation and no rush at all on this pull request! |
That is kind of what I'm doing, only my solution is hackier. I made a component called |
@zimri-leisher Yep, very similar approach. Only pitfall is that is it adds commands in your dictionary that you never want to send from the ground. Sequence directives are a slightly cleaner way of accomplishing the same thing. I think your approach will work well and as a future improvement we can work on the design and implementation of sequence directives for fprime. I'll make sure you get tagged in the github discussions on the topic once we get started. |
…onnections on init
Well, I took my time, but I'm back and gonna get this merged. Just pushed some changes to allow the code to build, and incorporated all of your feedback so far. What's the best way to add my name to the allowed words list? It's failing on spell check lol |
@zimri-leisher you can add words that aren't recognized to the https://github.com/nasa/fprime/blob/devel/.github/actions/spelling/expect.txt |
@zimri-leisher could using the |
It seems the problem was that the (previously unused) CmdSeqIn port took in a string like |
} | ||
|
||
//! Handler for input port seqRunIn | ||
void SeqDispatcher::seqRunIn_handler(NATIVE_INT_TYPE portNum, |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
const U32 cmdSeq, | ||
const Fw::CmdStringArg& fileName, | ||
Fw::Wait block) { | ||
FwIndexType idx = this->getNextAvailableSequencerIdx(); |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
Framework failure caused by: #2835. Will rerun. |
Okay, ready for review again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks very good! An EVR could be made high
instead of low
because it is a problem with a direct user command.
Tests could be more complete, and SDD is blank.
Other (very minor style points):
- Typically in compound
if
clauses we put()
around each sub-phrase. e.g.if ((A) || (B))
. for clarity. Your code is perfectly clear, so no real issue here. - Typically we don't return
bool
but rather opt for an enumeration that describes the issue. This is truly a "did work" or "did not work", so it is ok.
None of this is a blocker. Good work! I'd like another set of eyes....let me see if @timcanham will review. In the mean-time, consider that EVR to be made high
.
I made the changes to the SDD file and event. |
void SeqDispatcher::LOG_STATUS_cmdHandler( | ||
const FwOpcodeType opCode, /*!< The opcode*/ | ||
const U32 cmdSeq) { /*!< The command sequence number*/ | ||
for(FwIndexType idx = 0; idx < SeqDispatcherSequencerPorts; idx++) { |
Check notice
Code scanning / CodeQL
Use of basic integral type Note
Known file CI failure. I captured the failing random seed, and re-ran. We have an issue to look into these failures. |
@zimri-leisher Do you plan to release |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zimri-leisher This looks really great! Minor comments only. If you don't wish to make any changes, I'll approve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks very good. I have included my review comments.
@zimri-leisher I noted some things that could be future work, some things that would be nice to do now. Would you please note those items you intend to close-out for this PR, and which you'd prefer to see as a future work item? That way I know what to confirm is done before merging and what I should track as future work. Thanks for all the hard work! |
…ert instead of warning for runSeq
Okay, I fixed most of the new comments. Any pointers for the unit tests? |
// directly commanded that specific sequencer | ||
|
||
// warn because this may be unintentional | ||
this->log_WARNING_LO_UnexpectedSequenceStarted(static_cast<U16>(portNum), fileName); |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
return; | ||
} | ||
|
||
this->runSequence(idx, fileName, Fw::Wait::NO_WAIT); |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
// no available sequencers | ||
if (idx == -1) { | ||
this->log_WARNING_HI_NoAvailableSequencers(); | ||
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
// no available sequencers | ||
if (idx == -1) { | ||
this->log_WARNING_HI_NoAvailableSequencers(); | ||
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
return; | ||
} | ||
|
||
this->runSequence(idx, fileName, block); |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
return; | ||
} | ||
|
||
this->runSequence(idx, fileName, block); |
Check warning
Code scanning / CodeQL
Unchecked function argument Warning
I am going to merge and take action for adding rules testing! |
Change Description
This PR adds a SeqDispatcher component to Svc which allows command sequences to be automatically distributed among CmdSequencers.
Rationale
CmdSequencers only support running a single command sequence at a time. For complex missions, this necessitates having multiple CmdSequencers. However, without SeqDispatcher, ground operators would have to manually keep track of which CmdSequencers are currently being used. SeqDispatcher automates this process.
Testing/Review Recommendations
This is ported from an internal fork of FPrime which is a few versions out of date. Special care should be taken to make sure that the code seen here is up-to-date with the rest of FPrime. Also, probably should make much more in-depth unit tests.
Future Work
Closes #2729