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
00026
00027
00028
00029
00030
00031
00032 #ifndef __COMM_H__
00033 #define __COMM_H__
00034
00035 #include <iostream>
00036 #include <map>
00037 #include <vector>
00038 #include <boost/bind.hpp>
00039 #include <boost/function.hpp>
00040 #include <boost/shared_ptr.hpp>
00041 #include <boost/thread.hpp>
00042 #include <boost/asio.hpp>
00043
00044 #include <ros/ros.h>
00045
00046
00047 #include <asctec_hl_comm/HL_interface.h>
00048
00049 typedef boost::function<void(uint8_t*, int32_t)> CommCallbackType;
00050 typedef std::map<uint8_t, CommCallbackType> CommCallbackMap;
00051
00052 class Comm;
00053 typedef boost::shared_ptr<Comm> CommPtr;
00054
00056
00062 class Comm
00063 {
00064 typedef boost::asio::serial_port SerialPort;
00065 typedef boost::shared_ptr<SerialPort> SerialPortPtr;
00066
00067 private:
00068
00069 SerialPortPtr port_rx_;
00070 SerialPortPtr port_tx_;
00071 boost::asio::io_service uart_service_;
00072 boost::asio::deadline_timer rx_timeout_;
00073 bool rx_timeout_occurred_;
00074 boost::thread uart_thread_[2];
00075
00076 std::string port_rx_name_;
00077 std::string port_tx_name_;
00078
00079 uint32_t rx_packet_cnt_;
00080 uint32_t rx_packet_good_cnt_;
00081
00082 uint8_t tx_buffer_[256];
00083 uint8_t rx_buffer_[256];
00084 uint32_t tx_bytes2send_;
00085 int rx_state_;
00086 std::vector<uint8_t> packet_acks_;
00087 boost::mutex tx_mutex_;
00088 const int TX_HEADER_SIZE;
00089
00090 CommCallbackMap callbacks_;
00091
00092 void rxReadStart(uint32_t length, uint32_t timeout = 0);
00093 void rxReadCallback(const boost::system::error_code& error, size_t bytes_transferred);
00094 void rxTimeoutCallback(const boost::system::error_code & error);
00095 bool configurePort(SerialPortPtr & serial_port, uint32_t *baudrate);
00096 bool connect(SerialPortPtr & serial_port, const std::string & port, uint32_t baudrate);
00097
00098 void processPacketAck(uint8_t * buf, uint32_t length);
00099 bool validateChecksum(uint8_t * buf, uint32_t length, uint16_t checksum);
00100
00101 bool waitForPacketAck(uint8_t ack_id, const double & timeout = 1.0);
00102
00103 inline uint16_t crc_update(uint16_t crc, uint8_t data);
00104 uint16_t crc16(void* data, uint16_t cnt, uint16_t crc = 0xff);
00105
00106 void serializePacket(uint8_t packet_id, const void * data, const int32_t & packet_size, uint8_t flag = 0);
00107
00108 public:
00109 Comm();
00110
00111 ~Comm();
00112
00114
00125 bool connect(const std::string & port_rx, const std::string & port_tx, uint32_t baudrate);
00126
00128 void close();
00129
00130 uint32_t getRxPackets()
00131 {
00132 return rx_packet_cnt_;
00133 }
00134
00135 uint32_t getRxPacketsGood()
00136 {
00137 return rx_packet_good_cnt_;
00138 }
00139
00141 template<typename T>
00142 bool sendPacket(uint8_t packet_id, const T & data)
00143 {
00144 serializePacket(packet_id, &data, sizeof(T));
00145
00146 return tx_bytes2send_ == boost::asio::write(*port_tx_, boost::asio::buffer(tx_buffer_, tx_bytes2send_));
00147 }
00148
00150 template<typename T>
00151 bool sendPacketAck(uint8_t packet_id, const T & data, const double & timeout = 1.0)
00152 {
00153
00154 ros::Time time_start = ros::Time::now();
00155 uint8_t ack_id = (uint8_t)(time_start.toNSec() & 0xff) | HLI_COMM_ACK;
00156
00157
00158
00159
00160 serializePacket(packet_id, &data, sizeof(T), ack_id);
00161 if (tx_bytes2send_ != boost::asio::write(*port_tx_, boost::asio::buffer(tx_buffer_, tx_bytes2send_)))
00162 return false;
00163
00164 return waitForPacketAck(ack_id, timeout);
00165 }
00166
00168
00175 template<class T>
00176 void registerCallback(uint8_t id, void(T::*cb_func)(uint8_t*, uint32_t), T* p_obj)
00177 {
00178 if (callbacks_.find(id) != callbacks_.end())
00179 std::cerr<<"message "<< id << "is already registered"<<std::endl;
00180 else
00181 callbacks_[id] = boost::bind(cb_func, p_obj, _1, _2);
00182 }
00183 void loopOnce(){uart_service_.run_one();};
00184 };
00185
00186 #endif