MRPT  2.0.0
CImpinjRFID.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 
13 #include <mrpt/system/os.h>
14 
15 #include <iostream>
16 #include <thread>
17 
18 using namespace mrpt::hwdrivers;
19 using namespace mrpt::system;
20 using namespace std::literals;
21 
23 
25 {
26  m_sensorLabel = "RFID";
27  connected = false;
28 }
29 
30 CImpinjRFID::~CImpinjRFID() { closeReader(); }
32 {
33  // start the driver
34  // use a separate thread so the connection can be established while the
35  // program starts. This is essential because the module will stall on the
36  // accept() call until the driver executable requests a connection, and, on
37  // the other hand, if the module is not listening, the driver will fail
38  std::thread(dummy_startDriver, this).detach();
39  // system::createThreadFromObjectMethod<CImpinjRFID>(this,startDriver);
40 
41  // start connection
42 
43  connect();
44 }
45 
48 {
49  // start the driver
50  std::stringstream cmdline;
51  std::cout << "Waiting for the driver to start ... ";
52 
53  // create the command line (executable path + parameters)
54  cmdline << driver_path << " " << reader_name.c_str() << " " << IPm.c_str()
55  << " " << port;
56 
57  // wait until the current module starts the sockets and listens to it
58  std::this_thread::sleep_for(2s);
59 
60  const int ret = ::system(cmdline.str().c_str());
61  if (0 != ret)
62  std::cerr << "[CImpinjRFID::startDriver] Error (" << ret
63  << ") invoking command:\n"
64  << cmdline.str() << std::endl;
65 }
66 
68  const mrpt::config::CConfigFileBase& configSource,
69  const std::string& iniSection)
70 {
72  // TEMPORARILY DISABLED
73  /* pose_x_1 = configSource.read_float(iniSection,"pose_x_1",0,true);
74  pose_y_1 = configSource.read_float(iniSection,"pose_y_1",0,true);
75  pose_z_1 = configSource.read_float(iniSection,"pose_z_1",0,true);
76  pose_roll_1 =
77  configSource.read_float(iniSection,"pose_roll_1",0,true);
78  pose_pitch_1 =
79  configSource.read_float(iniSection,"pose_pitch_1",0,true);
80  pose_yaw_1 =
81  configSource.read_float(iniSection,"pose_yaw_1",0,true);
82 
83  pose_x_2 = configSource.read_float(iniSection,"pose_x_2",0,true);
84  pose_y_2 = configSource.read_float(iniSection,"pose_y_2",0,true);
85  pose_z_2 = configSource.read_float(iniSection,"pose_z_2",0,true);
86  pose_roll_2 =
87  configSource.read_float(iniSection,"pose_roll_2",0,true);
88  pose_pitch_2 =
89  configSource.read_float(iniSection,"pose_pitch_2",0,true);
90  pose_yaw_2 =
91  configSource.read_float(iniSection,"pose_yaw_2",0,true);
92  */
93  IPm = configSource.read_string(iniSection, "local_IP", "127.0.0.1", false);
94  reader_name = configSource.read_string(iniSection, "reader_name", "", true);
95  port = configSource.read_int(iniSection, "listen_port", 0, true);
96  driver_path = configSource.read_string(iniSection, "driver_path", "", true);
97 
98  MRPT_END
99 }
100 
101 /*---------------------------------------------------------------
102  getObservation
103  Get the power of a given network as an observation
104  ---------------------------------------------------------------*/
106 {
107  if (!connected)
108  {
109  // Start the server
110  server = std::make_unique<mrpt::comms::CServerTCPSocket>(port);
111  }
112 
113  client = server->accept();
114 
115  std::this_thread::sleep_for(1s);
116  connected = true;
117 }
118 
119 /*---------------------------------------------------------------
120  getObservation
121  Get the power of a given network as an observation
122  ---------------------------------------------------------------*/
124 {
125  try
126  {
127  bool receivedSomething = false;
128  char msg[34];
129  char cmd[20];
130  char epc[24];
131  char rx_pwr[5];
132  char* tmp;
133  obs.tag_readings.clear();
134  // send an observation command to the device interface program
135  strcpy(cmd, "OBS\0");
136  client->writeAsync(cmd, 10);
137 
138  // receive a reading from the sensor through the socket
139  while (client->readAsync(msg, 34, 100) > 0)
140  {
141  receivedSomething = true;
142  // the received string is in the format: ANT_PORT EPC RX_PWR
143  // ZERO_FILL
144  const char* ant_port_ptr = mrpt::system::strtok(msg, " ", &tmp);
145  if (!ant_port_ptr)
146  {
147  std::cerr << "[CImpinjRFID::getObservation] Unexpected format "
148  "in sensor data! (skipping).\n";
149  continue;
150  }
151  const char ant_port = *ant_port_ptr;
152  strcpy(epc, mrpt::system::strtok(nullptr, " ", &tmp));
153  strcpy(rx_pwr, mrpt::system::strtok(nullptr, " ", &tmp));
154 
155  // Fill the observation
156  obs.tag_readings.resize(
157  obs.tag_readings.size() +
158  1); // Alloc space for one more tag obs
160  *obs.tag_readings.rbegin(); // Get a reference to the latest
161  // new tag structure
162 
163  // Fill in fields in "new_tag":
164  new_tag.antennaPort = mrpt::format("%c", ant_port);
165  new_tag.epc = std::string(epc);
166  new_tag.power = atof(rx_pwr);
167  obs.sensorLabel = m_sensorLabel;
168 
169  // std::cout << "mrpt::hwdrivers::CImpinjRFID::getObservation() " <<
170  // "\n\tRXPWR: " << atof(rx_pwr) << " PWR READ: " << rx_pwr <<
171  // std::endl;
172  }
173  if (receivedSomething)
174  return true;
175  else
176  return false;
177  }
178  catch (const std::exception& e)
179  {
180  std::cerr << e.what() << std::endl;
181  return false;
182  }
183 }
184 
185 /*---------------------------------------------------------------
186  getObservation
187  Get the power of a given network as an observation
188  ---------------------------------------------------------------*/
190 {
191  char cmd[20];
192  // send a kill command to the device interface program
193  strcpy(cmd, "END\0");
194  client->writeAsync(cmd, 10); // JL->Emil: Why 10 not strlen(cmd)? Is the
195  // server expecting a fixed length data block?
196  client->close();
197 }
198 
200 {
203  if (getObservation(*obs)) appendObservation(obs);
204 }
std::string antennaPort
Port of the antenna that did the reading.
#define MRPT_START
Definition: exceptions.h:241
std::string read_string(const std::string &section, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
std::string std::string format(std::string_view fmt, ARGS &&... args)
Definition: format.h:26
This class implements an interface to an Impinj RFID reader.
Definition: CImpinjRFID.h:26
Contains classes for various device interfaces.
char * strcpy(char *dest, size_t destSize, const char *source) noexcept
An OS-independent version of strcpy.
int read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound=false) const
void loadConfig_sensorSpecific(const mrpt::config::CConfigFileBase &configSource, const std::string &section) override
Loads specific configuration for the device from a given source of configuration parameters, for example, an ".ini" file, loading from the section "[iniSection]" (see config::CConfigFileBase and derived classes)
Definition: CImpinjRFID.cpp:67
This class allows loading and storing values and vectors of different types from a configuration text...
void initialize() override
This method can or cannot be implemented in the derived class, depending on the need for it...
Definition: CImpinjRFID.cpp:31
std::string epc
EPC code of the observed tag.
char * strtok(char *str, const char *strDelimit, char **context) noexcept
An OS-independent method for tokenizing a string.
void startDriver()
start the external driver
Definition: CImpinjRFID.cpp:47
double power
The power or signal strength as sensed by the RFID receiver (in dBm)
static Ptr Create(Args &&... args)
#define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace)
This must be inserted in all CGenericSensor classes implementation files:
static void dummy_startDriver(CImpinjRFID *o)
Definition: CImpinjRFID.cpp:46
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
Definition: CObservation.h:62
void connect()
Connect to the reader.
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...
Definition: obs_utils.h:31
bool getObservation(mrpt::obs::CObservationRFID &obs)
Gets the information of the tags as a timestamped observation NOTE: Deprecated, use getObservations i...
#define MRPT_END
Definition: exceptions.h:245
std::vector< TTagReading > tag_readings
The vector of individual tag observations.
Each of the individual readings of a RFID tag.
void doProcess() override
This method will be invoked at a minimum rate of "process_rate" (Hz)
This represents one or more RFID tags observed by a receiver.
void closeReader()
Close the connection to the reader.



Page generated by Doxygen 1.8.14 for MRPT 2.0.0 Git: b38439d21 Tue Mar 31 19:58:06 2020 +0200 at miƩ abr 1 00:50:30 CEST 2020