56 #include "rnr/rnrconfig.h" 57 #include "rnr/serdev.h" 87 void Quaternion::clear()
95 void Quaternion::convertEuler(
double phi,
double theta,
double psi)
97 double half_phi, half_theta, half_psi;
98 double cos_phi, sin_phi;
99 double cos_theta, sin_theta;
100 double cos_psi, sin_psi;
102 half_phi = phi / 2.0;
103 half_theta = theta / 2.0;
104 half_psi = psi / 2.0;
106 cos_phi = cos(half_phi);
107 sin_phi = sin(half_phi);
108 cos_theta = cos(half_theta);
109 sin_theta = sin(half_theta);
110 cos_psi = cos(half_psi);
111 sin_psi = sin(half_psi);
113 m_x = cos_phi*cos_theta*cos_psi + sin_phi*sin_theta*sin_psi;
114 m_y = sin_phi*cos_theta*cos_psi - cos_phi*sin_theta*sin_psi;
115 m_z = cos_phi*sin_theta*cos_psi + sin_phi*cos_theta*sin_psi;
116 m_w = cos_phi*cos_theta*sin_psi - sin_phi*sin_theta*cos_psi;
119 void Quaternion::convertTaitBryan(
double roll,
double pitch,
double yaw)
121 double half_roll = 0.5 * roll;
122 double half_pitch = 0.5 * pitch;
123 double half_yaw = 0.5 * yaw;
125 double t0 = cos(half_yaw);
126 double t1 = sin(half_yaw);
127 double t2 = cos(half_roll);
128 double t3 = sin(half_roll);
129 double t4 = cos(half_pitch);
130 double t5 = sin(half_pitch);
132 m_w = t0 * t2 * t4 + t1 * t3 * t5;
133 m_x = t0 * t3 * t4 - t1 * t2 * t5;
134 m_y = t0 * t2 * t5 + t1 * t3 * t4;
135 m_z = t1 * t2 * t4 - t0 * t3 * t5;
143 LaeImu::LaeImu(
string strIdent) : m_strIdent(strIdent)
164 string strDevNameReal;
172 m_fd = SerDevOpen(strDevNameReal.c_str(), nBaudRate, 8,
'N', 1,
false,
false);
176 LOGERROR(
"Failed to open %s@%d.", strDevNameReal.c_str(), nBaudRate);
177 rc = -LAE_ECODE_NO_DEV;
186 RtDb.m_enable.m_bImu =
true;
190 LOGDIAG2(
"Opened interface to IMU on %s@%d.",
191 strDevNameReal.c_str(), nBaudRate);
208 LOGDIAG2(
"Closed %s interface to IMU.",
m_strDevName.c_str());
228 RtDb.m_enable.m_bImu =
false;
234 RtDb.m_enable.m_bImu =
true;
368 LaeImu(
"CleanFlight Naze32 with MPU-6050 IMU sensor")
383 strIdent =
"Unknown - blacklisted";
392 <<
" Naze32 with MPU-6050 IMU sensor";
457 RtDb.m_imu.m_accel[i] =
m_accel[i];
460 RtDb.m_imu.m_gyro[i] =
m_gyro[i];
465 RtDb.m_imu.m_rpy[i] =
m_rpy[i];
469 RtDb.m_imu.m_rpy[YAW] =
m_rpy[YAW];
477 static const size_t RspDataLen = 7;
479 byte_t rspData[RspDataLen];
484 return -LAE_ECODE_IO;
489 if( (rc =
sendCmd(CmdId, NULL, 0)) == LAE_OK )
510 static const size_t RspDataLen = 18;
512 byte_t rspData[RspDataLen];
518 return -LAE_ECODE_IO;
523 if( (rc =
sendCmd(CmdId, NULL, 0)) == LAE_OK )
530 for(i = 0, n = 0; i <
NumOfAxes; ++i, n += 2)
534 for(i = 0; i < NumOfAxes; ++i, n += 2)
538 for(i = 0; i < NumOfAxes; ++i, n += 2)
552 static const size_t RspDataLen = 6;
554 byte_t rspData[RspDataLen];
560 return -LAE_ECODE_IO;
565 if( (rc =
sendCmd(CmdId, NULL, 0)) == LAE_OK )
572 for(i = 0, n = 0; i <
NumOfAxes; ++i, n += 2)
597 cmd[n++] = (byte_t)lenData;
598 chksum ^= (byte_t)lenData;
600 cmd[n++] = (byte_t)cmdId;
601 chksum ^= (byte_t)cmdId;
603 for(
size_t i = 0; i < lenData; ++i)
605 cmd[n++] = (byte_t)cmdData[i];
606 chksum ^= (byte_t)cmdData[i];
609 cmd[n++] = (byte_t)chksum;
618 LOGERROR(
"IMU: Cmd %d: Send failed.", cmdId);
619 return -LAE_ECODE_IO;
640 LOGERROR(
"IMU: Cmd %d response: Receive failed.", cmdId);
642 return -LAE_ECODE_IO;
644 else if( n < lenRsp )
646 LOGERROR(
"IMU: Cmd %d response: Receive partial response: " 647 "rcv'd %zu bytes, expected %zu bytes.", cmdId, n, lenRsp);
649 return -LAE_ECODE_IO;
654 if( fldSize != lenData )
656 LOGERROR(
"IMU: Cmd %d response: Data length mismatch: " \
657 "Received %zu bytes, expected %zu bytes.", cmdId, fldSize, lenData);
659 return -LAE_ECODE_IO;
664 if( fldCmdId != cmdId )
666 LOGERROR(
"IMU: Cmd %d response: Command Id mismatch: Received %d.",
669 return -LAE_ECODE_IO;
681 fldChkSum = rsp[lenRsp-1];
683 if( chksum != fldChkSum )
685 LOGERROR(
"IMU: Cmd %d response: Checksum mismatch: " \
686 "Received 0x%02x, calculated 0x%02x.", cmdId, fldChkSum, chksum);
688 return -LAE_ECODE_IO;
701 LOGDIAG3(
"IMU: Resynchronizing serial communication.");
703 for(nTries = 0; nTries < nMaxTries; ++nTries)
712 LOGWARN(
"IMU: Failed to resynchronize communication in %d tries.", nMaxTries);
713 LOGWARN(
"IMU: Blacklisting.", nMaxTries);
725 SerDevFIFOOutputFlush(
m_fd);
726 SerDevFIFOInputFlush(
m_fd);
731 buf[0] = (byte_t)(val & 0xff);
732 buf[1] = (byte_t)((val >> 8) & 0xff);
738 val = ((uint_t)(buf[1]) << 8) | (uint_t)buf[0];
745 v = ((s16_t)(buf[1]) << 8) | (s16_t)buf[0];
752 buf[0] = (byte_t)(val & 0xff);
753 buf[1] = (byte_t)((val >> 8) & 0xff);
754 buf[2] = (byte_t)((val >> 16) & 0xff);
755 buf[3] = (byte_t)((val >> 24) & 0xff);
761 val = ((uint_t)(buf[3]) << 24) |
762 ((uint_t)(buf[2]) << 16) |
763 ((uint_t)(buf[1]) << 8) |
772 v = ((s32_t)(buf[3]) << 24) |
773 ((s32_t)(buf[2]) << 16) |
774 ((s32_t)(buf[1]) << 8) |
virtual int configure(const laelaps::LaeDesc &desc)
Configure IMU from product description.
int m_gyroRaw[NumOfAxes]
gyroscope raw values
static const uint_t TFlushDelay
flush buffer delay (usec)
static const double MspMpu6050RawToDegPerSec
MPU-6050 rotation raw value to degrees/second.
void flush(uint_t t)
Flush serial input and output FIFOs, discarding all data.
uint_t m_uCaps
capabilities or'd bits
uint_t m_uMultiType
multiwii type
Laelaps tuning data class.
Laelaps robotic mobile platform full description class.
double m_rpy[NumOfAxes]
roll,pitch,yaw (radians)
void lockIo()
Lock the shared I/O resource.
double degToRad(double d)
Convert degrees to radians.
double m_accel[NumOfAxes]
accelerometer (m/s^2)
virtual int readRawInertia()
Read sensors inertia data.
virtual int open(const std::string &strDevName, int nBaudRate)
void unlockIo()
Unlock the shared I/O resource.
virtual int readRawImu()
Read sensor and board raw IMU values.
int sendCmd(uint_t cmdId, byte_t cmdData[], size_t lenData)
Send command to IMU.
std::string m_strIdent
IMU identity.
int m_fd
opened device file descriptor
pthread_mutex_t m_mutexIo
low-level I/O mutex
static const uint_t TRspTimeout
response timeout (usec)
static const double MspGToMPerSec2
standard g in m/s^2
int pack16(int val, byte_t buf[])
Pack 16-bit signed value into buffer.
void resyncComm()
Attempt to resynchronize the serial communication between the host and the IMU.
void unlockOp()
Unlock the extended operation.
static const char *const MspCmdPreamble
command preamble
virtual void clearSensedData()
Clear IMU sensed data.
static const uint_t MspCmdIdIdent
read board/sensor idents
int m_nBaudRate
device baudrate
static const int MspRspMinLen
MspRspHdrLen+1 response min len.
Multiwii Serial Protocal Interface.
int unpack16(byte_t buf[], int &val)
Unpack 16-bit signed value from buffer.
LaeImuCleanFlight()
Default constructor.
virtual int convertRawToSI()
Convert last read IMU values to International System of Units.
virtual ~LaeImu()
Destructor.
virtual void getQuaternion(Quaternion &q)
Get the last computed quaternion.
virtual void getImuData(double accel[], double gyro[], double mag[], double rpy[], Quaternion &q)
Get the last sensed, converted, and computed IMU data.
int m_accelRaw[NumOfAxes]
accelerometer raw values
static const uint_t TCmdTimeout
command timeout (usec)
int mspReadRawImu()
Read raw IMU data.
virtual bool isOpen()
Check if IMU serial interface is open.
static const int MspCmdMaxLen
response max len
int receiveRsp(uint_t cmdId, byte_t rspData[], size_t lenData)
uint_t m_uMspVersion
MSP version.
virtual void getMagnetometerData(double mag[])
Get the last read magnetometer values.
virtual int reload(const laelaps::LaeTunes &tunes)
Reload with new tuning parameters.
Board identity structure.
The <b><i>Laelaps</i></b> namespace encapsulates all <b><i>Laelaps</i></b> related constructs...
Laelaps robotic base mobile platform description class interface.
double m_mag[NumOfAxes]
magnetometer (tesla)
virtual ~LaeImuCleanFlight()
Destructor.
const int NumOfAxes
maximum number of axes per sensor component.
uint_t m_uFwVersion
firmware version
Laelaps common utilities.
Laelaps built-in Inertial Measurement Unit class interface.
static const double MspAttitudeRawToDeg
board computed attitude raw value to degreess
virtual void computeQuaternion()
Compute the quaternion from the IMU data.
static const int MspFieldPosDataStart
data start field position
void lockOp()
Lock the extended operation.
virtual int readRawImu()=0
Read sensor raw IMU values.
static const double MspMpu6050RawToG
MPU-6050 acceleration raw value to g's.
int m_magRaw[NumOfAxes]
magnetometer raw values
virtual void compute()
Compute all IMU values form converted, raw values.
static const int MspFieldPosSize
data size field position
int pack32(int val, byte_t buf[])
Pack 32-bit signed value into buffer.
static const uint_t MspCmdIdRawImu
read raw imu data
pthread_mutex_t m_mutexOp
high-level operation mutex
Quaternion m_quaternion
imu orientation (and robot)
virtual void getAttitude(double rpy[])
Get the last read IMU (vehicle) attitude.
bool m_bBlackListed
IMU is [not] black listed.
virtual void exec()
Exectute one step to read, convert, and compute IMU values.
int unpack32(byte_t buf[], int &val)
Unpack 32-bit signed value from buffer.
virtual int readIdentity(std::string &strIdent)
Read sensor identity values.
int mspReadIdent(msp::MspIdent &ident)
Read CleanFlight board's identity values.
virtual int close()
Close connection to motor controller.
virtual int readRawRollPitchYaw()
Read board's calculated roll, pitch, and yaw raw values.
int mspReadAttitude()
MSP command/response.
virtual void getInertiaData(double accel[], double gyro[])
Get the last read and converted inertia data.
static const uint_t MspCmdIdAttitude
read raw attitude data
Laelaps real-time "database".
virtual void whitelist()
White list IMU sensor.
double m_gyro[NumOfAxes]
gyrscope (radians/s)
void convertTaitBryan(double roll, double pitch, double yaw)
Convert Tait-Bryan angles to quaternion.
static const int MspRspMaxLen
response max len
virtual void computeDynamics()
Compute the velocity, position, and any other dynamics from the IMU data.
virtual void blacklist()
Black list IMU from robot sensors.
virtual bool isBlackListed()
Test if IMU is black listed.
std::string m_strDevName
serial device name
std::string getRealDeviceName(const std::string &strDevName)
Get real device name.
int m_rpyRaw[NumOfAxes]
roll,pitch,yaw raw values
Top-level package include file.
static const int MspFieldPosCmdId
command id field position
virtual void getRawInertiaData(int accel[], int gyro[])
Get the last read raw inertia data.
virtual int convertRawToSI()=0
Convert last read IMU values to International System of Units.
void clear()
Clear quaternion values.