16#include <linux/i2c-dev.h>
19# include <i2c/smbus.h>
22#include <linux/kernel.h>
42constexpr uint8_t i2cAddrA = 0x28;
57 readFunc(&
BoschIMU::sendReadCommandSer),
66 errorCounter.resize(11);
76 yCTrace(IMUBOSCH_BNO055,
"Parameters are:\n\t%s", config.
toString().c_str());
78 if(!config.
check(
"comport") && !config.
check(
"i2c"))
80 yCError(IMUBOSCH_BNO055) <<
"Params 'comport' and 'i2c' not found";
84 if (config.
check(
"comport") && config.
check(
"i2c"))
86 yCError(IMUBOSCH_BNO055) <<
"Params 'comport' and 'i2c' both specified";
102 yCError(IMUBOSCH_BNO055) <<
"i2c param malformed, it should be a string, aborting.";
107 fd =
::open(i2cDevFile.c_str(), O_RDWR);
111 yCError(IMUBOSCH_BNO055,
"Can't open %s, %s", i2cDevFile.c_str(), strerror(errno));
115 if (::ioctl(
fd, I2C_SLAVE, i2cAddrA) < 0)
117 yCError(IMUBOSCH_BNO055,
"ioctl failed on %s, %s", i2cDevFile.c_str(), strerror(errno));
126 yCError(IMUBOSCH_BNO055,
"Can't open %s, %s", config.
find(
"comport").
toString().c_str(), strerror(errno));
130 struct termios options;
131 tcgetattr(
fd, &options);
136 int baudRate = B115200;
137 cfsetospeed(&options, baudRate);
138 cfsetispeed(&options, baudRate);
141 options.c_cflag &= ~CSIZE;
142 options.c_cflag |= CS8;
145 options.c_cflag &= ~CSTOPB;
148 options.c_cflag &=~PARENB;
156 options.c_cc[VMIN] = 0;
157 options.c_cc[VTIME] = 2;
160 options.c_cflag |= (CLOCAL | CREAD);
162 tcflush(
fd, TCIOFLUSH);
165 if ( tcsetattr(
fd, TCSANOW, &options) != 0)
167 yCError(IMUBOSCH_BNO055,
"Configuring comport failed");
175 double period = config.
check(
"period",
Value(10),
"Thread period in ms").asInt32() / 1000.0;
184 m_sensorName =
"sensor_imu_bosch_bno055";
185 yCWarning(IMUBOSCH_BNO055) <<
"Parameter \"sensor_name\" not set. Using default value \"" << m_sensorName <<
"\" for this parameter.";
194 m_frameName = m_sensorName;
195 yCWarning(IMUBOSCH_BNO055) <<
"Parameter \"frame_name\" not set. Using the same value as \"sensor_name\" for this parameter.";
198 return PeriodicThread::start();
205 PeriodicThread::stop();
221 "Inertial sensor didn't understand the command. \n\
222 If this error happens more than once in a row, please check serial communication is working fine and it isn't affected by electrical disturbance.");
231 "Received unknown response message. \n\
232 If this error happens more than once in a row, please check serial communication is working fine and it isn't affected by electrical disturbance.");
249 "Inertial sensor didn't understand the command. \n\
250 If this error happens more than once in a row, please check serial communication is working fine and it isn't affected by electrical disturbance.");
259 "Received unknown response message. \n\
260 If this error happens more than once in a row, please check serial communication is working fine and it isn't affected by electrical disturbance.");
274 bool success =
false;
275 for(
int trials=0; (trials<3) && (success==
false); trials++)
290 if(nbytes_w != command_len)
292 yCError(IMUBOSCH_BNO055) <<
"Cannot correctly send the message: " << comment;
297 memset(buf, 0x00, 20);
328 int command_len = 4+len;
334 command[3]= (
unsigned char) len;
335 for (
int i = 0; i < len; i++) {
344 if(nbytes_w != command_len)
346 yCError(IMUBOSCH_BNO055) <<
"Cannot correctly send the message: " << comment;
357 yCError(IMUBOSCH_BNO055) <<
"FAILED writing " << comment;
378 while(r!=0 && bytesRead < bytes);
386 while( (
::read(
fd, (
void*) &
byte, 1) > 0 ))
395 for (
int i = 0; i < length; i++) {
396 printf(
"\t0x%02X ",
buffer[i]);
412 yCError(IMUBOSCH_BNO055) <<
"@ line " << __LINE__;
417 yCError(IMUBOSCH_BNO055) <<
"@ line " << __LINE__;
438 if (i2c_smbus_read_i2c_block_data(
fd, register_add, len, buf) < 0)
440 yCError(IMUBOSCH_BNO055) <<
"Cannot correctly send the message: " << comment;
456 yCError(IMUBOSCH_BNO055) <<
"Wrong device on the bus, it is not BNO055";
469 yCError(IMUBOSCH_BNO055) <<
"Unable to set the Config mode";
477 yCError(IMUBOSCH_BNO055) <<
"Unable to set external clock";
488 yCError(IMUBOSCH_BNO055) <<
"Unable to set the page ID";
497 yCError(IMUBOSCH_BNO055) <<
"Unable to set the Operative mode";
511 yCError(IMUBOSCH_BNO055) <<
"Set page id 0 failed";
542 yCError(IMUBOSCH_BNO055) <<
"Set config mode failed";
558 yCError(IMUBOSCH_BNO055) <<
"Set external clock failed";
582 yCError(IMUBOSCH_BNO055) <<
"Set config NDOF_MODE failed";
591 for(
int i=0; i<10; i++)
604 yCError(IMUBOSCH_BNO055) <<
"First read from the device failed, check everything is fine and retry";
615 int16_t raw_data[16];
624 yCError(IMUBOSCH_BNO055) <<
"Failed to read all the data";
632 for(
int i=0; i<16; i++)
657 if( (sum_squared < 0.9) || (sum_squared > 1.2) )
670 data_tmp[3] = (double)raw_data[0] / 100.0;
671 data_tmp[4] = (double)raw_data[1] / 100.0;
672 data_tmp[5] = (double)raw_data[2] / 100.0;
676 data_tmp[6] = (double)raw_data[6] / 16.0;
677 data_tmp[7] = (double)raw_data[7] / 16.0;
678 data_tmp[8] = (double)raw_data[8] / 16.0;
681 data_tmp[9] = (double)raw_data[3] / 16.0;
682 data_tmp[10] = (double)raw_data[4] / 16.0;
683 data_tmp[11] = (double)raw_data[5] / 16.0;
688 std::lock_guard<std::mutex> guard(
mutex);
698 yCDebug(IMUBOSCH_BNO055,
"\t errors while reading data: %d",
errs);
708 std::lock_guard<std::mutex> guard(
mutex);
744 yCError(IMUBOSCH_BNO055) <<
"sens_index must be equal to 0, since there is only one sensor in consideration";
751bool BoschIMU::genericGetSensorName(
size_t sens_index, std::string& name)
const
755 yCError(IMUBOSCH_BNO055) <<
"sens_index must be equal to 0, since there is only one sensor in consideration";
763bool BoschIMU::genericGetFrameName(
size_t sens_index, std::string& frameName)
const
767 yCError(IMUBOSCH_BNO055) <<
"sens_index must be equal to 0, since there is only one sensor in consideration";
771 frameName = m_frameName;
784 return genericGetStatus(sens_index);
789 return genericGetSensorName(sens_index, name);
794 return genericGetFrameName(sens_index, frameName);
801 yCError(IMUBOSCH_BNO055) <<
"sens_index must be equal to 0, since there is only one sensor in consideration";
806 std::lock_guard<std::mutex> guard(
mutex);
824 return genericGetStatus(sens_index);
829 return genericGetSensorName(sens_index, name);
834 return genericGetFrameName(sens_index, frameName);
841 yCError(IMUBOSCH_BNO055) <<
"sens_index must be equal to 0, since there is only one sensor in consideration";
846 std::lock_guard<std::mutex> guard(
mutex);
862 return genericGetStatus(sens_index);
867 return genericGetSensorName(sens_index, name);
872 return genericGetFrameName(sens_index, frameName);
879 yCError(IMUBOSCH_BNO055) <<
"sens_index must be equal to 0, since there is only one sensor in consideration";
884 std::lock_guard<std::mutex> guard(
mutex);
900 return genericGetStatus(sens_index);
905 return genericGetSensorName(sens_index, name);
910 return genericGetFrameName(sens_index, frameName);
917 yCError(IMUBOSCH_BNO055) <<
"sens_index must be equal to 0, since there is only one sensor in consideration";
922 std::lock_guard<std::mutex> guard(
mutex);
924 out[0] =
data[9] / 1000000;
925 out[1] =
data[10]/ 1000000;
926 out[2] =
data[11]/ 1000000;
935 yCTrace(IMUBOSCH_BNO055,
"Thread released");
imuBosch_BNO055: This device will connect to the proper analogServer and read the data broadcasted ma...
void threadRelease() override
Terminate communication with the device and release the thread.
unsigned char command[MAX_MSG_LENGTH]
packet to be written to the device
bool getThreeAxisGyroscopeMeasure(size_t sens_index, yarp::sig::Vector &out, double ×tamp) const override
Get three axis gyroscope measurements.
bool sendReadCommandSer(unsigned char register_add, int len, unsigned char *buf, std::string comment="")
std::atomic< bool > dataIsValid
std::mutex mutex
mutex to avoid resource clash
bool checkReadResponse(unsigned char *response)
ReadFuncPtr readFunc
Functor object.
yarp::math::Quaternion quaternion_tmp
orientation in quaternion representation
size_t getNrOfThreeAxisMagnetometers() const override
Get the number of three axis magnetometers in the device.
void printBuffer(unsigned char *buffer, int length)
bool checkError
flag to check read error of sensor data
yarp::sig::Vector data
sensor data buffer
bool getChannels(int *nc) override
Get the number of channels of the sensor.
bool sendReadCommandI2c(unsigned char register_add, int len, unsigned char *buf, std::string comment="")
bool getThreeAxisLinearAccelerometerFrameName(size_t sens_index, std::string &frameName) const override
Get the name of the frame in which three axis linear accelerometer measurements are expressed.
bool getThreeAxisGyroscopeFrameName(size_t sens_index, std::string &frameName) const override
Get the name of the frame in which three axis gyroscope measurements are expressed.
bool close() override
Close the device.
bool i2c_flag
flag to check if device connected through i2c commununication
double m_timeStamp
device timestamp
unsigned char response[MAX_MSG_LENGTH]
packet to be read from the device
bool getOrientationSensorFrameName(size_t sens_index, std::string &frameName) const override
Get the name of the frame in which orientation sensor measurements are expressed.
bool threadInit() override
Initialize process with desired device configurations.
bool sendAndVerifyCommandSer(unsigned char register_add, int len, unsigned char *cmd, std::string comment)
bool getThreeAxisGyroscopeName(size_t sens_index, std::string &name) const override
Get the name of three axis gyroscope.
bool getOrientationSensorMeasureAsRollPitchYaw(size_t sens_index, yarp::sig::Vector &rpy, double ×tamp) const override
Get orientation sensor measurements.
bool checkWriteResponse(unsigned char *response)
bool calibrate(int ch, double v) override
Calibrate the sensor, single channel.
yarp::sig::Vector errorCounter
bool getThreeAxisMagnetometerFrameName(size_t sens_index, std::string &frameName) const override
Get the name of the frame in which three axis magnetometer measurements are expressed.
int nChannels
number of channels in the output port. Default 12. If 16, also includes quaternion data
yarp::dev::MAS_status getOrientationSensorStatus(size_t sens_index) const override
Get the status of orientation sensor.
bool getThreeAxisLinearAccelerometerName(size_t sens_index, std::string &name) const override
Get the name of three axis linear accelerometer.
bool read(yarp::sig::Vector &out) override
Read a vector from the sensor.
bool getOrientationSensorName(size_t sens_index, std::string &name) const override
Get the name of orientation sensor.
yarp::dev::MAS_status getThreeAxisGyroscopeStatus(size_t sens_index) const override
Get the status of three axis gyroscope.
bool getThreeAxisMagnetometerName(size_t sens_index, std::string &name) const override
Get the name of three axis magnetometer.
yarp::math::Quaternion quaternion
orientation in quaternion representation
bool sendWriteCommandSer(unsigned char register_add, int len, unsigned char *cmd, std::string comment="")
yarp::dev::MAS_status getThreeAxisMagnetometerStatus(size_t sens_index) const override
Get the status of three axis magnetometer.
double timeLastReport
timestamp of last reported data
int readBytes(unsigned char *buffer, int bytes)
size_t getNrOfThreeAxisGyroscopes() const override
Get the number of three axis gyroscopes in the device.
int fd
file descriptor to open device at system level
size_t getNrOfThreeAxisLinearAccelerometers() const override
Get the number of three axis linear accelerometers in the device.
bool open(yarp::os::Searchable &config) override
Open the device and set up parameters/communication.
yarp::sig::Vector data_tmp
sensor data temporary buffer
size_t getNrOfOrientationSensors() const override
Get the number of orientation sensors in the device.
bool getThreeAxisLinearAccelerometerMeasure(size_t sens_index, yarp::sig::Vector &out, double ×tamp) const override
Get three axis linear accelerometer measurements.
yarp::sig::Vector RPY_angle
orientation in Euler angle representation
yarp::dev::MAS_status getThreeAxisLinearAccelerometerStatus(size_t sens_index) const override
Get the status of three axis linear accelerometer.
bool getThreeAxisMagnetometerMeasure(size_t sens_index, yarp::sig::Vector &out, double ×tamp) const override
Get three axis magnetometer measurements.
void run() override
Update loop where measurements are read from the device.
yarp::sig::Matrix toRotationMatrix4x4() const
Converts a quaternion to a rotation matrix.
An abstraction for a periodic thread.
bool setPeriod(double period)
Set the (new) period of the thread.
A base class for nested structures that can be searched.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
static double nowSystem()
static void delaySystem(double seconds)
A single value (typically within a Bottle).
virtual bool isString() const
Checks if value is a string.
std::string toString() const override
Return a standard text representation of the content of the object.
virtual std::string asString() const
Get string value.
void resize(size_t size) override
Resize the vector.
void zero()
Zero the elements of the vector.
#define ATTEMPTS_NUM_OF_SEND_CONFIG_CMD
#define REGISTER_NOT_READY
#define TIME_REPORT_INTERVAL
#define yCError(component,...)
#define yCTrace(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
For streams capable of holding different kinds of content, check what they actually have.
MAS_status
Status of a given analog sensor exposed by a multiple analog sensors interface.
@ MAS_ERROR
The sensor is in generic error state.
@ MAS_OK
The sensor is working correctly.
yarp::sig::Vector dcm2rpy(const yarp::sig::Matrix &R)
Converts a dcm (direction cosine matrix) rotation matrix to roll-pitch-yaw angles (defined in Math....
void delay(double seconds)
Wait for a certain number of seconds.
An interface to the operating system, including Port based communication.
bool write(const ImageOf< PixelRgb > &src, const std::string &dest, image_fileformat format=FORMAT_PPM)