cob_relayboard_node.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 //##################
19 //#### includes ####
20 
21 // standard includes
22 //--
23 
24 // ROS includes
25 #include <ros/ros.h>
27 
28 // ROS message includes
29 #include <std_msgs/Bool.h>
30 #include <std_msgs/Float64.h>
31 #include <cob_msgs/EmergencyStopState.h>
32 
33 // ROS service includes
34 //--
35 
36 // external includes
37 //--
38 
39 //####################
40 //#### node class ####
41 class NodeClass
42 {
43  //
44 public:
45  // create a handle for this node, initialize node
48 
49  // topics to publish
52  // topics to subscribe, callback is called for new messages arriving
53  // --
54 
55  // Constructor
57  {
58  n = ros::NodeHandle();
59  n_priv = ros::NodeHandle("~");
60 
61  topicPub_isEmergencyStop = n.advertise<cob_msgs::EmergencyStopState>("emergency_stop_state", 1);
62  topicPub_Voltage = n.advertise<std_msgs::Float64>("voltage", 1);
63 
64  // Make sure member variables have a defined state at the beginning
66  relayboard_available = false;
67  relayboard_online = false;
68  relayboard_timeout_ = 2.0;
71  }
72 
73  // Destructor
75  {
76  delete m_SerRelayBoard;
77  }
78 
80  void sendBatteryVoltage();
81  int init();
82 
83 private:
84  std::string sComPort;
86 
92 
94  bool relayboard_online; //the relayboard is sending messages at regular time
95  bool relayboard_available; //the relayboard has sent at least one message -> publish topic
96 
97  // possible states of emergency stop
98  enum
99  {
103  };
104 
105  int requestBoardStatus();
106 };
107 
108 //#######################
109 //#### main programm ####
110 int main(int argc, char** argv)
111 {
112  // initialize ROS, spezify name of node
113  ros::init(argc, argv, "cob_relayboard_node");
114 
115  NodeClass node;
116  if(node.init() != 0) return 1;
117 
118  ros::Rate r(20); //Cycle-Rate: Frequency of publishing EMStopStates
119  while(node.n.ok())
120  {
122 
123  ros::spinOnce();
124  r.sleep();
125  }
126 
127  return 0;
128 }
129 
130 //##################################
131 //#### function implementations ####
132 
134 {
135  if (n_priv.hasParam("ComPort"))
136  {
137  n_priv.getParam("ComPort", sComPort);
138  ROS_INFO("Loaded ComPort parameter from parameter server: %s",sComPort.c_str());
139  }
140  else
141  {
142  sComPort ="/dev/ttyUSB0";
143  ROS_WARN("ComPort Parameter not available, using default Port: %s",sComPort.c_str());
144  }
145 
146  n_priv.param("relayboard_timeout", relayboard_timeout_, 2.0);
147  n_priv.param("protocol_version", protocol_version_, 1);
148 
150  ROS_INFO("Opened Relayboard at ComPort = %s", sComPort.c_str());
151 
153 
154  // Init member variable for EM State
157 
158  return 0;
159 }
160 
162  int ret;
163 
164  // Request Status of RelayBoard
165  ret = m_SerRelayBoard->sendRequest();
166  if(ret != SerRelayBoard::NO_ERROR) {
167  ROS_ERROR("Error in sending message to Relayboard over SerialIO, lost bytes during writing");
168  }
169 
170  ret = m_SerRelayBoard->evalRxBuffer();
172  ROS_ERROR("Failed to read relayboard data over Serial, the device is not initialized");
173  relayboard_online = false;
174  } else if(ret==SerRelayBoard::NO_MESSAGES) {
175  ROS_ERROR("For a long time, no messages from RelayBoard have been received, check com port!");
178  //ROS_ERROR("Relayboard: Too less bytes in queue");
179  } else if(ret==SerRelayBoard::CHECKSUM_ERROR) {
180  ROS_ERROR("A checksum error occurred while reading from relayboard data");
181  } else if(ret==SerRelayBoard::NO_ERROR) {
182  relayboard_online = true;
183  relayboard_available = true;
185  }
186 
187  return 0;
188 }
189 
191 {
192  std_msgs::Float64 voltage;
193  voltage.data = m_SerRelayBoard->getBatteryVoltage()/1000.0; //normalize from mV to V
194  topicPub_Voltage.publish(voltage);
195 }
196 
198 {
200 
201  if(!relayboard_available) return;
202 
204 
205 
206  bool EM_signal;
207  ros::Duration duration_since_EM_confirmed;
208  cob_msgs::EmergencyStopState EM_msg;
209 
210  // assign input (laser, button) specific EM state TODO: Laser and Scanner stop can't be read independently (e.g. if button is stop --> no informtion about scanner, if scanner ist stop --> no informtion about button stop)
211  EM_msg.emergency_button_stop = m_SerRelayBoard->isEMStop();
212  EM_msg.scanner_stop = m_SerRelayBoard->isScannerStop();
213 
214  // determine current EMStopState
215  EM_signal = (EM_msg.emergency_button_stop || EM_msg.scanner_stop);
216 
217  switch (EM_stop_status_)
218  {
219  case ST_EM_FREE:
220  {
221  if (EM_signal == true)
222  {
223  ROS_INFO("Emergency stop was issued");
224  EM_stop_status_ = EM_msg.EMSTOP;
225  }
226  break;
227  }
228  case ST_EM_ACTIVE:
229  {
230  if (EM_signal == false)
231  {
232  ROS_INFO("Emergency stop was confirmed");
233  EM_stop_status_ = EM_msg.EMCONFIRMED;
235  }
236  break;
237  }
238  case ST_EM_CONFIRMED:
239  {
240  if (EM_signal == true)
241  {
242  ROS_INFO("Emergency stop was issued");
243  EM_stop_status_ = EM_msg.EMSTOP;
244  }
245  else
246  {
247  duration_since_EM_confirmed = ros::Time::now() - time_of_EM_confirmed_;
248  if( duration_since_EM_confirmed.toSec() > duration_for_EM_free_.toSec() )
249  {
250  ROS_INFO("Emergency stop released");
251  EM_stop_status_ = EM_msg.EMFREE;
252  }
253  }
254  break;
255  }
256  };
257 
258 
259  EM_msg.emergency_state = EM_stop_status_;
260 
261  //publish EM-Stop-Active-messages, when connection to relayboard got cut
262  if(relayboard_online == false) {
263  EM_msg.emergency_state = EM_msg.EMSTOP;
264  }
266 }
ros::Publisher topicPub_Voltage
void sendEmergencyStopStates()
ros::Publisher topicPub_isEmergencyStop
void publish(const boost::shared_ptr< M > &message) const
ros::Time time_of_EM_confirmed_
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ros::Duration duration_for_EM_free_
double relayboard_timeout_
#define ROS_WARN(...)
int main(int argc, char **argv)
ros::Time time_last_message_received_
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
int getBatteryVoltage()
Definition: SerRelayBoard.h:54
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
SerRelayBoard * m_SerRelayBoard
bool sleep()
ros::NodeHandle n
bool getParam(const std::string &key, std::string &s) const
static Time now()
std::string sComPort
bool ok() const
bool hasParam(const std::string &key) const
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
ros::NodeHandle n_priv


cob_relayboard
Author(s): Christian Connette
autogenerated on Wed Apr 7 2021 02:11:46