MRPT  1.9.9
CRaePID.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "hwdrivers-precomp.h" // Precompiled headers
11 #include <mrpt/hwdrivers/CRaePID.h>
12 #include <mrpt/system/datetime.h>
13 
14 #include <iostream>
15 #include <iterator>
16 #include <sstream>
17 #include <thread>
18 
19 using namespace std;
20 using namespace mrpt::hwdrivers;
21 
23 
24 /* -----------------------------------------------------
25  Constructor
26  ----------------------------------------------------- */
27 CRaePID::CRaePID() { m_sensorLabel = "RAE_PID"; }
28 /* -----------------------------------------------------
29  loadConfig_sensorSpecific
30  ----------------------------------------------------- */
31 void CRaePID::loadConfig_sensorSpecific(
32  const mrpt::config::CConfigFileBase& configSource,
33  const std::string& iniSection)
34 {
35 #ifdef _WIN32
36  com_port =
37  configSource.read_string(iniSection, "COM_port_PID", "COM1", true);
38 #else
39  com_port =
40  configSource.read_string(iniSection, "COM_port_PID", "/dev/tty0", true);
41 #endif
42 
43  com_bauds = configSource.read_int(iniSection, "baudRate", 9600, false);
44 
45  pose_x = configSource.read_float(iniSection, "pose_x", 0, true);
46  pose_y = configSource.read_float(iniSection, "pose_y", 0, true);
47  pose_z = configSource.read_float(iniSection, "pose_z", 0, true);
48  pose_roll = configSource.read_float(iniSection, "pose_roll", 0, true);
49  pose_pitch = configSource.read_float(iniSection, "pose_pitch", 0, true);
50  pose_yaw = configSource.read_float(iniSection, "pose_yaw", 0, true);
51 }
52 
53 /* -----------------------------------------------------
54  tryToOpenTheCOM
55 ----------------------------------------------------- */
56 bool CRaePID::tryToOpenTheCOM()
57 {
58  if (COM.isOpen()) return true; // Already open
59 
60  if (m_verbose)
61  cout << "[CRaePID] Opening " << com_port << " @ " << com_bauds << endl;
62 
63  try
64  {
65  COM.open(com_port);
66  // Config:
67  COM.setConfig(com_bauds, 0, 8, 1);
68  // COM.setTimeouts( 1, 0, 1, 1, 1 );
69  COM.setTimeouts(50, 1, 100, 1, 20);
70  // std::this_thread::sleep_for(10ms);
71  COM.purgeBuffers();
72  // std::this_thread::sleep_for(10ms);
73 
74  return true; // All OK!
75  }
76  catch (std::exception& e)
77  {
78  std::cerr << "[CRaePID::tryToOpenTheCOM] Error opening or configuring "
79  "the serial port:"
80  << std::endl
81  << e.what();
82  COM.close();
83  return false;
84  }
85  catch (...)
86  {
87  std::cerr << "[CRaePID::tryToOpenTheCOM] Error opening or configuring "
88  "the serial port."
89  << std::endl;
90  COM.close();
91  return false;
92  }
93 }
94 
95 /* -----------------------------------------------------
96  doProcess
97 ----------------------------------------------------- */
98 void CRaePID::doProcess()
99 {
100  // Is the COM open?
101  if (!tryToOpenTheCOM())
102  {
103  m_state = ssError;
104  THROW_EXCEPTION("Cannot open the serial port");
105  }
106 
107  bool have_reading = false;
108  std::string power_reading;
109  bool time_out = false;
110 
111  while (!have_reading)
112  {
113  // Send command to PID to request a measurement
114  COM.purgeBuffers();
115  COM.Write("R", 1);
116 
117  // Read PID response
118  power_reading = COM.ReadString(500, &time_out);
119  if (time_out)
120  {
121  // cout << "[CRaePID] " << com_port << " @ " <<com_bauds << " -
122  // measurement Timed-Out" << endl;
123  std::this_thread::sleep_for(10ms);
124  }
125  else
126  have_reading = true;
127  }
128 
129  // cout << "[CRaePID] " << com_port << " @ " <<com_bauds << " - measurement
130  // -> " << power_reading << endl;
131 
132  // Convert the text to a number (ppm)
133  const float readnum = atof(power_reading.c_str());
134  const float val_ppm = readnum / 1000;
135 
136  // Fill the observation
138  obs.readingsVoltage.push_back(val_ppm);
139  obs.sensorTypes.push_back(0x0001);
140 
142  obsG.sensorLabel = this->getSensorLabel();
143  obsG.m_readings.push_back(obs);
144  obsG.timestamp = mrpt::system::now();
145 
146  appendObservation(
149 }
150 
151 std::string CRaePID::getFirmware()
152 {
153  // Send the command
154  cout << "Firmware version: " << endl;
155  COM.purgeBuffers();
156  size_t B_written = COM.Write("F", 1);
157  if (!B_written) return std::string("COMMS.ERROR");
158 
159  // Read the returned text
160  bool time_out = false;
161  std::string s_read = COM.ReadString(2000, &time_out);
162  if (time_out) s_read = "Time_out";
163  return s_read;
164 }
165 
166 std::string CRaePID::getModel()
167 {
168  // Send the command
169  COM.purgeBuffers();
170  COM.Write("M", 1);
171 
172  // Read the returned text
173  return COM.ReadString();
174 }
175 
176 std::string CRaePID::getSerialNumber()
177 {
178  // Send the command
179  COM.purgeBuffers();
180  COM.Write("S", 1);
181 
182  // Read the returned text
183  return COM.ReadString();
184 }
185 
186 std::string CRaePID::getName()
187 {
188  // Send the command
189  COM.purgeBuffers();
190  COM.Write("N", 1);
191 
192  // Read the returned text
193  return COM.ReadString();
194 }
195 
196 bool CRaePID::switchPower()
197 {
198  // Send the command
199  COM.purgeBuffers();
200  COM.Write("P", 1);
201 
202  // Read the returned text
203  std::string reading;
204  reading = COM.ReadString();
205 
206  if (strcmp(reading.c_str(), "Sleep...") == 0)
207  return true;
208  else
209  return false;
210 }
211 
212 mrpt::obs::CObservationGasSensors CRaePID::getFullInfo()
213 {
214  // Send the command
215  COM.purgeBuffers();
216  COM.Write("C", 1);
217 
218  // Read the returned text
219  std::string reading;
220  reading = COM.ReadString();
221 
222  // Iterate over each information component (tokenize first)
223  // construct a stream from the string (as seen in
224  // http://stackoverflow.com/a/53921)
225  std::stringstream readings_str(reading);
226 
227  // use stream iterators to copy the stream to the vector as whitespace
228  // separated strings
229  std::istream_iterator<std::string> it(readings_str);
230  std::istream_iterator<std::string> endit;
231  std::vector<std::string> measurements_text(it, endit);
232 
233  // Convert the text to a number (ppm)
236 
237  for (size_t k = 0; k < measurements_text.size(); k++)
238  {
239  const float readnum = atof(measurements_text[k].c_str());
240  const float val_ppm = readnum / 1000.f;
241 
242  // Fill the observation
243  obs.readingsVoltage.push_back(val_ppm);
244  obsG.m_readings.push_back(obs);
245  }
246 
247  obsG.sensorLabel = this->getSensorLabel();
248  obsG.timestamp = mrpt::system::now();
249 
250  return obsG;
251 }
252 
253 bool CRaePID::errorStatus(std::string& errorString)
254 {
255  // Send the command
256  COM.purgeBuffers();
257  COM.Write("E", 1);
258 
259  // Read the returned text
260  std::string reading;
261  reading = COM.ReadString();
262 
263  // Tokenize to separate the two components:
264  // construct a stream from the string (as seen in
265  // http://stackoverflow.com/a/53921)
266  std::stringstream readings_str(reading);
267 
268  // use stream iterators to copy the stream to the vector as whitespace
269  // separated strings
270  std::istream_iterator<std::string> it(readings_str);
271  std::istream_iterator<std::string> endit;
272  std::vector<std::string> errors_text(it, endit);
273 
274  // Take the first part and check the possible error condition
275  if ((strcmp(errors_text[0].c_str(), "0") == 0) &&
276  (strcmp(errors_text[1].c_str(), "0") == 0)) // no error
277  {
278  return false;
279  }
280  else
281  {
282  // By the moment, return the raw error; note that if necessary a
283  // detailed description of the error can be obtained analyzing the two
284  // error strings separately
285  errorString = reading;
286  return true;
287  }
288 }
289 
290 void CRaePID::getLimits(float& min, float& max)
291 {
292  // Send the command
293  COM.purgeBuffers();
294  COM.Write("L", 1);
295 
296  // Read the returned text
297  std::string reading;
298  reading = COM.ReadString();
299 
300  // Tokenize to separate the two components:
301  // construct a stream from the string (as seen in
302  // http://stackoverflow.com/a/53921)
303  std::stringstream readings_str(reading);
304 
305  // use stream iterators to copy the stream to the vector as whitespace
306  // separated strings
307  std::istream_iterator<std::string> it(readings_str);
308  std::istream_iterator<std::string> endit;
309  std::vector<std::string> readings_text(it, endit);
310 
311  // read min and max
312  max = atof(readings_text[0].c_str());
313  min = atof(readings_text[1].c_str());
314 }
#define min(a, b)
std::string read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:41
This class implements a driver for the RAE Systems gas PhotoIonization Detector (PID) (Tested on a Mi...
Definition: CRaePID.h:29
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:87
Contains classes for various device interfaces.
float read_float(const std::string &section, const std::string &name, float defaultValue, bool failIfNotFound=false) const
STL namespace.
int read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound=false) const
This class allows loading and storing values and vectors of different types from a configuration text...
std::vector< int > sensorTypes
The kind of sensors in the array (size of "sensorTypes" is the same that the size of "readingsVoltage...
Declares a class derived from "CObservation" that represents a set of readings from gas sensors...
GLsizei const GLchar ** string
Definition: glext.h:4101
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
Definition: CObservation.h:62
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp.
Definition: CObservation.h:60
std::vector< TObservationENose > m_readings
One entry per e-nose on the robot.
std::vector< float > readingsVoltage
The set of readings (in volts) from the array of sensors (size of "sensorTypes" is the same that the ...



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020