SMACC2
Loading...
Searching...
No Matches
cb_default_generic_sensor_behavior.hpp
Go to the documentation of this file.
1// Copyright 2021 RobosoftAI Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
19
20#include <string>
21
24
25namespace cl_generic_sensor
26{
27// Component-based default behavior for multirole sensor client
28// This behavior works with ClGenericSensor and propagates events from components
29template <typename ClientType>
31{
32public:
33 typedef typename ClientType::TMessageType TMessageType;
34
35 ClientType * sensor_;
36
37 // References to the components we'll use
40
45
46 static std::string getEventLabel()
47 {
48 // Show ros message type
49 return smacc2::demangleSymbol(typeid(TMessageType).name());
50 }
51
52 // Deferred event propagation functions - set during orthogonal allocation
53 std::function<void()> deferredComponentConnection;
54
55 template <typename TOrthogonal, typename TSourceObject>
57 {
58 // Setup deferred component connection and event propagation
60 {
61 RCLCPP_INFO(
62 getLogger(),
63 "[CbDefaultGenericSensorBehavior] Connecting to components for client type '%s'",
65
66 // Get the subscriber component from the client
67 this->requiresComponent(subscriberComponent_);
68
69 if (subscriberComponent_ == nullptr)
70 {
71 RCLCPP_ERROR(
72 getLogger(),
73 "[CbDefaultGenericSensorBehavior] Failed to get CpTopicSubscriber component!");
74 return;
75 }
76
77 // Connect to subscriber component signals to propagate events
81 this);
82
86 this);
87
88 RCLCPP_INFO(
89 getLogger(), "[CbDefaultGenericSensorBehavior] Connected to subscriber component");
90
91 // Try to get the timeout component (it's optional)
92 try
93 {
94 this->requiresComponent(timeoutComponent_);
95
96 if (timeoutComponent_ != nullptr)
97 {
98 // Connect to timeout component signal to propagate timeout events
102 this);
103
104 RCLCPP_INFO(
105 getLogger(),
106 "[CbDefaultGenericSensorBehavior] Connected to timeout component (watchdog active)");
107 }
108 }
109 catch (const std::exception & e)
110 {
111 RCLCPP_INFO(
112 getLogger(),
113 "[CbDefaultGenericSensorBehavior] Timeout component not found (watchdog disabled): %s",
114 e.what());
115 }
116 };
117 }
118
119 // Propagate message event with message data
120 template <typename EvType>
122 {
123 RCLCPP_DEBUG(
124 getLogger(), "[CbDefaultGenericSensorBehavior] Propagating message event: %s",
126
127 auto event = new EvType();
128 event->msgData = msg;
129 this->postEvent(event);
130 }
131
132 // Propagate timeout event (no message data)
133 template <typename EvType>
135 {
136 RCLCPP_WARN(
137 getLogger(), "[CbDefaultGenericSensorBehavior] Propagating timeout event: %s",
139
140 this->postEvent<EvType>();
141 }
142
143 void onEntry() override
144 {
145 RCLCPP_INFO(
146 getLogger(), "[CbDefaultGenericSensorBehavior] onEntry. Requires client of type '%s'",
148
149 // Get the client if we don't have it yet
150 if (sensor_ == nullptr)
151 {
152 this->requiresClient(sensor_);
153 }
154
155 if (sensor_ == nullptr)
156 {
157 RCLCPP_FATAL_STREAM(
158 getLogger(),
159 "[CbDefaultGenericSensorBehavior] Sensor client behavior needs a client of type: "
160 << smacc2::demangleSymbol<ClientType>() << " but it is not found.");
161 }
162 else
163 {
164 // Connect to components
166 RCLCPP_INFO(getLogger(), "[CbDefaultGenericSensorBehavior] Sensor behavior initialized");
167 }
168 }
169
170 void onExit() override { RCLCPP_INFO(getLogger(), "[CbDefaultGenericSensorBehavior] onExit"); }
171
172 // Virtual callback for custom message processing in derived behaviors
173 virtual void onMessageCallback(const TMessageType & /*msg*/)
174 {
175 // Empty to fill by sensor customization based on inheritance
176 }
177};
178
179} // namespace cl_generic_sensor
smacc2::client_core_components::CpTopicSubscriber< TMessageType > * subscriberComponent_
cl_generic_sensor::components::CpMessageTimeout< TMessageType > * timeoutComponent_
boost::signals2::connection onMessageTimeout(void(T::*callback)(), T *object)
virtual rclcpp::Logger getLogger() const
void requiresClient(SmaccClientType *&storage)
void requiresComponent(SmaccComponentType *&storage, ComponentRequirement requirementType=ComponentRequirement::SOFT)
boost::signals2::connection onMessageReceived(void(T::*callback)(const MessageType &), T *object)
boost::signals2::connection onFirstMessageReceived(void(T::*callback)(const MessageType &), T *object)
std::string demangleSymbol()