source: pacpussensors/trunk/Sick/SickLDMRSSensor.h@ 54

Last change on this file since 54 was 52, checked in by cfougera, 10 years ago

Memory leak bug resolved (dynamic memory allocation is no longer used).

File size: 8.8 KB
Line 
1/*********************************************************************
2// created: 2014/02/02 - 10:48
3// filename: SickLDMRSSensor.h
4//
5// author: Cyril Fougeray
6// Copyright Heudiasyc UMR UTC/CNRS 6599
7//
8// version: $Id: $
9//
10// purpose: Definition of the SickLDMRSSensor class
11*********************************************************************/
12
13
14
15
16#ifndef SICKLDMRSSENSOR_H
17#define SICKLDMRSSENSOR_H
18
19#include "Pacpus/kernel/ComponentBase.h"
20#include "Pacpus/kernel/DbiteFile.h"
21
22#include "AbstractSickSensor.h"
23#include "SickLDMRSData.h"
24
25#include <fstream>
26#include <string>
27
28#define BODY_MAX_SIZE 10000
29
30// Export macro for SickLDMRS DLL for Windows only
31#ifdef WIN32
32# ifdef SICKLDMRS_EXPORTS
33 // make DLL
34# define SICKLDMRS_API __declspec(dllexport)
35# else
36 // use DLL
37# define SICKLDMRS_API __declspec(dllimport)
38# endif
39#else
40 // On other platforms, simply ignore this
41# define SICKLDMRS_API
42#endif
43
44class QEvent;
45
46namespace pacpus {
47
48class ShMem;
49class SickComponent;
50
51
52
53/// The class carrying Sick LDMRS message.
54/** This class is used so that we can store every information sent by a Sick LDMRS sensor.
55 * First, the raw data is stored in \c body.
56 * These data are then decoded and general information about the message is stored in DataHeader and ScanHeader
57 * (Object data decoding is not implemented yet).
58 * Then, the body field is replaced by a ScanPoint or ScanObject array in order to be stored in DBT/UTC files.
59 */
60class SICKLDMRS_API MessageLDMRS
61{
62public:
63 /// Constructor.
64 MessageLDMRS()
65 {
66 time = 0;
67 timerange = 0;
68 memset(&hData,0,sizeof(hData));
69 memset(&hScan,0,sizeof(hScan));
70 }
71
72 /// Destructor.
73 ~MessageLDMRS(){}
74
75 //! An instance of DataHeader.
76 DataHeader hData;
77
78 //! An instance of ScanHeader (if data type is scan points).
79 ScanHeader hScan;
80
81 //! An array of characters : raw data then array of points or objects, depending on data type.
82 /** This array pointer points to allocated in memory (basically, in heap (malloc)) and then must be freed (free) when the whole message is decoded and stored. */
83 char body[BODY_MAX_SIZE];
84
85 //! Time when the message is received.
86 road_time_t time;
87
88 //! Timerange : roughly, time between measurement of a point and the processing step (not implemented).
89 road_timerange_t timerange;
90};
91
92
93
94//! The class implenting receiving, decoding and storing process of Sick LD-MRS data.
95/**
96 * This class can be used as a particular thread to acquire data from Sick LDMRS sensors.
97 * The Ethernet interface is used to get data from the sensor. Thus, the goal of this class is to
98 * get packets and decode them. Also, it offers the possibility to store all relevant information in
99 * two files (.dbt and .utc).
100 * It can be managed by SickComponent objects.
101 */
102class SickLDMRSSensor : public AbstractSickSensor
103{
104 Q_OBJECT
105public:
106 /// Constructor
107 SickLDMRSSensor(QObject *parent);
108
109 /**
110 * @brief SickLDMRSSensor constructor.
111 * @param parent Basically, a SickComponent object.
112 * @param name Name of the sensor in order to write on .dbt and .utc files and to recognize every sensors used.
113 * @param ip The IP address of the remote Sick LDMRS sensor.
114 * @param port The port of the remote Sick LDMRS sensor.
115 * @param recording If \c true, data is recorded into dbt + utc files. Data is not recorded otherwise.
116 */
117 SickLDMRSSensor(QObject *parent, QString name, QString ip, int port, int recording);
118
119 /// Destructor
120 ~SickLDMRSSensor();
121
122 void run() {}
123
124 void stopActivity(); /*!< To stop the processing thread */
125 void startActivity(); /*!< To start the processing thread */
126
127 /**
128 * @brief splitPacket reconstitute incoming data and find messages.
129 * @param packet Raw data coming from the sensor.
130 * @param length Length of the data.
131 * @param time Time of the last received data.
132 *
133 * Analyse the ethernet packet received from the Sick sensor and try to find a
134 * complete message (scan data message or object message)
135 * If a message has been found it is added at the end of the message list
136 * else the pending bytes are stored to be analyzed by further incoming data.
137 */
138 void splitPacket(const char * packet, const int length, road_time_t time);
139
140
141 /**
142 * @brief Process/decode a message.
143 * @param msg The message is encapsulated into a MessageLDMRS
144 * @return Type of the message
145 *
146 * Process the raw data of the message and update the MessageLDMRS object passed : it fills the 2 headers (message and scan)
147 * and replace the body field of the MessageLDRMS object by an array of ScanPoint.
148 * - @b Warning : the process of object data type is not implemented yet !
149 */
150 unsigned long processMessage(MessageLDMRS & msg);
151
152 //! Find the position of the magic word into the array and returns this index.
153 /*!
154 * \param message Array of characters, raw data received from sensor.
155 * \param length Length of the array.
156 * \return
157 * - @b -1 if no magic word is found
158 * - @b position of the magic word otherwise
159 */
160 u_int32_t findMagicWord(const char * message, const unsigned length);
161
162 /**
163 * @brief getMessageSize get the message size of the entire message.
164 * @param message Raw data of the message.
165 * @param length Length of the raw data received.
166 * @param magicWordIndex First element of the message, used to get the size of the message.
167 * @return The @b size of the whole message.
168 *
169 * The size of the message is found inside the message thanks to an offset after the index of the Magic Word.
170 * - The first header of the message that contains the size of the message is in \b Big \b Endian format !
171 *
172 */
173 u_int32_t getMessageSize(const char * message, const unsigned length, const long magicWordIndex);
174
175 /**
176 * @brief isMessageComplete compare the size of the message read into the message and the length of the received data.
177 * @param length Length of the received data.
178 * @param size Size of the message read. See getMessageSize.
179 * @return @b true if the message is complete, @b false otherwise
180 */
181 bool isMessageComplete(const unsigned length, const long size);
182
183public Q_SLOTS:
184 /**
185 * @brief customEvent allows to receive the incoming data and store them into known structures.
186 * @param e Event that carries the Ethernet packets and receiving time.
187 */
188 void customEvent(QEvent * e);
189
190 /**
191 * @brief Configure the object, not used for the moment.
192 */
193 void configure();
194
195public:
196 /**
197 * @brief S_socket, used to receive and send data to the remote sensor.
198 */
199 SickSocket * S_socket;
200
201private:
202 /// Name is used to recognize between several sensors and store data into .dbt and utc files.
203 QString name_;
204
205 /// The IP address of the remote Sick LDMRS sensor we are connected to.
206 QString ipaddr_;
207
208 /// The SickLDMRS port
209 int port_;
210
211 /// Enable storing in DBT + UTC files
212 bool recording_;
213
214 /// List of messages to process.
215 std::list<MessageLDMRS> msgList;
216
217 /// Received raw data is appended into this MessagePacket.
218 MessagePacket pendingBytes;
219
220 /// Append new data into the private MessagePacket @b pendingBytes.
221 void storePendingBytes(road_time_t time);
222
223 /**
224 * @brief fillDataHeader fills the message header of the message
225 * @param msg
226 * - @b Warning:
227 * - the body field of the message have to be completed before
228 * - Data header format is @b Big @b Endian
229 */
230 void fillDataHeader(MessageLDMRS& msg);
231
232
233 /**
234 * @brief fillScanHeader fill the scan header of the message
235 * @param msg Raw data must be stored into the body field of the message
236 * - @b Warning
237 * - the body field of the message have to be completed before
238 * - Scan header format is @b Little @b Endian
239 */
240 void fillScanHeader(MessageLDMRS& msg);
241
242 /**
243 * @brief Write data into .dbt + .utc files.
244 * @param msg
245 *
246 * SickLDMRS_dbt structure is filled and stored into the DBT file.
247 * The array of ScanPoint is then stored into the UTC file.
248 */
249 void writeData(MessageLDMRS &msg);
250
251 std::string kSickDbtFileName; //!< Name of the DBT file.
252 std::string kSickUtcFileName; //!< Name of the UTC file.
253
254 pacpus::DbiteFile dbtFile_; //!< DBT file.
255 std::ofstream dataFile_; //!< UTC file.
256
257
258#ifdef SICKLDMRS_SH_MEM
259 ShMem * shmem_;
260 SickLDMRS_shMem sickData;
261#endif
262
263};
264
265} // namespace pacpus
266
267#endif // SICKLDMRSSENSOR_H
Note: See TracBrowser for help on using the repository browser.