-
Notifications
You must be signed in to change notification settings - Fork 80
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
Master introduce v1cmd syntax #84
base: master
Are you sure you want to change the base?
Master introduce v1cmd syntax #84
Conversation
1e04fb4
to
a6ced57
Compare
There was no need to have this non-const. non-const prevented us to use it on a const& to a SendHandle, which we do need if the SendHandle is presented by a DataSource. Signed-off-by: Peter Soetens <[email protected]>
This script introduces two changes to scripting: 1. It rearranges the ActionInterface::readArguments/execute/reset semantics when mapped to DataSource::evaluate/rvalue/reset functions. This had some influence on the flow of executing (remote) operations, but all cases have been rectified. 2. It adds to the parser a look for '.cmd' suffix on operation calls, which is similar to '.send', but yields the script execution until the send returns something else than SendNotReady. The result of a .cmd call is a SendStatus which can be read/used by the script itself. This has been tested on C++ operations and exported script functions. 'cmd' called operations will not update their arguments when SendSuccess is returned and the return value of the operation is ignored. Signed-off-by: Peter Soetens <[email protected]>
Since a condition edge now waits on the result of a collect datasource, that datasource needs to implement copy/clone semantics properly, such that when copying the state machine, we keep referencing the correct datasource. This patch also adds support for var SendStatus ss = foo.cmd() in which case, the initialisation of the var is delayed until the cmd result is known (identical behavior to: var SendStatus ss; ss = foo.cmd(); ) Signed-off-by: Peter Soetens <[email protected]>
This patch adds .cmd() and .send()+collectIfDone() syntax for an exported script function just like for a C++ operation. The patch consists of 3 parts: 1. Cleanup in CmdFunction and CallFunction : removed unused variables 2. Adding logic into the ExpressionParser to detect the case of script functions. Since they don't have true SendHandle objects and use SendStatus datasources, the parser needs to re-arrange some data sources when handling a 'SendHandleAlias'. The SendHandle of a script function is effectively the alias to the .send() function, + that a .reset() is not forwarded. Evaluating a SendHandle of a script function is the same as writing sh.collectIfDone(). 3. Added unit tests in state_test to test all these cases. I also removed a deprecated warning in the ScriptngService Signed-off-by: Peter Soetens <[email protected]>
…ready gone This is related to 00b2679 in CallFunction.hpp. Signed-off-by: Johannes Meyer <[email protected]>
…t functions We noticed that a send() on a script function did not work when the return value was stored in a SendHandle. The reason was that the SendHandleAlias was stored as an Attribute, but can't be instantiated (since its an alias to a FusedFunctorDataSource), hence, it copied all arguments, prior to giving the arguments a chance to instantiate. so this send() then used copies that weren't used later on... We now remove the SendHandleAlias from the StateMachineService such that they are removed before instantiation happens. We only need them during parsing as attributes, not during execution. Signed-off-by: Peter Soetens <[email protected]>
Without this patch calling operation task.foo with .call() ended up with a ``` Service or Task "task" has no Peer or Service foo (or task was not found at all). ``` error message. I also eliminated some compiler warnings due to signed/unsigned comparisons. Signed-off-by: Johannes Meyer <[email protected]>
A wrapper did forcefully not forward the reset(). It seems this is no longer required, since removing that code makes .cmd() invocations work correctly again. Signed-off-by: Peter Soetens <[email protected]>
a6ced57
to
edff4c6
Compare
merged into toolchain-2.9: 2af3745 |
Commit faf49ed breaks the state_test:
|
…tantiation The loop that removed SendHandleAlias variables from the StateMachineService could have skipped the second one for the case the first two variables are SendHandles. Signed-off-by: Johannes Meyer <[email protected]>
Fixed in psoetens@d444550. |
The state_test is still broken:
The failing test case
The problem is that the condition of the first while loop in the run program never evaluates to false and that every evaluation of |
This partially reverts commit edff4c6.
…n exported function With patch edff4c6, resetting the collect data source returned by FunctionFactory::produceCollect() requeues the function and keeps sending it for every evaluation of sh.collectIfDone() in a loop. Commit f82fa9a reverts this faulty solution. Instead, to make sure that an evaluation of .cmd() also requeues the function, the data source returned by the ExpressionParser is an ActionAliasDataSource which correctly combines the send and collect cycle. Some additional minor patches were required to fix the correct behavior of this solution: * The FusedMSendDataSource stored as the first argument inside the FusedMCollectDataSource must be an AssignableDataSource, as otherwise every evaluation of the collect data source also re-evaluates the send data source from RTT::internal::GetArgument<Seq, RTT::SendHandle<Signature> >::operator(). * When copying the data sources, every instance of FusedMSendDataSource must only be cloned once so that the FusedMCollectDataSource that is evaluated by the ActionAliasDataSource collects from the same SendHandle that was used to send the command. * FusedMCollectDataSource::reset() must not forward to args[0]->reset(), the FusedMSendDataSource. * Evaluating a CmdFunction instance should not reset the cached SendStatus to SendNotReady if the function was already queued. * The default SendStatus returned by CmdFunction::rvalue() was changed from SendNotReady to SendFailure, in analogy to FusedMCollectDataSource. * Use create_sequence::assignable() in OperationInterfacePartFused::produceCollect(), as all arguments in a collect call must be assignable, including the SendHandle data source (see first bullet item). Signed-off-by: Johannes Meyer <[email protected]>
I am not sure if this is the expected behavior for the Deployer [S]> scripting.eval("void test() {}")
= true
Deployer [S]> var SendHandle sh = test.send()
Semantic error: Attempt to initialize a var SendHandle with a SendStatus.
Deployer [S]> sh
= (SendHandle)
Deployer [S]> var SendHandle sh2
= (SendHandle)
Deployer [S]> sh2 = test.send()
= SendNotReady
Deployer [S]> Why can the result of Should Did the last commit 361fe29 introduce this bug? |
…ing functions Test cases testProgramCallFoo and testProgramDoFoo were exactly the same and only covered calling functions from programs. This commit replaces the latter by a new test case testProgramSendFoo, which would also reveal the bug that caused a function to be resent on each evaluation of sh.collectIfDone(). Before, only a similar test case in state_test was triggering that bug. The resending collect problem has been fixed in orocos-toolchain@361fe29. Signed-off-by: Johannes Meyer <[email protected]>
The operation "vo0" added for the testStateYieldbyCmd check in state_test.cpp was not an OwnThread operation and hence executed by the GlobalEngine instead of the task that is also running the state machine. This patch does not change the result of the test: .cmd() correctly yields and allows the engine to execute the operation before checking the result in the next cycle. Signed-off-by: Johannes Meyer <[email protected]>
…mdFunction instances Signed-off-by: Johannes Meyer <[email protected]>
... as generated by tools/scripts/verify_headers.sh.
I am tempted to at least partially revert this patch in the toolchain-2.10 branch for the upcoming release. It still has unresolved issues (#84 (comment)) and introduces new complexity. The // instead of:
operation.cmd(1.0, "string argument");
// ... you can write:
var SendHandle sh = operation.send(1.0, "string argument");
while(sh.collectIfDone() == SendNotReady) {
yield;
} (which additionally allows to return the results as reference arguments to The implementation side of RTT v1 commands was not restored in this PR. RTT v1 commands are stateful task primitives that allow the user to pass a non-blocking start callback and a completion condition to the Did I miss something? Any more thoughts? @psoetens? Is someone already using this new feature? |
I don't believe that the original intent was to fully implement the v1 Command syntax and implementation, but to give a useful approximation of it. But given the complexity I don't doubt that there are outstanding issues ... Yes, we use this extensively to, for example, have state machines "block" on a long call while still checking (and potentially executing) transitions. |
This adds the RTT v1 command semantics to operations used in RTT scripts, by introducing a .cmd() method, analog to .send() and .call(). An operation invoked with .cmd() will wait in a non-blocking way for the operation to complete. So this can mainly be used in periodically executed components, which call operations which take a long time to execute in non-periodic components.
To be discussed, but not to be merged into toolchain-2.8