YARP
Yet Another Robot Platform
AnalogSensorClient.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #include "AnalogSensorClient.h"
11 #include <yarp/os/Log.h>
12 #include <yarp/os/LogComponent.h>
13 #include <yarp/os/LogStream.h>
14 #include <yarp/os/Value.h>
15 
18 using namespace yarp::dev;
19 using namespace yarp::os;
20 using namespace yarp::sig;
21 
22 namespace
23 {
24 YARP_LOG_COMPONENT(ANALOGSENSORCLIENT, "yarp.device.analogsensorclient")
25 
26 inline int checkResponse(bool ok, const yarp::os::Bottle& response)
27 {
28  const yarp::os::Value & v = response.get(0);
29  return ok && v.isInt32() ? v.asInt32() : IAnalogSensor::AS_ERROR;
30 }
31 
32 } // namespace
33 
35 {
36  mutex.lock();
37  count=0;
38  deltaT=0;
39  deltaTMax=0;
40  deltaTMin=1e22;
41  now=Time::now();
42  prev=now;
43  mutex.unlock();
44 }
45 
47 {
49  resetStat();
50 }
51 
53 {
54  now=Time::now();
55  mutex.lock();
56 
57  if (count>0)
58  {
59  double tmpDT=now-prev;
60  deltaT+=tmpDT;
61  if (tmpDT>deltaTMax)
62  deltaTMax=tmpDT;
63  if (tmpDT<deltaTMin)
64  deltaTMin=tmpDT;
65 
66  //compare network time
67  if (tmpDT*1000<ANALOG_TIMEOUT)
68  {
70  }
71  else
72  {
74  }
75  }
76 
77  prev=now;
78  count++;
79 
80  lastVector=v;
81  Stamp newStamp;
82  getEnvelope(newStamp);
83 
84  //initialialization (first received data)
85  if (lastStamp.isValid()==false)
86  {
87  lastStamp = newStamp;
88  }
89 
90  //now compare timestamps
91  if ((1000*(newStamp.getTime()-lastStamp.getTime()))<ANALOG_TIMEOUT)
92  {
94  }
95  else
96  {
98  }
99  lastStamp = newStamp;
100 
101  mutex.unlock();
102 }
103 
105 {
106  mutex.lock();
107  int ret=state;
109  {
110  data=lastVector;
111  stmp = lastStamp;
112  }
113  mutex.unlock();
114 
115  return ret;
116 }
117 
119 {
120  mutex.lock();
121  int ret=count;
122  mutex.unlock();
123  return ret;
124 }
125 
126 // time is in ms
127 void InputPortProcessor::getEstFrequency(int &ite, double &av, double &min, double &max)
128 {
129  mutex.lock();
130  ite=count;
131  min=deltaTMin*1000;
132  max=deltaTMax*1000;
133  if (count<1)
134  {
135  av=0;
136  }
137  else
138  {
139  av=deltaT/count;
140  }
141  av=av*1000;
142  mutex.unlock();
143 }
144 
146 {
147  return state;
148 }
149 
151 {
152  if (state==IAnalogSensor::AS_ERROR)
153  {
154  return 0;
155  }
156  else
157  {
158  return (int)lastVector.size();
159  }
160 }
161 
163 {
164  bool done = false;
165  while(!done)
166  {
167  std::size_t found = name.find('/');
168  // if no '/' found, I'm done
169  if (found == std::string::npos)
170  {
171  done = true;
172  continue;
173  }
174 
175  yCDebug(ANALOGSENSORCLIENT) << "found is " << found << "; length is : " << name.length();
176  // remove leading or trailing '/'
177  if( (found == 0) || (found == name.length()-1 ) /*found starts from 0, length doesn't*/ )
178  {
179  done = false; // we could have both leading and trailing, so let's check again
180  name.erase(found,1);
181  }
182  else
183  done = true; // there is some '/', but their are in the middle and they are allowed
184  }
185 
186  yCDebug(ANALOGSENSORCLIENT) << name;
187 }
188 
190 {
191  std::string carrier = config.check("carrier", Value("udp"), "default carrier for streaming robot state").asString();
192 
193  local.clear();
194  remote.clear();
195 
196  local = config.find("local").asString();
197  remote = config.find("remote").asString();
198 
199  if (local=="")
200  {
201  yCError(ANALOGSENSORCLIENT, "AnalogSensorClient::open() error you have to provide valid local name");
202  return false;
203  }
204  if (remote=="")
205  {
206  yCError(ANALOGSENSORCLIENT, "AnalogSensorClient::open() error you have to provide valid remote name\n");
207  return false;
208  }
209 
210  std::string local_rpc = local;
211  local_rpc += "/rpc:o";
212  std::string remote_rpc = remote;
213  remote_rpc += "/rpc:i";
214 
215  if (!inputPort.open(local))
216  {
217  yCError(ANALOGSENSORCLIENT, "AnalogSensorClient::open() error could not open port %s, check network", local.c_str());
218  return false;
219  }
220  inputPort.useCallback();
221 
222  if (!rpcPort.open(local_rpc))
223  {
224  yCError(ANALOGSENSORCLIENT, "AnalogSensorClient::open() error could not open rpc port %s, check network", local_rpc.c_str());
225  return false;
226  }
227 
228  bool ok=Network::connect(remote.c_str(), local.c_str(), carrier.c_str());
229  if (!ok)
230  {
231  yCError(ANALOGSENSORCLIENT, "AnalogSensorClient::open() error could not connect to %s", remote.c_str());
232  return false;
233  }
234 
235  ok=Network::connect(local_rpc, remote_rpc);
236  if (!ok)
237  {
238  yCError(ANALOGSENSORCLIENT, "AnalogSensorClient::open() error could not connect to %s\n", remote_rpc.c_str());
239  return false;
240  }
241 
242  return true;
243 }
244 
246 {
247  rpcPort.close();
248  inputPort.close();
249  return true;
250 }
251 
253 {
254  return inputPort.getLast(out, lastTs);
255 }
256 
258 {
259  //not implemented yet
260  return AS_OK;
261 }
262 
264 {
265  return inputPort.getChannels();
266 }
267 
269 {
270  Bottle cmd, response;
271  cmd.addVocab(VOCAB_IANALOG);
273  bool ok = rpcPort.write(cmd, response);
274  return checkResponse(ok, response);
275 }
276 
278 {
279  Bottle cmd, response;
280  cmd.addVocab(VOCAB_IANALOG);
282  Bottle& l = cmd.addList();
283  for (int i = 0; i < this->getChannels(); i++)
284  l.addFloat64(value[i]);
285  bool ok = rpcPort.write(cmd, response);
286  return checkResponse(ok, response);
287 }
288 
290 {
291  Bottle cmd, response;
292  cmd.addVocab(VOCAB_IANALOG);
294  cmd.addInt32(ch);
295  bool ok = rpcPort.write(cmd, response);
296  return checkResponse(ok, response);
297 }
298 
299 int AnalogSensorClient::calibrateChannel(int ch, double value)
300 {
301  Bottle cmd, response;
302  cmd.addVocab(VOCAB_IANALOG);
304  cmd.addInt32(ch);
305  cmd.addFloat64(value);
306  bool ok = rpcPort.write(cmd, response);
307  return checkResponse(ok, response);
308 }
309 
311 {
312  return lastTs;
313 }
const int ANALOG_TIMEOUT
constexpr yarp::conf::vocab32_t VOCAB_IANALOG
Definition: IAnalogSensor.h:17
constexpr yarp::conf::vocab32_t VOCAB_CALIBRATE
constexpr yarp::conf::vocab32_t VOCAB_CALIBRATE_CHANNEL
bool ret
void removeLeadingTrailingSlashesOnly(std::string &name)
yarp::os::Stamp getLastInputStamp() override
Get the time stamp for the last read data.
bool close() override
Close the DeviceDriver.
int calibrateChannel(int ch) override
Calibrates one single channel.
int calibrateSensor() override
Calibrates the whole sensor.
int read(yarp::sig::Vector &out) override
Read a vector from the sensor.
int getState(int ch) override
Check the state value of a given channel.
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
int getChannels() override
Get the number of channels of the sensor.
void onRead(yarp::sig::Vector &v) override
int getLast(yarp::sig::Vector &data, yarp::os::Stamp &stmp)
void getEstFrequency(int &ite, double &av, double &min, double &max)
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
Bottle & addList()
Places an empty nested list in the bottle, at the end of the list.
Definition: Bottle.cpp:185
void addFloat64(yarp::conf::float64_t x)
Places a 64-bit floating point number in the bottle, at the end of the list.
Definition: Bottle.cpp:161
void addVocab(int x)
Places a vocabulary item in the bottle, at the end of the list.
Definition: Bottle.cpp:167
void addInt32(std::int32_t x)
Places a 32-bit integer in the bottle, at the end of the list.
Definition: Bottle.cpp:143
A base class for nested structures that can be searched.
Definition: Searchable.h:69
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
An abstraction for a time stamp and/or sequence number.
Definition: Stamp.h:25
double getTime() const
Get the time stamp.
Definition: Stamp.cpp:37
A single value (typically within a Bottle).
Definition: Value.h:47
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:207
virtual bool isInt32() const
Checks if value is a 32-bit integer.
Definition: Value.cpp:135
virtual std::string asString() const
Get string value.
Definition: Value.cpp:237
#define yCError(component,...)
Definition: LogComponent.h:157
#define yCDebug(component,...)
Definition: LogComponent.h:112
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:80
An interface for the device drivers.
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition: Time.cpp:124
An interface to the operating system, including Port based communication.
Signal processing.
Definition: Image.h:25
The main, catch-all namespace for YARP.
Definition: environment.h:18