32 : m_usbSerialNumber("ENOSE001"), m_COM_port(), m_COM_baud(115200)
34 m_sensorLabel =
"ENOSE";
41 void CBoardENoses::loadConfig_sensorSpecific(
48 configSource.
read_string(iniSection,
"USB_serialname",
"",
false);
52 configSource.
read_string(iniSection,
"COM_port_WIN", m_COM_port);
55 configSource.
read_string(iniSection,
"COM_port_LIN", m_COM_port);
58 configSource.
read_uint64_t(iniSection,
"COM_baudRate", m_COM_baud);
61 iniSection,
"enose_poses_x", vector<float>(0), enose_poses_x,
true);
63 iniSection,
"enose_poses_y", vector<float>(0), enose_poses_y,
true);
65 iniSection,
"enose_poses_z", vector<float>(0), enose_poses_z,
true);
68 iniSection,
"enose_poses_yaw", vector<float>(0), enose_poses_yaw,
true);
70 iniSection,
"enose_poses_pitch", vector<float>(0), enose_poses_pitch,
73 iniSection,
"enose_poses_roll", vector<float>(0), enose_poses_roll,
76 ASSERT_(enose_poses_x.size() == enose_poses_y.size());
77 ASSERT_(enose_poses_x.size() == enose_poses_z.size());
78 ASSERT_(enose_poses_x.size() == enose_poses_yaw.size());
79 ASSERT_(enose_poses_x.size() == enose_poses_pitch.size());
80 ASSERT_(enose_poses_x.size() == enose_poses_roll.size());
83 enose_poses_yaw *=
M_PIf / 180.0f;
84 enose_poses_pitch *=
M_PIf / 180.0f;
85 enose_poses_roll *=
M_PIf / 180.0f;
93 bool CBoardENoses::queryFirmwareVersion(
string& out_firmwareVersion)
101 if (!
comms)
return false;
105 arch.sendMessage(msg);
107 if (arch.receiveMessage(msgRx))
118 m_stream_SERIAL.reset();
119 m_stream_FTDI.reset();
127 CStream* CBoardENoses::checkConnectionAndConnect()
130 if (!m_stream_FTDI && !m_stream_SERIAL)
132 if (!m_COM_port.empty())
140 if (m_stream_FTDI->isOpen())
return m_stream_FTDI.get();
143 m_stream_FTDI->OpenBySerialNumber(m_usbSerialNumber);
144 std::this_thread::sleep_for(10ms);
145 m_stream_FTDI->Purge();
146 std::this_thread::sleep_for(10ms);
147 m_stream_FTDI->SetLatencyTimer(1);
148 m_stream_FTDI->SetTimeouts(10, 100);
149 return m_stream_FTDI.get();
153 m_stream_FTDI->Close();
160 if (m_stream_SERIAL->isOpen())
return m_stream_SERIAL.get();
163 m_stream_SERIAL->open(m_COM_port);
164 m_stream_SERIAL->setConfig(m_COM_baud);
165 std::this_thread::sleep_for(10ms);
166 m_stream_SERIAL->purgeBuffers();
167 std::this_thread::sleep_for(10ms);
169 m_stream_SERIAL->setTimeouts(50, 1, 100, 1, 20);
170 return m_stream_SERIAL.get();
174 m_stream_SERIAL->close();
190 if (!
comms)
return false;
211 if (!arch.receiveMessage(msg))
221 vector<uint16_t> readings(
234 size_t NumberOfChambers = (size_t)readings[0];
235 size_t ActiveChamber = (size_t)readings[1];
238 ASSERT_(((readings.size() - 4) % NumberOfChambers) == 0);
239 size_t wordsPereNose = (readings.size() - 4) / NumberOfChambers;
242 for (
size_t i = 0; i < NumberOfChambers; i++)
250 if (i < enose_poses_x.size())
253 enose_poses_x[i], enose_poses_y[i], enose_poses_z[i],
254 enose_poses_yaw[i], enose_poses_pitch[i],
255 enose_poses_roll[i]);
267 if (i == (ActiveChamber)) newRead.
isActive =
true;
270 for (
size_t idx = 0; idx < wordsPereNose / 2; idx++)
272 if (readings[i * wordsPereNose + 2 * idx + 2] !=
276 if (readings[i * wordsPereNose + 2 * idx + 2] == 0xFFFF)
281 [i * wordsPereNose + 2 * idx + 3]) /
288 readings[i * wordsPereNose + 2 * idx + 2]);
293 (readings[i * wordsPereNose + 2 * idx + 3] *
310 (
uint16_t*)&readings[readings.size() - 2];
321 first_reading =
false;
334 for (
size_t ch = 0; ch < obs.
m_readings.size(); ch++)
336 if ((obs.
m_readings[ch].sensorTypes.size() != 7) ||
337 (obs.
m_readings[ch].readingsVoltage.size() != 7))
345 if (!correct) printf(
"Error en la observacion");
351 cerr <<
"[CBoardENoses::getObservation] Returning false due to " 354 cerr << e.what() << endl;
371 void CBoardENoses::doProcess()
374 mrpt::make_aligned_shared<CObservationGasSensors>();
379 appendObservation(obs);
396 void CBoardENoses::initialize()
411 bool CBoardENoses::setActiveChamber(
unsigned char chamber)
417 if (!
comms)
return false;
421 unsigned char buf[1];
422 buf[0] = ((chamber & 15) << 2) | 130;
424 comms->Write(buf, 1);
430 m_stream_SERIAL.reset();
431 m_stream_FTDI.reset();
unsigned __int16 uint16_t
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
A communications serial port built as an implementation of a utils::CStream.
mrpt::system::TTimeStamp getCurrentTime()
Returns the current (UTC) system time.
float temperature
Sensed temperature in Celcius (valid if hasTemperature=true only)
uint32_t type
An identifier of the message type (only the least-sig byte is typically sent)
Contains classes for various device interfaces.
The structure for each e-nose.
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
CArchiveStreamBase< STREAM > archiveFrom(STREAM &s)
Helper function to create a templatized wrapper CArchive object for a: MRPT's CStream, std::istream, std::ostream, std::stringstream
#define ASSERT_(f)
Defines an assertion mechanism.
This class allows loading and storing values and vectors of different types from a configuration text...
This base provides a set of functions for maths stuff.
math::TPose3D eNosePoseOnTheRobot
The pose of the sensors on the robot.
std::vector< int > sensorTypes
The kind of sensors in the array (size of "sensorTypes" is the same that the size of "readingsVoltage...
A class for interfacing an e-Noses via a FTDI USB link.
bool hasTemperature
Must be true for "temperature" to contain a valid measurement.
This namespace contains representation of robot actions and observations.
uint64_t read_uint64_t(const std::string §ion, const std::string &name, uint64_t defaultValue, bool failIfNotFound=false) const
Declares a class derived from "CObservation" that represents a set of readings from gas sensors...
GLsizei const GLchar ** string
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
bool isActive
True if the input to this chamber/enose is poluted air, False if clean air.
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp.
A class that contain generic messages, that can be sent and received from a "CClientTCPSocket" object...
void getContentAsString(std::string &str)
Gets the contents of the message as a string.
A definition of a CStream actually representing a USB connection to a FTDI chip.
std::vector< TObservationENose > m_readings
One entry per e-nose on the robot.
OBSERVATION_T::Ptr getObservation(mrpt::obs::CSensoryFrame::Ptr &observations, mrpt::obs::CObservation::Ptr &observation, bool priority_to_sf=true)
Given an mrpt::obs::CSensoryFrame and a mrpt::obs::CObservation pointer if a OBSERVATION_T type obser...
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
std::vector< uint8_t > content
The contents of the message (memory is automatically handled by the std::vector object) ...
std::vector< float > readingsVoltage
The set of readings (in volts) from the array of sensors (size of "sensorTypes" is the same that the ...
mrpt::system::TTimeStamp time_tToTimestamp(const double t)
Transform from standard "time_t" (actually a double number, it can contain fractions of seconds) to T...
void read_vector(const std::string §ion, const std::string &name, const VECTOR_TYPE &defaultValue, VECTOR_TYPE &outValues, bool failIfNotFound=false) const
Reads a configuration parameter of type vector, stored in the file as a string: "[v1 v2 v3 ...
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".