Galaxis Codebase  1.0.0
Team Galaxis software stack for the Carolo Cup 2023 - ROS2 based software
masterNode.cpp
Go to the documentation of this file.
1 #include "masterNode.hpp"
2 #include <rclcpp/rclcpp.hpp>
4 #include <functional>
5 #include <string>
6 #include <sstream>
7 #include <galaxis/cuprules.hpp>
8 #include <utils/logger.hpp>
9 
10 #include <unistd.h>
11 
12 static long long
14  auto time_now = std::chrono::system_clock::now();
15  auto time_now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(time_now);
16  auto time_value = time_now_ms.time_since_epoch();
17  return time_value.count();
18 }
19 
21  Node("master_node") {
22  this->nodeName = this->get_name();
23  std::string info_msg = "Initializing master_node";
24 
25  galaxis::utils::log(info_msg);
26 
27  init();
28 }
29 
31  std::string info_msg("Shutting down");
32  galaxis::utils::log(info_msg);
33 }
34 
35 void
37  m_ecuOnlineStatus = false;
38 
39  /* for create_publisher and create_subscriber */
40  using std::placeholders::_1;
41 
42  galaxis::ros::create_publisher(this, service_state_pub_);
43  galaxis::ros::create_publisher(this, settingsValuesPubSPtr);
44  galaxis::ros::create_subscription(this,
46  std::bind(&masterNode::heartbeat_callback, this, _1));
47  galaxis::ros::create_subscription(this,
49  std::bind(&masterNode::callback_buttonState, this, _1));
50 
51  periodic_timer_ = this->create_wall_timer(std::chrono::milliseconds{ _HEARTBEAT_CHECK_PERIOD }, std::bind(&masterNode::check_heartbeats, this));
52  periodic_timer_print_system_status_ = this->create_wall_timer(std::chrono::milliseconds{ 1000 }, std::bind(&masterNode::print_system_status, this));
53  /* WAIT FOR ALL NODES TO BE RUNNING AND THEN SEND STATE?! */
54 
55  // Insert Nodes // TODO
56  system_state_.insert(std::make_pair<std::string, std::pair<long long, galaxis::serviceStates::State>>("ControllerNode", std::make_pair<long long, galaxis::serviceStates::State>(0, galaxis::serviceStates::State::BOOTSTRAP)));
57  system_state_.insert(std::make_pair<std::string, std::pair<long long, galaxis::serviceStates::State>>("Autopilot", std::make_pair<long long, galaxis::serviceStates::State>(0, galaxis::serviceStates::State::BOOTSTRAP)));
58  system_state_.insert(std::make_pair<std::string, std::pair<long long, galaxis::serviceStates::State>>("ecu_node", std::make_pair<long long, galaxis::serviceStates::State>(0, galaxis::serviceStates::State::BOOTSTRAP)));
59  // system_state_.insert(std::make_pair<std::string, std::pair<long long, galaxis::serviceStates::State>>("ObjectDetector", std::make_pair<long long, galaxis::serviceStates::State>(0, galaxis::serviceStates::State::BOOTSTRAP)));
60 
61  // std::thread(&masterNode::initial_set_ecu_settings, this).detach();
62 }
63 
64 void
66  return;
67  // if(m_ecuOnlineStatus) {
68  // RCLCPP_INFO(this->get_logger(), "SET INITIAL ECU SETTINGS");
69  // // Training
70  // /* set required car settings like speed */
71  // auto msgUPtr = std::make_unique<SettingsValuesType>();
72  // msgUPtr->firmware.rc_use_erpm = cuprules::modes::training::rc_use_erpm;
73  // msgUPtr->firmware.erpm_max_rc = cuprules::modes::training::erpm_max_rc;
74  // RCLCPP_INFO(this->get_logger(), "ERPM max is : %f", msgUPtr->firmware.erpm_max_rc);
75  // RCLCPP_INFO(this->get_logger(), "Sending settings for btn1");
76  // //settingsValuesPubSPtr->publish(std::move(msgUPtr));
77 
78  // m_ecuInitStatus = true;
79  // }
80 }
81 
82 void
84  std::ostringstream ostring;
85  ostring << "System State (" << m_currentServiceState << "): \n";
86  long long timeNow = __get_time_now_ms();
87 
88  for(auto& x: system_state_) {
89  ostring << x.first << "\t\t";
90  if(timeNow - x.second.first > _HEARTBEAT_MAXIMUM_OFF_TIME_MS) {
91  ostring << "offline";
92  } else {
93  ostring << "online\t\tmode: " << x.second.second << "\t\t" << (timeNow - x.second.first);
94  }
95  ostring << "\n";
96  }
97 
98  RCLCPP_INFO(this->get_logger(), "%s", ostring.str().c_str());
99 }
100 
101 bool
103  long long timeNow = __get_time_now_ms();
104  bool systemOnline = true;
105 
106  for(auto& node: system_state_) {
107  if(timeNow - node.second.first > _HEARTBEAT_MAXIMUM_OFF_TIME_MS) {
108  systemOnline = false;
109 
110  if(node.first.compare("ecu_node") == 0)
111  m_ecuOnlineStatus = false;
112  }
113  }
114 
115  return systemOnline;
116 }
117 
118 void
120  return; // DISABLE FUNCTION
121  bool systemOnline = getSystemOnlineState();
122 
123  if(systemOnline == false) {
125  }
126 
127  if(m_systemOnlineStatus == false && systemOnline == true) {
129  }
130 
131  m_systemOnlineStatus = systemOnline;
132 
133  //ecu init
134  if(m_ecuInitStatus == false) {
135  // initial_set_ecu_settings();
136  }
137 }
138 
139 void
141  //if (m_previousServiceState != p_state && (m_systemOnlineStatus || p_force || true)) { // m_systemOnlineStatus disabled
143  m_currentServiceState = p_state;
144 
145  ServiceStateType::UniquePtr serviceStateMsgUPtr = std::make_unique<ServiceStateType>();
146  serviceStateMsgUPtr->state = get_service_state_by_enum_state(p_state);
147  service_state_pub_->publish(std::move(serviceStateMsgUPtr));
148  RCLCPP_INFO(this->get_logger(), "!SystemState switched to: %i", p_state);
149  //}
150 }
151 
152 void
153 masterNode::heartbeat_callback(HeartbeatMessageType::SharedPtr const msg) {
154  if(system_state_.find(msg->node_name.c_str()) == system_state_.end()) {
155  system_state_.insert(std::pair<std::string, std::pair<long long, galaxis::serviceStates::State>>(msg->node_name, std::pair<long long, galaxis::serviceStates::State>(__get_time_now_ms(), static_cast<galaxis::serviceStates::State>(msg->service_state.state))));
156  } else {
157  system_state_.find(msg->node_name.c_str())->second = std::pair<long long, galaxis::serviceStates::State>(__get_time_now_ms(), static_cast<galaxis::serviceStates::State>(msg->service_state.state));
158  }
159 
160  if(msg->node_name.compare("ecu_node") == 0) {
161  m_ecuOnlineStatus = true;
162  }
163 
164  //RCLCPP_INFO(this->get_logger(), "[HEARTBEAT] %s: %i", msg->node_name.c_str(), msg->service_state.state);
165  //print_system_status();
166 }
167 
168 void
170  // TODO?
171 }
172 
173 void
174 masterNode::callback_buttonState(ButtonStateMessageType::SharedPtr const buttonStateMsgSPtr) {
175  RCLCPP_INFO(this->get_logger(), "Got new buttonState message");
176  if(buttonStateMsgSPtr == nullptr) {
177  RCLCPP_ERROR(this->get_logger(), "buttonStateMsgSPtr is nullptr");
179  }
180 
181  uint8_t btn1 = buttonStateMsgSPtr->pressed_button_1;
182  uint8_t btn2 = buttonStateMsgSPtr->pressed_button_2;
183  uint8_t btn3 = buttonStateMsgSPtr->pressed_button_3;
184 
185  uint8_t cnt = (btn1) + (btn3) + (btn2);
186 
187  if(cnt > 1) {
188  RCLCPP_ERROR(this->get_logger(), "Pressed two or more buttons at once, aborting");
189  return;
190  } else if(cnt == 0) { // no button pressed
191  return;
192  }
193 
195 
196  if(btn1) {
197  // Training
198  /* set required car settings like speed */
199  auto msgUPtr = std::make_unique<SettingsValuesType>();
200  msgUPtr->firmware.rc_use_erpm = cuprules::modes::training::rc_use_erpm;
201  msgUPtr->firmware.erpm_max_rc = cuprules::modes::training::erpm_max_rc;
202  msgUPtr->firmware.servo_offset.front = 5;
203  msgUPtr->firmware.servo_offset.rear = 0;
204  RCLCPP_INFO(this->get_logger(), "ERPM max is : %f", msgUPtr->firmware.erpm_max_rc);
205  RCLCPP_INFO(this->get_logger(), "Sending settings for btn1");
206  settingsValuesPubSPtr->publish(std::move(msgUPtr));
207 
208  // stop controller
209  handle_controller(false);
210 
211  //newServiceState = galaxis::serviceStates::btnStateMap[galaxis::serviceStates::ButtonType::BTN_SC1];
212  //switch_system_state(newServiceState);
213  } else if(btn2) {
214  // Free Driving
215  /* set required car settings like speed */
216  auto msgUPtr = std::make_unique<SettingsValuesType>();
217  msgUPtr->firmware.rc_use_erpm = cuprules::modes::free_driving::rc_use_erpm;
218  msgUPtr->firmware.erpm_max_rc = cuprules::modes::free_driving::erpm_max_rc;
219  msgUPtr->firmware.servo_offset.front = 5;
220  msgUPtr->firmware.servo_offset.rear = 0;
221  RCLCPP_INFO(this->get_logger(), "FREE DRIVING (btn2)");
222  RCLCPP_INFO(this->get_logger(), "Sending settings for btn2");
223  settingsValuesPubSPtr->publish(std::move(msgUPtr));
224 
225  usleep(100);
226 
227  // start controller
228  handle_controller(true);
229 
230  //newServiceState = galaxis::serviceStates::btnStateMap[galaxis::serviceStates::ButtonType::BTN_SC2];
231  newServiceState = galaxis::serviceStates::FREE_DRIVING;
232  switch_system_state(newServiceState);
233  } else if(btn3) {
234  // Obstacle Driving
235  /* set required car settings like speed */
236  auto msgUPtr = std::make_unique<SettingsValuesType>();
237  msgUPtr->firmware.rc_use_erpm = cuprules::modes::obstacle_driving::rc_use_erpm;
238  msgUPtr->firmware.erpm_max_rc = cuprules::modes::obstacle_driving::erpm_max_rc;
239  msgUPtr->firmware.servo_offset.front = 5;
240  msgUPtr->firmware.servo_offset.rear = 0;
241  RCLCPP_INFO(this->get_logger(), "OBSTACLE DRIVING (btn3)");
242  RCLCPP_INFO(this->get_logger(), "Sending settings for btn2");
243  settingsValuesPubSPtr->publish(std::move(msgUPtr));
244 
245  // start controller
246  handle_controller(true);
247 
248  usleep(100);
249 
250  // newServiceState = galaxis::serviceStates::btnStateMap[galaxis::serviceStates::ButtonType::BTN_SC3];
252  switch_system_state(newServiceState);
253  } else {
254  // pass
255  }
256 }
257 
261  switch(p_state) {
262  case messages::msg::ServiceState::STATE_BOOTSTRAP:
264  break;
265  case messages::msg::ServiceState::STATE_FREE_DRIVING:
267  break;
268  case messages::msg::ServiceState::STATE_OBSTACLE_DRIVING:
270  break;
271  default:
272  RCLCPP_ERROR(this->get_logger(), "p_state not known %u", p_state);
274  break;
275  }
276 
277  return state;
278 }
279 
280 uint8_t
282  uint8_t state;
283  switch(p_state) {
285  state = messages::msg::ServiceState::STATE_BOOTSTRAP;
286  break;
288  state = messages::msg::ServiceState::STATE_FREE_DRIVING;
289  break;
291  state = messages::msg::ServiceState::STATE_OBSTACLE_DRIVING;
292  break;
293  default:
294  RCLCPP_ERROR(this->get_logger(), "p_state unknwon -> %u", p_state);
295  state = messages::msg::ServiceState::STATE_BOOTSTRAP;
296  break;
297  }
298 
299  return state;
300 }
masterNode::masterNode
masterNode()
Definition: masterNode.cpp:20
masterNode::m_previousServiceState
galaxis::serviceStates::State m_previousServiceState
Definition: masterNode.hpp:30
masterNode::get_service_state_by_uint8
galaxis::serviceStates::State get_service_state_by_uint8(uint8_t p_state)
Definition: masterNode.cpp:259
galaxis::serviceStates::OBSTACLE_DRIVING
@ OBSTACLE_DRIVING
Definition: ServiceState.hpp:13
masterNode::print_system_status
void print_system_status()
Definition: masterNode.cpp:83
__get_time_now_ms
static long long __get_time_now_ms()
Definition: masterNode.cpp:13
cuprules::modes::obstacle_driving::rc_use_erpm
const uint8_t rc_use_erpm
Definition: cuprules.hpp:19
masterNode::m_ecuOnlineStatus
bool m_ecuOnlineStatus
Definition: masterNode.hpp:33
masterNode::switch_system_state
void switch_system_state(galaxis::serviceStates::State p_state, bool p_force)
Definition: masterNode.cpp:140
node_ros_pubsub_wrapper.hpp
cuprules::modes::free_driving::rc_use_erpm
const uint8_t rc_use_erpm
Definition: cuprules.hpp:14
masterNode::heartbeat_sub_
rclcpp::Subscription< HeartbeatMessageType >::SharedPtr heartbeat_sub_
Definition: masterNode.hpp:25
masterNode::buttonStateSubSPtr
rclcpp::Subscription< ButtonStateMessageType >::SharedPtr buttonStateSubSPtr
Definition: masterNode.hpp:26
masterNode::periodic_timer_print_system_status_
rclcpp::TimerBase::SharedPtr periodic_timer_print_system_status_
Definition: masterNode.hpp:27
masterNode::init
void init(void)
Definition: masterNode.cpp:36
galaxis::Errors::POINTER_ERROR
Definition: Errors.hpp:18
masterNode::service_state_pub_
rclcpp::Publisher< ServiceStateType >::SharedPtr service_state_pub_
Definition: masterNode.hpp:23
_HEARTBEAT_MAXIMUM_OFF_TIME_MS
constexpr long long _HEARTBEAT_MAXIMUM_OFF_TIME_MS
Definition: masterNode.hpp:12
masterNode::check_heartbeats
void check_heartbeats()
Definition: masterNode.cpp:119
masterNode::system_state_
std::map< std::string, std::pair< long long, galaxis::serviceStates::State > > system_state_
Definition: masterNode.hpp:20
cuprules::modes::training::erpm_max_rc
const float erpm_max_rc
Definition: cuprules.hpp:10
masterNode::callback_buttonState
void callback_buttonState(ButtonStateMessageType::SharedPtr const buttonStateMsgSPtr)
Definition: masterNode.cpp:174
masterNode::m_systemOnlineStatus
bool m_systemOnlineStatus
Definition: masterNode.hpp:31
galaxis::serviceStates::BOOTSTRAP
@ BOOTSTRAP
Definition: ServiceState.hpp:10
masterNode::getSystemOnlineState
bool getSystemOnlineState()
Definition: masterNode.cpp:102
masterNode.hpp
masterNode::m_currentServiceState
galaxis::serviceStates::State m_currentServiceState
Definition: masterNode.hpp:29
cuprules.hpp
masterNode::periodic_timer_
rclcpp::TimerBase::SharedPtr periodic_timer_
Definition: masterNode.hpp:27
masterNode::~masterNode
~masterNode()
Definition: masterNode.cpp:30
masterNode::settingsValuesPubSPtr
rclcpp::Publisher< SettingsValuesType >::SharedPtr settingsValuesPubSPtr
Definition: masterNode.hpp:24
masterNode::m_ecuInitStatus
bool m_ecuInitStatus
Definition: masterNode.hpp:34
logger.hpp
galaxis::serviceStates::FREE_DRIVING
@ FREE_DRIVING
Definition: ServiceState.hpp:12
masterNode::heartbeat_callback
void heartbeat_callback(const messages::msg::Heartbeat::SharedPtr msg)
Definition: masterNode.cpp:153
galaxis::utils::log
void log(const Args &... args)
Definition: logger.hpp:33
masterNode::handle_controller
void handle_controller(bool start)
Definition: masterNode.cpp:169
_HEARTBEAT_CHECK_PERIOD
constexpr long long _HEARTBEAT_CHECK_PERIOD
Definition: masterNode.hpp:11
cuprules::modes::obstacle_driving::erpm_max_rc
const float erpm_max_rc
Definition: cuprules.hpp:20
cuprules::modes::training::rc_use_erpm
const uint8_t rc_use_erpm
Definition: cuprules.hpp:9
masterNode::get_service_state_by_enum_state
uint8_t get_service_state_by_enum_state(galaxis::serviceStates::State p_state)
Definition: masterNode.cpp:281
masterNode::initial_set_ecu_settings
void initial_set_ecu_settings()
Definition: masterNode.cpp:65
masterNode::nodeName
std::string nodeName
Definition: masterNode.hpp:22
cuprules::modes::free_driving::erpm_max_rc
const float erpm_max_rc
Definition: cuprules.hpp:15
galaxis::serviceStates::State
State
Definition: ServiceState.hpp:9