iCub-main
Loading...
Searching...
No Matches
eo_ftsens_privData.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2006-2018 Istituto Italiano di Tecnologia (IIT)
3 * All rights reserved.
4 * Author: Valentina Gaggero
5 * This software may be modified and distributed under the terms of the
6 * BSD-3-Clause license. See the accompanying LICENSE file for details.
7 */
9#include "EoProtocolAS.h"
10#include "EOnv_hid.h"
11
12using namespace yarp;
13using namespace yarp::os;
14using namespace yarp::dev;
15
16
19 useCalibValues(false),
20 useTemperature(false),
21 scaleFactorIsFilled(false),
22 lastTemperature(0),
23 timestampTemperature(0.0),
24 timestampAnalogdata(0.0)
25{
26 analogdata.resize(strain_Channels, 0.0);
27 offset.resize(strain_Channels, 0.0);
28 scaleFactor.resize(strain_Channels, 1.0);
29}
30
31
33{ analogdata.resize(0);
34 offset.resize(0);
35 scaleFactor.resize(0);
36}
37
38
39bool eo_ftsens_privData::fromConfig(yarp::os::Searchable &_config, servConfigFTsensor_t &serviceConfig)
40{
41
42 ServiceParser* parser = new ServiceParser;
43 bool ret = parser->parseService(_config, serviceConfig);
44 delete parser;
45
46 if(!ret)
47 {
48 yError() << getBoardInfo() << "is missing some configuration parameter. Check logs and your config file.";
49 return false;
50 }
51
52 useCalibValues = serviceConfig.useCalibration;
53 if(serviceConfig.temperatureAcquisitionrate > 0)
54 useTemperature = true;
55 devicename = serviceConfig.nameOfStrain;
56 frameName = serviceConfig.frameName;
57
58 if(isVerbose())
59 printServiceConfig(serviceConfig);
60 return ret;
61}
62
63
64
65
66//#warning --> marco.accame: review function embObjFTsensor::fillScaleFactor() as in comment below
67// it is better to change the behaviour of the function so that: 1. we send the request, 2. we wait for the sig<> and unblock a mutex
68// current implementation relies on a wait of 1 sec and check of non-zero length of an array: smart but not the rigth way to do it.
69
70// EVEN better: in serviceVerifyActivate() we allow the retrieval of a parameter which the ETH board sends back. in such a param it is contained
71// the fullscales values ...
72
73// marco.accame on 09 jan 2018: much better using an ask(id32_fullscale) and making this variable proxied inside the ETH board ...
74
76{
77 // if we already have set the scalefactor ...
78 if(true == scaleFactorIsFilled)
79 {
80 return true;
81 }
82
83 // at first we set the scale factors to 1, so that we are sure they have a safe value. it redundant, as we already set it to 1.0
84 for(size_t i = 0; i<scaleFactor.size(); i++)
85 {
86 scaleFactor[i] = 1.0f;
87 }
88
89 // if we dont need calibration we are done
90 if(false == useCalibValues)
91 {
92 if(isVerbose())
93 {
94 yDebug() << getBoardInfo() << "fillScaleFactor(): we DONT use calibration, thus all scale factors are set to 1.0";
95 }
96
98 return true;
99 }
100
101 // if we need calibration, then we need to ask the fullscales directly to the strain
102
103
104 // marco.accame on 11 apr 2014:
105 // added the code under ifdef 1. the reason is that one cannot rely on validity of data structures inside the EOnv, as in protocol v2 the requirement is that
106 // the initialisation is not specialised and is ... all zeros. if the user wants to init to proper values must redefine the relevant INIT funtion.
107 // in this case, the eoprot_fun_INIT_as_strain_status_fullscale().
108 // extern void eoprot_fun_INIT_as_strain_status_fullscale(const EOnv* nv)
109 // {
110 // eOas_arrayofupto12bytes_t fullscale_values = {0};
111 // eo_array_New(6, 2, &fullscale_values); // itemsize = 2, capacity = 6
112 // eo_nv_Set(nv, &fullscale_values, eobool_true, eo_nv_upd_dontdo);
113 // }
114 // moreover, even if properly initted, it is required to set the size to 0 because the size being not 0 is the check of reception of a message.
115
116
117 bool gotFullScaleValues = false;
118
119
120 // Check initial size of array... it should be zero.
121 int timeout, NVsize;
122 EOnv tmpNV;
123 EOnv *p_tmpNV = NULL;
124 eOas_arrayofupto12bytes_t fullscale_values = {0};
125 // force it to be an empty array of itemsize 2 and capacity 6.
126 // the reason is that the eoprot_tag_as_strain_status_fullscale contains 3 forces and 3 torques each of 2 bytes. see eOas_strain_status_t in EoAnalogSensors.h
127 eo_array_New(6, 2, &fullscale_values);
128
129 eOprotID32_t id32_fullscale = eoprot_ID_get(eoprot_endpoint_analogsensors, eoprot_entity_as_strain, 0, eoprot_tag_as_strain_status_fullscale);
130
131
132 // at first we impose that the local value of fullscales is zero.
133 // we also force the change because this variable is readonly
134 const bool overrideROprotection = true;
135 res->setLocalValue(id32_fullscale, &fullscale_values, overrideROprotection);
136
137
138 // Prepare analog sensor
139 eOas_strain_config_t strainConfig = {0};
140 strainConfig.datarate = serviceConfig.acquisitionrate;
141 strainConfig.mode = eoas_strainmode_acquirebutdonttx;
142 strainConfig.signaloncefullscale = eobool_true;
143
144 eOprotID32_t id32_strain_config = eoprot_ID_get(eoprot_endpoint_analogsensors, eoprot_entity_as_strain, 0, eoprot_tag_as_strain_config);
145
146 timeout = 5;
147
148 // wait for response
149 while(!gotFullScaleValues && (timeout != 0))
150 {
151 res->setRemoteValue(id32_strain_config, &strainConfig);
152 SystemClock::delaySystem(1.0);
153 // read fullscale values
154 res->getLocalValue(id32_fullscale, &fullscale_values);
155 // If data arrives, size is bigger than zero
156 //#warning --> marco.accame says: to wait for 1 sec and read size is ok. a different way is to ... wait for a semaphore incremented by the reply of the board. think of it!
157 NVsize = eo_array_Size((EOarray *)&fullscale_values);
158
159 if(0 != NVsize)
160 {
161 gotFullScaleValues = true;
162 break;
163 }
164
165 timeout--;
166 if(isVerbose())
167 {
168 yWarning() << getBoardInfo() << "filling ScaleFactor ....";
169 }
170 }
171
172 if((false == gotFullScaleValues) && (0 == timeout))
173 {
174 yError() << getBoardInfo() << "fillScaleFactor(): ETH Analog sensor: request for calibration parameters timed out ";
175 return false;
176 }
177
178 if((strain_Channels != NVsize))
179 {
180 yError() << getBoardInfo() << "Analog sensor Calibration data has a different size from channels number in configuration file ";
181 return false;
182 }
183
184
185 if(gotFullScaleValues)
186 {
187 if(isVerbose())
188 {
189 yWarning() << getBoardInfo() << "fillScaleFactor() detected that already has full scale values";
190 yDebug() << getBoardInfo() << "fillScaleFactor(): Fullscale values are: size=" << eo_array_Size((EOarray *)&fullscale_values) << " numchannel=" << strain_Channels;
191 }
192
193 for (size_t i = 0; i<scaleFactor.size(); i++)
194 {
195 // Get the k-th element of the array as a 2 bytes msg
196 uint8_t *msg = (uint8_t *) eo_array_At((EOarray *) &fullscale_values, i);
197 if(NULL == msg)
198 {
199 yError() << getBoardInfo() << "fillScaleFactor() doesn't receive data for channel " << i;
200 return false;
201 }
202 // Got from CanBusMotionControl... here order of bytes seems inverted with respect to calibratedValues or uncalibratedValues (see callback of can strain messages inside the FW of ETHBOARD)
203 scaleFactor[i] = ((uint16_t)(msg[0]<<8) | msg[1]);
204 //yError() << " scale factor[" << i << "] = " << scaleFactor[i];
205 if(isVerbose())
206 {
207 yDebug() << getBoardInfo() << "fillScaleFactor(): channel " << i << "full scale value " << scaleFactor[i];
208 }
209 }
210
211 scaleFactorIsFilled = true;
212 }
213
214 return scaleFactorIsFilled;
215}
216
217
219{
220 vector<eOprotID32_t> id32v(0); //vector with id of nv to configure as regulars
221 eOprotID32_t id32 = eo_prot_ID32dummy;
222
223 //1) set regulars for ft (strain) service
224 if(true == serviceConfig.useCalibration)
225 {
226 id32 = eoprot_ID_get(eoprot_endpoint_analogsensors, eoprot_entity_as_strain, 0, eoprot_tag_as_strain_status_calibratedvalues);
227 }
228 else
229 {
230 id32 = eoprot_ID_get(eoprot_endpoint_analogsensors, eoprot_entity_as_strain, 0, eoprot_tag_as_strain_status_uncalibratedvalues);
231 }
232
233 id32v.push_back(id32);
234
235 if(!serviceSetRegulars(eomn_serv_category_strain, id32v))
236 return false;
237
238 //2) set regulars for temperature service
239 id32v.resize(0);
240 id32 = eo_prot_ID32dummy;
241
242 id32 = eoprot_ID_get(eoprot_endpoint_analogsensors, eoprot_entity_as_temperature, 0, eoprot_tag_as_temperature_status);
243 id32v.push_back(id32);
244
245 if(!serviceSetRegulars(eomn_serv_category_temperatures, id32v))
246 return false;
247
248 return true;
249}
250
251
253{
254 char loc[20] = {0};
255 char fir[20] = {0};
256 char pro[20] = {0};
257 const char * boardname = (NULL != res) ? (res->getProperties().boardnameString.c_str()) : ("NOT-ASSIGNED-YET");
258 const char * ipv4 = (NULL != res) ? (res->getProperties().ipv4addrString.c_str()) : ("NOT-ASSIGNED-YET");
259 const char * boardtype = eoboards_type2string2(static_cast<eObrd_type_t>(serviceConfig.ethservice.configuration.data.as.strain.boardtype.type), eobool_true);
260 ServiceParser *parser = new ServiceParser();
261 parser->convert(serviceConfig.ethservice.configuration.data.as.strain.canloc, loc, sizeof(loc));
262 parser->convert(serviceConfig.ethservice.configuration.data.as.strain.boardtype.firmware, fir, sizeof(fir));
263 parser->convert(serviceConfig.ethservice.configuration.data.as.strain.boardtype.protocol, pro, sizeof(pro));
264
265 yInfo() << "The embObjFTsensor device using BOARD" << boardname << " w/ IP" << ipv4 << "has the following service config:";
266 yInfo() << "- acquisitionrate =" << serviceConfig.acquisitionrate;
267 yInfo() << "- useCalibration =" << serviceConfig.useCalibration;
268 yInfo() << "- STRAIN of type" << boardtype << "named" << serviceConfig.nameOfStrain << "@" << loc << "with required protocol version =" << pro << "and required firmware version =" << fir;
269 delete parser;
270}
271
273{
274 eOas_strain_config_t strainConfig = {0};
275
276 strainConfig.datarate = serviceConfig.acquisitionrate;
277 strainConfig.signaloncefullscale = eobool_false;
278 strainConfig.mode = (true == serviceConfig.useCalibration) ? (eoas_strainmode_txcalibrateddatacontinuously) : (eoas_strainmode_txuncalibrateddatacontinuously);
279
280 // version with read-back
281
282 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_analogsensors, eoprot_entity_as_strain, 0, eoprot_tag_as_strain_config);
283
284 if(false == res->setcheckRemoteValue(id32, &strainConfig, 10, 0.010, 0.050))
285 {
286 yError() << getBoardInfo() << "FATAL: sendConfig2Strain() had an error while calling setcheckRemoteValue() for strain config ";
287 return false;
288 }
289 else
290 {
291 if(isVerbose())
292 {
293 yDebug() << getBoardInfo() << "sendConfig2Strain() correctly configured strain coinfig ";
294 }
295 }
296
297 //configure the service of temperature
298 id32 = eoprot_ID_get(eoprot_endpoint_analogsensors, eoprot_entity_as_temperature, 0, eoprot_tag_as_temperature_config);
299
300
301 eOas_temperature_config_t tempconfig = {0};
302 if(serviceConfig.temperatureAcquisitionrate > 0)
303 {
304 tempconfig.enabled = 1;
305 tempconfig.datarate = serviceConfig.temperatureAcquisitionrate/1000;
306 }
307
308
309 if(false == res->setcheckRemoteValue(id32, &tempconfig, 10, 0.010, 0.050))
310 {
311 yError() << getBoardInfo() << "FATAL: sendConfig2Strain(temperature) had an error while calling setcheckRemoteValue() for strain config ";
312 return false;
313 }
314 else
315 {
316 if(isVerbose())
317 {
318 yDebug() << getBoardInfo() << "sendConfig2Strain() correctly configured strain coinfig ";
319 }
320 }
321 return true;
322}
323
324bool eo_ftsens_privData::fillTemperatureEthServiceInfo(eOmn_serv_parameter_t &ftSrv, eOmn_serv_parameter_t &tempSrv)
325{
326// const eOmn_serv_parameter_t* servparamstrain = &serviceConfig.ethservice;
327// eOmn_serv_parameter_t servparamtemp;
328// const eOmn_serv_parameter_t* servparamtemp_ptr = &servparamtemp;
329
330 tempSrv.configuration.type = eomn_serv_AS_temperatures;
331
332 EOarray* array = eo_array_New(eOas_temperature_descriptors_maxnumber, sizeof(eOas_temperature_descriptor_t), &(tempSrv.configuration.data.as.temperature.arrayofdescriptor));
333 eOas_temperature_descriptor_t descr= {0};
334 descr.typeofboard = ftSrv.configuration.data.as.strain.boardtype.type; //eobrd_strain2 ;
335 descr.typeofsensor = eoas_temperature_t1;
336 descr.on.can.place = eobrd_place_can;
337 descr.on.can.port = ftSrv.configuration.data.as.strain.canloc.port;
338 descr.on.can.addr = ftSrv.configuration.data.as.strain.canloc.addr;
339 eo_array_PushBack(array, &descr);
340
341 eOas_temperature_setof_boardinfos_t * boardInfoSet_ptr = &tempSrv.configuration.data.as.temperature.setofboardinfos;
342 eOresult_t res = eoas_temperature_setof_boardinfos_clear(boardInfoSet_ptr);
343 if(res != eores_OK)
344 {
345 yError() << getBoardInfo() << "Error in eoas_temperature_setof_boardinfos_clear()";
346 return false;
347 }
348
349 eObrd_info_t boardInfo = {0};
350 boardInfo.type = ftSrv.configuration.data.as.strain.boardtype.type;
351 memcpy(&boardInfo.protocol , &(ftSrv.configuration.data.as.strain.boardtype.protocol), sizeof(eObrd_protocolversion_t));
352 memcpy(&boardInfo.firmware, &(ftSrv.configuration.data.as.strain.boardtype.firmware), sizeof(eObrd_firmwareversion_t));
353 res = eoas_temperature_setof_boardinfos_add(boardInfoSet_ptr, &boardInfo);
354 if(eores_OK != res)
355 {
356 yError() << getBoardInfo() << "Error in eoas_temperature_setof_boardinfos_add()";
357 return false;
358 }
359
360 return true;
361
362}
bool convert(std::string const &fromstring, eOmc_actuator_t &toactuatortype, bool &formaterror)
bool parseService(yarp::os::Searchable &config, servConfigMais_t &maisconfig)
virtual bool setcheckRemoteValue(const eOprotID32_t id32, void *value, const unsigned int retries=10, const double waitbeforecheck=0.001, const double timeout=0.050)=0
virtual const Properties & getProperties()=0
virtual bool setRemoteValue(const eOprotID32_t id32, void *value)=0
virtual bool getLocalValue(const eOprotID32_t id32, void *value)=0
virtual bool setLocalValue(eOprotID32_t id32, const void *value, bool overrideROprotection=false)=0
bool serviceSetRegulars(eOmn_serv_category_t category, vector< eOprotID32_t > &id32vector, double timeout=0.500)
void printServiceConfig(servConfigFTsensor_t &serviceConfig)
bool fromConfig(yarp::os::Searchable &config, servConfigFTsensor_t &serviceConfig)
bool initRegulars(servConfigFTsensor_t &serviceConfig)
bool fillScaleFactor(servConfigFTsensor_t &serviceConfig)
bool sendConfig2Strain(servConfigFTsensor_t &serviceConfig)
std::vector< double > scaleFactor
std::vector< double > analogdata
bool fillTemperatureEthServiceInfo(eOmn_serv_parameter_t &ftSrv, eOmn_serv_parameter_t &tempSrv)
Copyright (C) 2008 RobotCub Consortium.
std::string nameOfStrain
eOmn_serv_parameter_t ethservice