SMACC
Loading...
Searching...
No Matches
smacc_state_machine.cpp
Go to the documentation of this file.
1/*****************************************************************************************************************
2 * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018
3 * Authors: Pablo Inigo Blasco, Brett Aldrich
4 *
5 ******************************************************************************************************************/
10#include <smacc_msgs/SmaccStatus.h>
11#include <smacc_msgs/SmaccTransitionLogEntry.h>
12namespace smacc
13{
14using namespace smacc::introspection;
16 : private_nh_("~"), stateSeqCounter_(0)
17{
18 ROS_INFO("Creating State Machine Base");
19 signalDetector_ = signalDetector;
21
22 std::string runMode;
23 if (nh_.getParam("run_mode", runMode))
24 {
25 if (runMode == "debug")
26 {
28 }
29 else if (runMode == "release")
30 {
32 }
33 else
34 {
35 ROS_ERROR("Incorrect run_mode value: %s", runMode.c_str());
36 }
37 }
38 else
39 {
41 }
42}
43
45{
46 ROS_INFO("[SmaccSignals] object signal disconnecting %ld", (long)object_ptr);
47 if(stateCallbackConnections.count(object_ptr) > 0)
48 {
49 auto callbackSemaphore = stateCallbackConnections[object_ptr];
50 callbackSemaphore->finalize();
51 stateCallbackConnections.erase(object_ptr);
52 }
53 else
54 {
55 ROS_INFO("[SmaccSignals] no signals found %ld", (long)object_ptr);
56 }
57}
58
60{
61 ROS_INFO("Finishing State Machine");
62}
63
65{
66}
67
69{
70}
71
73{
74}
75
76const std::map<std::string, std::shared_ptr<smacc::ISmaccOrthogonal>> &ISmaccStateMachine::getOrthogonals() const
77{
78 return this->orthogonals_;
79}
80
82{
83 std::lock_guard<std::recursive_mutex> lock(m_mutex_);
84
85 if (currentStateInfo_ != nullptr)
86 {
87 ROS_WARN_STREAM("[StateMachine] setting state active "
88 << ": " << currentStateInfo_->getFullPath());
89
90 if (this->runMode_ == SMRunMode::DEBUG)
91 {
92 status_msg_.current_states.clear();
93 std::list<const SmaccStateInfo *> ancestorList;
94 currentStateInfo_->getAncestors(ancestorList);
95
96 for (auto &ancestor : ancestorList)
97 {
98 status_msg_.current_states.push_back(ancestor->toShortName());
99 }
100
101 status_msg_.global_variable_names.clear();
102 status_msg_.global_variable_values.clear();
103
104 for (auto entry : this->globalData_)
105 {
106 status_msg_.global_variable_names.push_back(entry.first);
107 status_msg_.global_variable_values.push_back(entry.second.first()); // <- invoke to_string()
108 }
109
110 status_msg_.header.stamp = ros::Time::now();
111 status_msg_.header.frame_id = "odom";
112 this->stateMachineStatusPub_.publish(status_msg_);
113 }
114 }
115}
116
118{
119 smacc_msgs::SmaccTransitionLogEntry transitionLogEntry;
120 transitionLogEntry.timestamp = ros::Time::now();
121 transitionInfoToMsg(transitionInfo, transitionLogEntry.transition);
122 this->transitionLogHistory_.push_back(transitionLogEntry);
123
124 transitionLogPub_.publish(transitionLogEntry);
125}
126
128{
129}
130
132{
133 timer_ = nh_.createTimer(ros::Duration(0.5), &ISmaccStateMachine::state_machine_visualization, this);
134}
135
136void ISmaccStateMachine::initializeROS(std::string shortname)
137{
138 ROS_WARN_STREAM("State machine base creation:" << shortname);
139 // STATE MACHINE TOPICS
140 stateMachinePub_ = nh_.advertise<smacc_msgs::SmaccStateMachine>(shortname + "/smacc/state_machine_description", 1);
141 stateMachineStatusPub_ = nh_.advertise<smacc_msgs::SmaccStatus>(shortname + "/smacc/status", 1);
142 transitionLogPub_ = nh_.advertise<smacc_msgs::SmaccTransitionLogEntry>(shortname + "/smacc/transition_log", 1);
143
144 // STATE MACHINE SERVICES
145 transitionHistoryService_ = nh_.advertiseService(shortname + "/smacc/transition_log_history", &ISmaccStateMachine::getTransitionLogHistory, this);
146}
147
148bool ISmaccStateMachine::getTransitionLogHistory(smacc_msgs::SmaccGetTransitionHistory::Request &req, smacc_msgs::SmaccGetTransitionHistory::Response &res)
149{
150 ROS_WARN("Requesting Transition Log History, current size: %ld", this->transitionLogHistory_.size());
151 res.history = this->transitionLogHistory_;
152 return true;
153}
154
156{
157 std::lock_guard<std::recursive_mutex> lock(m_mutex_);
158
159 smacc_msgs::SmaccStateMachine state_machine_msg;
160 state_machine_msg.states = stateMachineInfo_->stateMsgs;
161 this->stateMachinePub_.publish(state_machine_msg);
162
163 status_msg_.header.stamp = ros::Time::now();
164 this->stateMachineStatusPub_.publish(status_msg_);
165}
166
168{
169 ROS_DEBUG("locking state machine: %s", msg.c_str());
170 m_mutex_.lock();
171}
172
174{
175 ROS_DEBUG("unlocking state machine: %s", msg.c_str());
176 m_mutex_.unlock();
177}
178
180{
181 return demangleSymbol(typeid(*this).name());
182}
183
185{
186 // transition from an orthogonal that doesn’t exist.
187 // transition from a source that doesn’t exist.
188
189 // std::stringstream errorbuffer;
190 // bool errorFound = false;
191
192 // for (auto &stentry : this->stateMachineInfo_->states)
193 // {
194 // auto stinfo = stentry.second;
195
196 // for (auto &transition : stinfo->transitions_)
197 // {
198 // auto evinfo = transition.eventInfo;
199 // bool found = false;
200 // for (auto &orthogonal : orthogonals_)
201 // {
202 // if (orthogonal.first == evinfo->getOrthogonalName())
203 // {
204 // found = true;
205 // break;
206 // }
207 // }
208
209 // if (!found)
210 // {
211 // errorbuffer << "---------" << std::endl
212 // << "[Consistency Checking] Transition event refers not existing orthogonal." << std::endl
213 // << "State: " << demangleType(*stinfo->tid_) << std::endl
214 // << "Transition: " << transition.transitionTypeInfo->getFullName() << std::endl
215 // << "Orthogonal: " << evinfo->getOrthogonalName() << std::endl
216 // << "---------" << std::endl;
217
218 // errorFound = true;
219 // }
220 // //std::string getEventSourceName();
221 // //std::string getOrthogonalName();
222 // }
223 // }
224
225 // if (errorFound)
226 // {
227 // ROS_WARN_STREAM("== STATE MACHINE CONSISTENCY CHECK: ==" << std::endl
228 // << errorbuffer.str() << std::endl
229 // << "=================");
230 // }
231 // cb from a client that doesn’t exist – don’t worry about making clients dynamically.
232}
233
234} // namespace smacc
void publishTransition(const SmaccTransitionInfo &transitionInfo)
std::shared_ptr< SmaccStateMachineInfo > stateMachineInfo_
void initializeROS(std::string smshortname)
ISmaccStateMachine(SignalDetector *signalDetector)
smacc_msgs::SmaccStatus status_msg_
void lockStateMachine(std::string msg)
ros::ServiceServer transitionHistoryService_
const std::map< std::string, std::shared_ptr< smacc::ISmaccOrthogonal > > & getOrthogonals() const
std::shared_ptr< SmaccStateInfo > currentStateInfo_
std::map< void *, std::shared_ptr< CallbackCounterSemaphore > > stateCallbackConnections
std::recursive_mutex m_mutex_
void state_machine_visualization(const ros::TimerEvent &)
virtual void onInitialize()
this function should be implemented by the user to create the orthogonals
std::map< std::string, std::shared_ptr< smacc::ISmaccOrthogonal > > orthogonals_
std::map< std::string, std::pair< std::function< std::string()>, boost::any > > globalData_
void unlockStateMachine(std::string msg)
void disconnectSmaccSignalObject(void *object)
std::vector< smacc_msgs::SmaccTransitionLogEntry > transitionLogHistory_
void initialize(ISmaccStateMachine *stateMachine)
void transitionInfoToMsg(const SmaccTransitionInfo &transition, smacc_msgs::SmaccTransition &transitionMsg)
Definition: reflection.cpp:9
std::string demangleSymbol()
Definition: introspection.h:75