Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <ros/ros.h>
00026 #include <cob_relayboard/SerRelayBoard.h>
00027
00028
00029 #include <std_msgs/Bool.h>
00030 #include <std_msgs/Float64.h>
00031 #include <cob_msgs/EmergencyStopState.h>
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 class NodeClass
00042 {
00043
00044 public:
00045
00046 ros::NodeHandle n;
00047 ros::NodeHandle n_priv;
00048
00049
00050 ros::Publisher topicPub_isEmergencyStop;
00051 ros::Publisher topicPub_Voltage;
00052
00053
00054
00055
00056 NodeClass()
00057 {
00058 n = ros::NodeHandle();
00059 n_priv = ros::NodeHandle("~");
00060
00061 topicPub_isEmergencyStop = n.advertise<cob_msgs::EmergencyStopState>("emergency_stop_state", 1);
00062 topicPub_Voltage = n.advertise<std_msgs::Float64>("voltage", 1);
00063
00064
00065 EM_stop_status_ = ST_EM_FREE;
00066 relayboard_available = false;
00067 relayboard_online = false;
00068 relayboard_timeout_ = 2.0;
00069 protocol_version_ = 1;
00070 duration_for_EM_free_ = ros::Duration(1);
00071 }
00072
00073
00074 ~NodeClass()
00075 {
00076 delete m_SerRelayBoard;
00077 }
00078
00079 void sendEmergencyStopStates();
00080 void sendBatteryVoltage();
00081 int init();
00082
00083 private:
00084 std::string sComPort;
00085 SerRelayBoard * m_SerRelayBoard;
00086
00087 int EM_stop_status_;
00088 ros::Duration duration_for_EM_free_;
00089 ros::Time time_of_EM_confirmed_;
00090 double relayboard_timeout_;
00091 int protocol_version_;
00092
00093 ros::Time time_last_message_received_;
00094 bool relayboard_online;
00095 bool relayboard_available;
00096
00097
00098 enum
00099 {
00100 ST_EM_FREE = 0,
00101 ST_EM_ACTIVE = 1,
00102 ST_EM_CONFIRMED = 2
00103 };
00104
00105 int requestBoardStatus();
00106 };
00107
00108
00109
00110 int main(int argc, char** argv)
00111 {
00112
00113 ros::init(argc, argv, "cob_relayboard_node");
00114
00115 NodeClass node;
00116 if(node.init() != 0) return 1;
00117
00118 ros::Rate r(20);
00119 while(node.n.ok())
00120 {
00121 node.sendEmergencyStopStates();
00122
00123 ros::spinOnce();
00124 r.sleep();
00125 }
00126
00127 return 0;
00128 }
00129
00130
00131
00132
00133 int NodeClass::init()
00134 {
00135 if (n_priv.hasParam("ComPort"))
00136 {
00137 n_priv.getParam("ComPort", sComPort);
00138 ROS_INFO("Loaded ComPort parameter from parameter server: %s",sComPort.c_str());
00139 }
00140 else
00141 {
00142 sComPort ="/dev/ttyUSB0";
00143 ROS_WARN("ComPort Parameter not available, using default Port: %s",sComPort.c_str());
00144 }
00145
00146 n_priv.param("relayboard_timeout", relayboard_timeout_, 2.0);
00147 n_priv.param("protocol_version", protocol_version_, 1);
00148
00149 m_SerRelayBoard = new SerRelayBoard(sComPort, protocol_version_);
00150 ROS_INFO("Opened Relayboard at ComPort = %s", sComPort.c_str());
00151
00152 m_SerRelayBoard->init();
00153
00154
00155 EM_stop_status_ = ST_EM_ACTIVE;
00156 duration_for_EM_free_ = ros::Duration(1);
00157
00158 return 0;
00159 }
00160
00161 int NodeClass::requestBoardStatus() {
00162 int ret;
00163
00164
00165 ret = m_SerRelayBoard->sendRequest();
00166 if(ret != SerRelayBoard::NO_ERROR) {
00167 ROS_ERROR("Error in sending message to Relayboard over SerialIO, lost bytes during writing");
00168 }
00169
00170 ret = m_SerRelayBoard->evalRxBuffer();
00171 if(ret==SerRelayBoard::NOT_INITIALIZED) {
00172 ROS_ERROR("Failed to read relayboard data over Serial, the device is not initialized");
00173 relayboard_online = false;
00174 } else if(ret==SerRelayBoard::NO_MESSAGES) {
00175 ROS_ERROR("For a long time, no messages from RelayBoard have been received, check com port!");
00176 if(time_last_message_received_.toSec() - ros::Time::now().toSec() > relayboard_timeout_) {relayboard_online = false;}
00177 } else if(ret==SerRelayBoard::TOO_LESS_BYTES_IN_QUEUE) {
00178
00179 } else if(ret==SerRelayBoard::CHECKSUM_ERROR) {
00180 ROS_ERROR("A checksum error occurred while reading from relayboard data");
00181 } else if(ret==SerRelayBoard::NO_ERROR) {
00182 relayboard_online = true;
00183 relayboard_available = true;
00184 time_last_message_received_ = ros::Time::now();
00185 }
00186
00187 return 0;
00188 }
00189
00190 void NodeClass::sendBatteryVoltage()
00191 {
00192 std_msgs::Float64 voltage;
00193 voltage.data = m_SerRelayBoard->getBatteryVoltage()/1000.0;
00194 topicPub_Voltage.publish(voltage);
00195 }
00196
00197 void NodeClass::sendEmergencyStopStates()
00198 {
00199 requestBoardStatus();
00200
00201 if(!relayboard_available) return;
00202
00203 sendBatteryVoltage();
00204
00205
00206 bool EM_signal;
00207 ros::Duration duration_since_EM_confirmed;
00208 cob_msgs::EmergencyStopState EM_msg;
00209
00210
00211 EM_msg.emergency_button_stop = m_SerRelayBoard->isEMStop();
00212 EM_msg.scanner_stop = m_SerRelayBoard->isScannerStop();
00213
00214
00215 EM_signal = (EM_msg.emergency_button_stop || EM_msg.scanner_stop);
00216
00217 switch (EM_stop_status_)
00218 {
00219 case ST_EM_FREE:
00220 {
00221 if (EM_signal == true)
00222 {
00223 ROS_INFO("Emergency stop was issued");
00224 EM_stop_status_ = EM_msg.EMSTOP;
00225 }
00226 break;
00227 }
00228 case ST_EM_ACTIVE:
00229 {
00230 if (EM_signal == false)
00231 {
00232 ROS_INFO("Emergency stop was confirmed");
00233 EM_stop_status_ = EM_msg.EMCONFIRMED;
00234 time_of_EM_confirmed_ = ros::Time::now();
00235 }
00236 break;
00237 }
00238 case ST_EM_CONFIRMED:
00239 {
00240 if (EM_signal == true)
00241 {
00242 ROS_INFO("Emergency stop was issued");
00243 EM_stop_status_ = EM_msg.EMSTOP;
00244 }
00245 else
00246 {
00247 duration_since_EM_confirmed = ros::Time::now() - time_of_EM_confirmed_;
00248 if( duration_since_EM_confirmed.toSec() > duration_for_EM_free_.toSec() )
00249 {
00250 ROS_INFO("Emergency stop released");
00251 EM_stop_status_ = EM_msg.EMFREE;
00252 }
00253 }
00254 break;
00255 }
00256 };
00257
00258
00259 EM_msg.emergency_state = EM_stop_status_;
00260
00261
00262 if(relayboard_online == false) {
00263 EM_msg.emergency_state = EM_msg.EMSTOP;
00264 }
00265 topicPub_isEmergencyStop.publish(EM_msg);
00266 }