Skip to content
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

ROS generated code only subscribing to output channels if mentioned in trace #14

Open
MattWindsor91 opened this issue Jul 26, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@MattWindsor91
Copy link
Collaborator

From discussion with @pefribeiro, rtcg is only generating subscribers and callbacks for topics of output channels if they are mentioned in the trace producing the test. This is bad; it means that

foo.in,foo.in

and

foo.in,bar.out,foo.in

are treated as identical traces if bar is never mentioned in the test.

This is related to #8 inasmuch as a) some of the output channels might not be named by the tests, and b) we'd need to know that the channels are output channels so as to forbid them (currently the STM JSON gets a list of inferred types for channels, but not a list of input/output directions).

@MattWindsor91 MattWindsor91 added the bug Something isn't working label Jul 26, 2023
@MattWindsor91
Copy link
Collaborator Author

MattWindsor91 commented Jul 26, 2023

I think the first problem arises anywhere in the templates that is ranging over .Transitions.Out (i.e. currently only considering the outbound transitions of the STM, rather than all outward channels).

Firstly, this snippet here in the STM template, generating prototypes for output callbacks:

{{- range .Transitions.Out }}
void {{ cppCallbackName .Channel.Name }}(const {{ cppChannelMsgType .Channel.Name }} msg);
{{- end }}

Secondly, the implementation of those prototypes (I never noticed the repetition in the function header before!):

{{- range .Transitions.Out }}
void StateMachine::{{ cppCallbackName .Channel.Name }}(const {{ cppChannelMsgType .Channel.Name }} msg)
{
{{- block "out_callback" . }}
{{- template "out_callback.cpp.tmpl" . }}
{{- end -}}
}
{{- end }}

Note that this calls into a template that requires the aggregate transition set for the channel. Since the aim of the template will still be to dispatch on all the transitions involving that channel and then give up if we're not in any relevant state -- all we're doing is creating new callbacks that have no relevant states! --, this should probably remain the same, with some zero value or suchlike passed in.

And thirdly, this snippet here in the ROS main template, generating the subscribers:

{{ range .Transitions.Out }}
auto {{ template "subscriber_name" . }} = nh.subscribe("{{ template "topic_name" . }}", 10, &StateMachine::{{ cppCallbackName .Channel.Name }}, &stm);
{{- end }}

Of course, the question is what to replace .Transitions.Out with. We'll still need .Transitions.Out to be able to define the callback bodies, but . should probably be carrying a new list of output channels that may or may not have transitions in this test. This links back to #8 in that the channel list (and their types and directionalities) should probably be explicit rather than inferred.

@pefribeiro
Copy link

Thanks @MattWindsor91 for the details. I was under the impression that it would be sufficient to change the way in which the state machine is generated, by having additional information about all inputs/outputs (and possibly whether that should lead to stopping the machine), rather than the templates themselves? But I could be wrong. I'll take your input into consideration when I come to revisiting this.

@MattWindsor91
Copy link
Collaborator Author

@pefribeiro I forgot just how much of the logic I put in the templates...! (Wanting a powerful template language I understood better than Xtend templates is why I wrote this in Go, but at the same time I realise that the templates are somewhat reminiscent of line noise in places.)

If it was possible for a transition to throw the test off-script rather than always transitioning to another state, it might be possible to saturate the state machine by adding transitions for all outputs into the states that are accepting inputs? But that'd need a change to the templates anyway, I'd suspect, to teach them how to handle the new possibility of an off-script transition.

pefribeiro added a commit that referenced this issue Jul 27, 2023
* I now calculate output channels that are unused in the transitions and ensure that these are subscribed to and that they lead to off_script.
* I now use the fully qualified name for a channel including the 'in' and 'out' in the gen.xml file. In the internal data structures it isn't clear when this is a 'channel' or not, esp. intermediate representation.
* This now means that the b2x tests pass for the battery monitor.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants