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);
50 #ifdef MRPT_OS_WINDOWS 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)
100 CStream* comms = checkConnectionAndConnect();
101 if (!comms)
return false;
117 m_stream_SERIAL.reset();
118 m_stream_FTDI.reset();
126 CStream* CBoardENoses::checkConnectionAndConnect()
129 if (!m_stream_FTDI && !m_stream_SERIAL)
131 if (!m_COM_port.empty())
139 if (m_stream_FTDI->isOpen())
return m_stream_FTDI.get();
142 m_stream_FTDI->OpenBySerialNumber(m_usbSerialNumber);
143 std::this_thread::sleep_for(10ms);
144 m_stream_FTDI->Purge();
145 std::this_thread::sleep_for(10ms);
146 m_stream_FTDI->SetLatencyTimer(1);
147 m_stream_FTDI->SetTimeouts(10, 100);
148 return m_stream_FTDI.get();
152 m_stream_FTDI->Close();
159 if (m_stream_SERIAL->isOpen())
return m_stream_SERIAL.get();
162 m_stream_SERIAL->open(m_COM_port);
163 m_stream_SERIAL->setConfig(m_COM_baud);
164 std::this_thread::sleep_for(10ms);
165 m_stream_SERIAL->purgeBuffers();
166 std::this_thread::sleep_for(10ms);
168 m_stream_SERIAL->setTimeouts(50, 1, 100, 1, 20);
169 return m_stream_SERIAL.get();
173 m_stream_SERIAL->close();
187 CStream* comms = checkConnectionAndConnect();
189 if (!comms)
return false;
219 vector<uint16_t> readings(
232 size_t NumberOfChambers = (size_t)readings[0];
233 size_t ActiveChamber = (size_t)readings[1];
236 ASSERT_(((readings.size() - 4) % NumberOfChambers) == 0);
237 size_t wordsPereNose = (readings.size() - 4) / NumberOfChambers;
240 for (
size_t i = 0; i < NumberOfChambers; i++)
248 if (i < enose_poses_x.size())
251 enose_poses_x[i], enose_poses_y[i], enose_poses_z[i],
252 enose_poses_yaw[i], enose_poses_pitch[i],
253 enose_poses_roll[i]);
265 if (i == (ActiveChamber)) newRead.
isActive =
true;
268 for (
size_t idx = 0; idx < wordsPereNose / 2; idx++)
270 if (readings[i * wordsPereNose + 2 * idx + 2] !=
274 if (readings[i * wordsPereNose + 2 * idx + 2] == 0xFFFF)
278 ((
int16_t)readings[i * wordsPereNose + 2 * idx +
286 readings[i * wordsPereNose + 2 * idx + 2]);
291 (readings[i * wordsPereNose + 2 * idx + 3] *
308 (
uint16_t*)&readings[readings.size() - 2];
319 first_reading =
false;
332 for (
size_t ch = 0; ch < obs.
m_readings.size(); ch++)
334 if ((obs.
m_readings[ch].sensorTypes.size() != 7) ||
335 (obs.
m_readings[ch].readingsVoltage.size() != 7))
343 if (!correct) printf(
"Error en la observacion");
349 cerr <<
"[CBoardENoses::getObservation] Returning false due to " 352 cerr << e.what() << endl;
369 void CBoardENoses::doProcess()
372 mrpt::make_aligned_shared<CObservationGasSensors>();
377 appendObservation(obs);
394 void CBoardENoses::initialize()
409 bool CBoardENoses::setActiveChamber(
unsigned char chamber)
414 CStream* comms = checkConnectionAndConnect();
415 if (!comms)
return false;
419 unsigned char buf[1];
420 buf[0] = ((chamber & 15) << 2) | 130;
428 m_stream_SERIAL.reset();
429 m_stream_FTDI.reset();
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
unsigned __int16 uint16_t
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)
void WriteBuffer(const void *Buffer, size_t Count)
Writes a block of bytes to the stream from Buffer.
Contains classes for various device interfaces.
vector_int sensorTypes
The kind of sensors in the array (size of "sensorTypes" is the same that the size of "readingsVoltage...
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
The structure for each e-nose.
This class allows loading and storing values and vectors of different types from a configuration text...
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
This base provides a set of functions for maths stuff.
std::shared_ptr< CObservationGasSensors > Ptr
math::TPose3D eNosePoseOnTheRobot
The pose of the sensors on the robot.
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 ...
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.
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.
void getContentAsString(std::string &str)
Gets the contents of the message as a string.
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp.
bool receiveMessage(utils::CMessage &msg)
Tries to receive a message from the device.
A definition of a CStream actually representing a USB connection to a FTDI chip.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
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...
uint64_t read_uint64_t(const std::string §ion, const std::string &name, uint64_t defaultValue, bool failIfNotFound=false) const
void sendMessage(const utils::CMessage &msg)
Send a message to the device.
std::vector< uint8_t > content
The contents of the message (memory is automatically handled by the std::vector object) ...
mrpt::system::TTimeStamp secondsToTimestamp(const double nSeconds)
Transform a time interval (in seconds) into TTimeStamp (e.g.
std::vector< float > readingsVoltage
The set of readings (in volts) from the array of sensors (size of "sensorTypes" is the same that the ...
A class that contain generic messages, that can be sent and received from a "CClientTCPSocket" object...
uint32_t type
An identifier of the message type (only the least-sig byte is typically sent)
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".