MRPT  1.9.9
CRaePID.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "hwdrivers-precomp.h" // Precompiled headers
11 
12 #include <mrpt/hwdrivers/CRaePID.h>
13 #include <mrpt/system/datetime.h>
14 
15 #include <iostream>
16 #include <iterator>
17 #include <memory>
18 #include <sstream>
19 #include <thread>
20 
21 using namespace std;
22 using namespace mrpt::hwdrivers;
23 
25 
26 /* -----------------------------------------------------
27  Constructor
28  ----------------------------------------------------- */
29 CRaePID::CRaePID() { m_sensorLabel = "RAE_PID"; }
30 /* -----------------------------------------------------
31  loadConfig_sensorSpecific
32  ----------------------------------------------------- */
33 void CRaePID::loadConfig_sensorSpecific(
34  const mrpt::config::CConfigFileBase& configSource,
35  const std::string& iniSection)
36 {
37 #ifdef _WIN32
38  com_port =
39  configSource.read_string(iniSection, "COM_port_PID", "COM1", true);
40 #else
41  com_port =
42  configSource.read_string(iniSection, "COM_port_PID", "/dev/tty0", true);
43 #endif
44 
45  com_bauds = configSource.read_int(iniSection, "baudRate", 9600, false);
46 
47  pose_x = configSource.read_float(iniSection, "pose_x", 0, true);
48  pose_y = configSource.read_float(iniSection, "pose_y", 0, true);
49  pose_z = configSource.read_float(iniSection, "pose_z", 0, true);
50  pose_roll = configSource.read_float(iniSection, "pose_roll", 0, true);
51  pose_pitch = configSource.read_float(iniSection, "pose_pitch", 0, true);
52  pose_yaw = configSource.read_float(iniSection, "pose_yaw", 0, true);
53 }
54 
55 /* -----------------------------------------------------
56  tryToOpenTheCOM
57 ----------------------------------------------------- */
58 bool CRaePID::tryToOpenTheCOM()
59 {
60  if (COM.isOpen()) return true; // Already open
61 
62  if (m_verbose)
63  cout << "[CRaePID] Opening " << com_port << " @ " << com_bauds << endl;
64 
65  try
66  {
67  COM.open(com_port);
68  // Config:
69  COM.setConfig(com_bauds, 0, 8, 1);
70  // COM.setTimeouts( 1, 0, 1, 1, 1 );
71  COM.setTimeouts(50, 1, 100, 1, 20);
72  // std::this_thread::sleep_for(10ms);
73  COM.purgeBuffers();
74  // std::this_thread::sleep_for(10ms);
75 
76  return true; // All OK!
77  }
78  catch (const std::exception& e)
79  {
80  std::cerr << "[CRaePID::tryToOpenTheCOM] Error opening or configuring "
81  "the serial port:"
82  << std::endl
83  << e.what();
84  COM.close();
85  return false;
86  }
87  catch (...)
88  {
89  std::cerr << "[CRaePID::tryToOpenTheCOM] Error opening or configuring "
90  "the serial port."
91  << std::endl;
92  COM.close();
93  return false;
94  }
95 }
96 
97 /* -----------------------------------------------------
98  doProcess
99 ----------------------------------------------------- */
100 void CRaePID::doProcess()
101 {
102  // Is the COM open?
103  if (!tryToOpenTheCOM())
104  {
105  m_state = ssError;
106  THROW_EXCEPTION("Cannot open the serial port");
107  }
108 
109  bool have_reading = false;
110  std::string power_reading;
111  bool time_out = false;
112 
113  while (!have_reading)
114  {
115  // Send command to PID to request a measurement
116  COM.purgeBuffers();
117  COM.Write("R", 1);
118 
119  // Read PID response
120  power_reading = COM.ReadString(500, &time_out);
121  if (time_out)
122  {
123  // cout << "[CRaePID] " << com_port << " @ " <<com_bauds << " -
124  // measurement Timed-Out" << endl;
125  std::this_thread::sleep_for(10ms);
126  }
127  else
128  have_reading = true;
129  }
130 
131  // cout << "[CRaePID] " << com_port << " @ " <<com_bauds << " - measurement
132  // -> " << power_reading << endl;
133 
134  // Convert the text to a number (ppm)
135  const float readnum = atof(power_reading.c_str());
136  const float val_ppm = readnum / 1000;
137 
138  // Fill the observation
140  obs.readingsVoltage.push_back(val_ppm);
141  obs.sensorTypes.push_back(0x0001);
142 
144  obsG.sensorLabel = this->getSensorLabel();
145  obsG.m_readings.push_back(obs);
146  obsG.timestamp = mrpt::system::now();
147 
148  appendObservation(mrpt::obs::CObservationGasSensors::Create(obsG));
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 (auto& k : measurements_text)
238  {
239  const float readnum = atof(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 }
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:67
This class implements a driver for the RAE Systems gas PhotoIonization Detector (PID) (Tested on a Mi...
Definition: CRaePID.h:28
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:86
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...
#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 ...
static Ptr Create(Args &&... args)



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: c7a3bec24 Sun Mar 29 18:33:13 2020 +0200 at dom mar 29 18:50:38 CEST 2020