9 #include <yarp/os/Time.h>
10 #include <yarp/os/LogStream.h>
11 #include <yarp/os/Log.h>
24 fprintf(stderr,
"%s\n", config.toString().c_str());
26 correct &= config.check(
"canbusDevice");
27 correct &= config.check(
"canDeviceNum");
28 correct &= config.check(
"canAddress");
29 correct &= config.check(
"format");
30 correct &= config.check(
"period");
31 correct &= config.check(
"channels");
32 correct &= config.check(
"physDevice");
36 yError() <<
"Insufficient parameters to CanBusAnalogSensor\n";
40 int period=config.find(
"period").asInt32();
41 setPeriod((
double)period/1000.0);
45 prop.put(
"device", config.find(
"canbusDevice").asString().c_str());
46 prop.put(
"physDevice", config.find(
"physDevice").asString().c_str());
47 prop.put(
"canTxTimeout", 500);
48 prop.put(
"canRxTimeout", 500);
49 canDeviceNum = config.find(
"canDeviceNum").asInt32();
50 prop.put(
"canDeviceNum", canDeviceNum);
51 prop.put(
"canMyAddress", 0);
59 if (!driver.isValid())
61 yError() <<
"Error opening PolyDriver check parameters";
67 yError() <<
"Error opening can device not available";
70 driver.view(pCanBufferFactory);
75 pCanBus->canSetBaudRate(0);
80 this->boardId = config.find(
"canAddress").asInt32();
81 this->useCalibration = config.find(
"useCalibration").asInt32();
83 unsigned int tmpFormat = config.find(
"format").asInt32();
85 this->dataFormat = ANALOG_FORMAT_8_BIT;
86 else if (tmpFormat == 16)
87 this->dataFormat = ANALOG_FORMAT_16_BIT;
89 this->dataFormat = ANALOG_FORMAT_ERR;
92 if( config.check(
"diagnostic") && config.find(
"diagnostic").asInt32() == 1)
94 this->diagnostic =
true;
98 this->diagnostic =
false;
103 for (
int id=0;
id<16; ++id)
105 pCanBus->canIdAdd(0x300+(boardId<<4)+
id);
107 pCanBus->canIdAdd(0x200+boardId);
108 pCanBus->canIdAdd(0x200+(boardId<<4));
111 this->channelsNum = config.find(
"channels").asInt32();
112 data.resize(channelsNum);
114 scaleFactor.resize(channelsNum);
118 sensor_start(config);
120 PeriodicThread::start();
124 bool CanBusAnalogSensor::readFullScaleAnalog(
int ch)
126 scaleFactor[ch]=1
e-20;
128 unsigned int canMessages=0;
129 unsigned id = 0x200 + boardId;
130 CanMessage &msg=outBuffer[0];
132 msg.getData()[0]=0x18;
136 pCanBus->canWrite(outBuffer, 1, &canMessages);
139 bool full_scale_read=
false;
143 unsigned int read_messages = 0;
144 bool b = pCanBus->canRead(inBuffer,max_messages,&read_messages,
false);
146 for (
unsigned int i=0; i<read_messages; i++)
148 CanMessage& m= inBuffer[i];
149 unsigned int currId=m.getId();
150 if (currId==(0x0200 | boardId << 4))
152 m.getData()[0]==0x18 &&
155 scaleFactor[ch]=m.getData()[2]<<8 | m.getData()[3];
156 full_scale_read=
true;
160 yarp::os::Time::delay(0.002);
163 while(timeout<32 && full_scale_read==
false);
165 if (full_scale_read==
false)
167 yError(
"Trying to get fullscale data from sensor %d net [%d]: no answer received or message lost (ch:%d)\n", boardId, canDeviceNum, ch);
174 bool CanBusAnalogSensor::sensor_start(yarp::os::Searchable& analogConfig)
176 yTrace(
"Initializing analog device %s\n", analogConfig.find(
"deviceId").toString().c_str());
178 unsigned int canMessages=0;
179 unsigned id = 0x200 + boardId;
181 if (analogConfig.check(
"period"))
183 int period=analogConfig.find(
"period").asInt32();
184 CanMessage &msg=outBuffer[0];
186 msg.getData()[0]=0x08;
187 msg.getData()[1]=period;
190 pCanBus->canWrite(outBuffer, 1, &canMessages);
191 yDebug(
"using broadcast period %d on device %s\n", period, analogConfig.find(
"deviceId").toString().c_str());
195 if (channelsNum==16 && dataFormat==ANALOG_FORMAT_8_BIT)
197 CanMessage &msg=outBuffer[0];
199 msg.getData()[0]=0x07;
200 msg.getData()[1]=0x00;
203 pCanBus->canWrite(outBuffer, 1, &canMessages);
207 else if (channelsNum==6 && dataFormat==ANALOG_FORMAT_16_BIT)
210 if (useCalibration>0)
212 yDebug(
"Using internal calibration on device %s\n", analogConfig.find(
"deviceId").toString().c_str());
214 for (
int ch=0; ch<6; ch++)
220 b = readFullScaleAnalog(ch);
223 if (attempts>0) yWarning(
"Trying to get fullscale data from sensor: channel recovered (ch:%d)\n", ch);
227 yarp::os::Time::delay(0.020);
231 yError(
"Trying to get fullscale data from sensor: all attempts failed (ch:%d)\n", ch);
237 fprintf(stderr,
"Sensor Fullscale Id %#4X: ",boardId);
238 fprintf(stderr,
" %f ", scaleFactor[0]);
239 fprintf(stderr,
" %f ", scaleFactor[1]);
240 fprintf(stderr,
" %f ", scaleFactor[2]);
241 fprintf(stderr,
" %f ", scaleFactor[3]);
242 fprintf(stderr,
" %f ", scaleFactor[4]);
243 fprintf(stderr,
" %f ", scaleFactor[5]);
248 CanMessage &msg=outBuffer[0];
250 msg.getData()[0]=0x07;
251 if (useCalibration == 1) msg.getData()[1]=0x00;
252 if (useCalibration == 2) msg.getData()[1]=0x00;
253 if (useCalibration == 3) msg.getData()[1]=0x00;
256 pCanBus->canWrite(outBuffer, 1, &canMessages);
261 yInfo(
"Using uncalibrated raw data for device %s\n", analogConfig.find(
"deviceId").toString().c_str());
262 CanMessage &msg=outBuffer[0];
264 msg.getData()[0]=0x07;
265 msg.getData()[1]=0x03;
268 pCanBus->canWrite(outBuffer, 1, &canMessages);
274 bool CanBusAnalogSensor::sensor_stop()
276 unsigned int canMessages=0;
277 unsigned id = 0x200 + boardId;
278 CanMessage &msg=outBuffer[0];
280 msg.getData()[0]=0x07;
281 msg.getData()[1]=0x01;
284 pCanBus->canWrite(outBuffer, 1, &canMessages);
291 PeriodicThread::stop();
297 if (pCanBufferFactory)
299 pCanBufferFactory->destroyBuffer(inBuffer);
300 pCanBufferFactory->destroyBuffer(outBuffer);
313 if( this->diagnostic )
316 return IAnalogSensor::AS_OK;
321 if( this->diagnostic )
324 return IAnalogSensor::AS_OK;
361 bool CanBusAnalogSensor::decode16(
const unsigned char *msg,
int msg_id,
double *
data)
363 const char groupId=(msg_id & 0x00f);
372 data[k]=(((
unsigned short)(msg[2*k+1]))<<8)+msg[2*k]-0x8000;
373 if (useCalibration>0)
375 data[k]=
data[k]*scaleFactor[k]/float(0x8000);
384 data[k+3]=(((
unsigned short)(msg[2*k+1]))<<8)+msg[2*k]-0x8000;
385 if (useCalibration>0)
387 data[k+3]=
data[k+3]*scaleFactor[k+3]/float(0x8000);
399 yWarning(
"Got unexpected class 0x3 msg(s): groupId 0x%x\n", groupId);
410 bool CanBusAnalogSensor::decode8(
const unsigned char *msg,
int msg_id,
double *
data)
412 const char groupId=(msg_id & 0x00f);
419 for(
int k=0;k<=6;k++)
425 for(
int k=0;k<=7;k++)
436 yWarning(
"CanBusAnalogSensor got unexpected class 0x3 msg(s): groupId 0x%x\n", groupId);
448 lock_guard<mutex> lck(mtx);
450 unsigned int canMessages=0;
456 yError()<<
"CanBusAnalogSensor canRead failed\n";
459 double timeNow=Time::now();
460 for (
unsigned int i=0; i<canMessages; i++)
462 CanMessage &msg=inBuffer[i];
464 unsigned int msgid = msg.getId();
465 unsigned char *buff = msg.getData();
466 unsigned int len = msg.getLen();
467 unsigned int id = (msgid & 0x00f0)>>4;
468 const char type = ((msgid&0x700)>>8);
471 status=IAnalogSensor::AS_OK;
477 timeStamp=Time::now();
480 case ANALOG_FORMAT_8_BIT:
481 ret=decode8(buff, msgid,
data.data());
482 status=IAnalogSensor::AS_OK;
484 case ANALOG_FORMAT_16_BIT:
487 ret=decode16(buff, msgid,
data.data());
488 status=IAnalogSensor::AS_OK;
492 if ((len==7) && (buff[6] != 0))
494 status=IAnalogSensor::AS_OVF;
498 status=IAnalogSensor::AS_ERROR;
500 ret=decode16(buff, msgid,
data.data());
504 status=IAnalogSensor::AS_ERROR;
512 if (timeStamp+0.1<timeNow)
514 status=IAnalogSensor::AS_TIMEOUT;
520 yTrace(
"CanBusVirtualAnalogSensor Thread released\n");
const int CAN_DRIVER_BUFFER_SIZE
virtual int getChannels()
virtual void threadRelease()
virtual bool open(yarp::os::Searchable &config)
virtual bool threadInit()
virtual int getState(int ch)
virtual int calibrateChannel(int ch, double v)
virtual int read(yarp::sig::Vector &out)