diff --git a/examples/bmon/gen.xml b/examples/bmon/gen.xml
index ba3c360..1cc37f4 100644
--- a/examples/bmon/gen.xml
+++ b/examples/bmon/gen.xml
@@ -4,7 +4,7 @@
-
+
@@ -23,8 +23,8 @@
-
-
+
+
diff --git a/internal/gen/config/cpp/context.go b/internal/gen/config/cpp/context.go
index ad95263..47a468a 100644
--- a/internal/gen/config/cpp/context.go
+++ b/internal/gen/config/cpp/context.go
@@ -3,6 +3,7 @@ package cpp
import (
"github.com/UoY-RoboStar/rtcg/internal/stm"
"github.com/UoY-RoboStar/rtcg/internal/testlang/rstype"
+ "github.com/UoY-RoboStar/rtcg/internal/testlang/channel"
)
// Context contains any context derived from the C++ generator config.
@@ -10,9 +11,11 @@ import (
// This is common to multiple different generators that consider C++ config.
type Context struct {
Includes []Include // Includes contains the user-configured includes.
+ Channels []channel.Channel // All channels
ChannelTypes map[string]ChannelType // ChannelTypes contains the calculated channel types.
HasConversion bool // HasConversion is true if there is a convert.cpp file.
ChannelTopics map[string]string // Mapping from channel name to topic.
+ // ChannelIO map[string] // Indicates whether a channel is input or output.
}
// Process processes a config into a Context.
@@ -20,9 +23,11 @@ type Context struct {
func (c *Config) Process(types stm.TypeMap) Context {
ctx := Context{
Includes: c.Includes,
+ Channels: c.getChannels(),
ChannelTypes: make(map[string]ChannelType, len(types)),
ChannelTopics: c.ChannelTopicMap(),
HasConversion: false,
+// ChannelIO: c.ChannelIO(),
}
overrides := c.ChannelMap()
@@ -50,3 +55,11 @@ type ChannelType struct {
func (t ChannelType) HasOverride() bool {
return t.Override != ""
}
+
+// // ChannelIO defines whether a channel is input or output
+// type ChannelIO uint8
+
+// const (
+// input ChannelIO = iota
+// utput ChannelIO = iota
+// )
\ No newline at end of file
diff --git a/internal/gen/config/cpp/cpp.go b/internal/gen/config/cpp/cpp.go
index 0fb5ae4..ec4f541 100644
--- a/internal/gen/config/cpp/cpp.go
+++ b/internal/gen/config/cpp/cpp.go
@@ -4,6 +4,7 @@ package cpp
import (
"github.com/UoY-RoboStar/rtcg/internal/gen/config/catkin"
"github.com/UoY-RoboStar/rtcg/internal/gen/config/makefile"
+ "github.com/UoY-RoboStar/rtcg/internal/testlang/channel"
)
// Config contains configuration for a C++ generator.
@@ -41,12 +42,35 @@ func WithChannel(name, ty string) Option {
}
}
+func (c *Config) getChannels() []channel.Channel {
+
+ //carray := make([]channel.Channel, len(c.Channels))
+ var carray []channel.Channel
+
+ for _, chi := range c.Channels {
+ ach := new(channel.Channel)
+ err := ach.UnmarshalText([]byte(chi.Name))
+ if (err == nil) {
+ carray = append(carray, *ach)
+ }
+ }
+
+ return carray
+}
+
// ChannelMap gets the Channels field of this Config as a map from channel names to type overrides.
func (c *Config) ChannelMap() map[string]string {
cmap := make(map[string]string, len(c.Channels))
for _, over := range c.Channels {
- cmap[over.Name] = over.Type
+
+ // Create object and parse
+ chp := new(channel.Channel)
+ err := chp.UnmarshalText([]byte(over.Name))
+
+ if err == nil {
+ cmap[chp.Name] = over.Type
+ }
}
return cmap
@@ -57,12 +81,23 @@ func (c *Config) ChannelTopicMap() map[string]string {
cmap := make(map[string]string, len(c.Channels))
for _, over := range c.Channels {
- cmap[over.Name] = over.Topic
+
+ // Create object and parse
+ chp := new(channel.Channel)
+ err := chp.UnmarshalText([]byte(over.Name))
+
+ if err == nil {
+ cmap[chp.Name] = over.Topic
+ } else {
+ cmap[over.Name] = over.Topic
+ }
}
return cmap
}
+// ChannelIO gets the Channel types
+
// Include captures a custom include header.
type Include struct {
diff --git a/internal/gen/cpp/embed/templates/base/stm.cpp.tmpl b/internal/gen/cpp/embed/templates/base/stm.cpp.tmpl
index 3cbedd5..c152a77 100644
--- a/internal/gen/cpp/embed/templates/base/stm.cpp.tmpl
+++ b/internal/gen/cpp/embed/templates/base/stm.cpp.tmpl
@@ -28,6 +28,9 @@ public:
{{- range .Transitions.Out }}
void {{ cppCallbackName .Channel.Name }}(const {{ cppChannelMsgType .Channel.Name }} msg);
{{- end }}
+{{- range cppOtherOutChannels .Transitions.Out .Channels }}
+ void {{ cppCallbackName .Name }}(const {{ cppChannelMsgType .Name }} msg);
+{{- end }}
private:
Verdict verdict_;
State state_ = {{ (index .Stm.States 0).ID | cppStateEnum }};
@@ -131,6 +134,14 @@ void StateMachine::{{ cppCallbackName .Channel.Name }}(const {{ cppChannelMsgTyp
}
{{- end }}
+{{- range cppOtherOutChannels .Transitions.Out .Channels }}
+
+void StateMachine::{{ cppCallbackName .Name }}(const {{ cppChannelMsgType .Name }} msg)
+{
+ ROS_INFO_STREAM("Unexpected message for {{ . }}." << std::endl);
+ end(rtcg::Status::OFF_SCRIPT);
+}
+{{- end }}
//
// State machine entry functions
diff --git a/internal/gen/cpp/embed/templates/ros/main.cpp.tmpl b/internal/gen/cpp/embed/templates/ros/main.cpp.tmpl
index fb6bae6..edba1bb 100644
--- a/internal/gen/cpp/embed/templates/ros/main.cpp.tmpl
+++ b/internal/gen/cpp/embed/templates/ros/main.cpp.tmpl
@@ -64,6 +64,9 @@ const int INPUT_DELAY_SEC = 3;
{{ range .Transitions.Out }}
auto {{ template "subscriber_name" . }} = nh.subscribe("{{ cppChannelTopicName $.ChannelTopics .Channel.Name }}", 10, &StateMachine::{{ cppCallbackName .Channel.Name }}, &stm);
{{- end }}
+{{- range cppOtherOutChannels .Transitions.Out .Channels }}
+ auto {{ toLowerUnderscored .Name }}_sub = nh.subscribe("{{ cppChannelTopicName $.ChannelTopics .Name }}", 10, &StateMachine::{{ cppCallbackName .Name }}, &stm);
+{{- end }}
// Timers
auto timeout_timer = nh.createTimer(ros::Duration(TIMEOUT_SEC), &StateMachine::timeoutCallback, &stm);
diff --git a/internal/gen/cpp/func.go b/internal/gen/cpp/func.go
index ffc2959..9470915 100644
--- a/internal/gen/cpp/func.go
+++ b/internal/gen/cpp/func.go
@@ -5,10 +5,12 @@ import (
"strings"
"text/template"
+ "github.com/UoY-RoboStar/rtcg/internal/stm/transition"
"github.com/UoY-RoboStar/rtcg/internal/strmanip"
"github.com/UoY-RoboStar/rtcg/internal/testlang"
"github.com/UoY-RoboStar/rtcg/internal/testlang/rstype"
"github.com/UoY-RoboStar/rtcg/internal/testlang/value"
+ "github.com/UoY-RoboStar/rtcg/internal/testlang/channel"
)
// Funcs gets the C++ function map.
@@ -18,6 +20,7 @@ func Funcs() template.FuncMap {
"cppChannelMsgType": ChannelMsgType,
"cppChannelValueType": ChannelValueType,
"cppChannelTopicName": ChannelTopicName,
+ "cppOtherOutChannels": OtherOutChannels,
"cppConvertFrom": ConvertFrom,
"cppConvertTo": ConvertTo,
"cppEnumField": EnumField,
@@ -136,3 +139,27 @@ const (
testEnumName = "Test" // testEnumName is the name in the C++ code for the test enum.
outcomeEnumName = "Outcome" // outcomeEnumName is the name in the C++ code for the outcome enum.
)
+
+func OtherOutChannels(tagg []transition.AggregateSet, channels []channel.Channel) []channel.Channel {
+
+ var carray []channel.Channel
+
+ for _, c := range channels {
+
+ if (c.IsOut()) {
+ var inside = false
+
+ for _, t := range tagg {
+ if t.Channel == c {
+ inside = true
+ }
+ }
+
+ if !inside {
+ carray = append(carray, c)
+ }
+ }
+ }
+
+ return carray
+}
\ No newline at end of file