00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <iostream>
00033 #include <string>
00034 #include <ros/ros.h>
00035 #include "smi540/smi540.h"
00036 #include "smi540/smi540meas.h"
00037 #include <sstream>
00038 #include <ros/time.h>
00039
00040 Smi540::Smi540():
00041 bSubDeviceOpen (false),
00042 bSubDeviceConfigured (false),
00043 strSerial (" ")
00044 {
00045 int iSpiErr;
00046 int iSPI_cfg_set;
00047 int iSPI_cfg_get;
00048
00049 std::cout << "---opening SUB device---" << " \n";
00050
00051
00052
00053
00054
00055
00056
00057
00058 fd = sub_open(0);
00059
00060 if( fd==0 ) {
00061
00062 ROS_INFO("ERROR - Sub20 could not be opened: %s ", sub_strerror(sub_errno) );
00063 }
00064 else {
00065
00066 bSubDeviceOpen = true;
00067 std::cout << "Device Handle : " << fd << " \n";
00068
00069 if( sub_get_serial_number(fd, const_cast<char*>(strSerial.c_str()), strSerial.size() ) >= 0 )
00070 std::cout << "Serial Number : " << strSerial << std::endl;
00071 std::cout << "---Initializing SPI Interface---" << std::endl;
00072
00073 iSpiErr = sub_spi_config( fd, 0, &iSPI_cfg_get );
00074 std::cout << "Dev Sub config : " << iSPI_cfg_get << " \n";
00075
00076 iSPI_cfg_set = SPI_ENABLE|SPI_CPOL_RISE|SPI_SMPL_SETUP|SPI_MSB_FIRST|SPI_CLK_1MHZ;
00077
00078 iSpiErr = sub_spi_config( fd, iSPI_cfg_set, 0 );
00079
00080 iSpiErr = sub_spi_config( fd, 0, &iSPI_cfg_get );
00081
00082
00083 if (iSPI_cfg_get == iSPI_cfg_set ) {
00084 std::cout<< "Configuration : " << iSPI_cfg_set << " successfully stored \n";
00085
00086 bSubDeviceConfigured = true;
00087 }
00088 else {
00089 std::cout<< "ERROR - Configuration :" << iSPI_cfg_set << " not accept by device \n";
00090
00091 bSubDeviceConfigured = false;
00092 }
00093
00094
00095 if ( bSubDeviceConfigured ) {
00096 std::cout<< "Configuring SMI530 device \n";
00097
00098
00099
00100 iSpiErr = sub_spi_transfer( fd, cmd540::chTRIGGER_RESET, 0, 4, SS_CONF(0,SS_LO) );
00101 };
00102 };
00103 };
00104
00105 Smi540::~Smi540()
00106 {
00107 int iSpiErr;
00108
00109 iSpiErr = sub_spi_config( fd, 0, 0 );
00110
00111 sub_close( fd );
00112
00113 bSubDeviceOpen = false;
00114 bSubDeviceConfigured = false;
00115 };
00116
00117 ONESMI540MEAS Smi540::GetOneMeas(void)
00118 {
00119 char chMM5_rx[8];
00120 int iSpiErr;
00121 ONESMI540MEAS sMeas;
00122 unsigned short smi540health;
00123
00124
00125 sMeas.dRateZ = 0;
00126 sMeas.dAccX = 0;
00127 sMeas.dAccY = 0;
00128 sMeas.bMeasAvailable = false;
00129
00130
00131 if ( bSubDeviceConfigured )
00132 {
00133
00134
00135 iSpiErr = sub_spi_transfer( fd, cmd540::chRD_ACT_DATA_64, 0, 4, SS_CONF(0,SS_LO) );
00136 iSpiErr = sub_spi_transfer( fd, 0, chMM5_rx, 8, SS_CONF(0,SS_LO) );
00137
00138 if (iSpiErr == 0 ) {
00139
00140 sMeas.dRateZ = mm5data_to_int(chMM5_rx[5], chMM5_rx[6], cmd540::eGYRO);
00141 sMeas.dAccX = mm5data_to_int(chMM5_rx[3], chMM5_rx[4], cmd540::eACCEL);
00142 sMeas.dAccY = mm5data_to_int(chMM5_rx[1], chMM5_rx[2], cmd540::eACCEL);
00143 sMeas.bMeasAvailable = true;
00144 sMeas.dtomeas = ros::Time::now();
00145
00146
00147 smi540health = (unsigned short)(chMM5_rx[0]&0x23);
00148 }
00149 else {
00150 throw std::string ("SPI transfer error");
00151
00152 sMeas.bMeasAvailable = false;
00153 }
00154 }
00155 else {
00156
00157 throw std::string ("No SubDevice connected OR access rights to USB not given");
00158
00159 sMeas.bMeasAvailable = false;
00160 }
00161 return (sMeas);
00162 }
00163
00164 double Smi540::mm5data_to_int(char chMSB, char chLSB, cmd540::eSensorType eSensor)
00165 {
00166 short s16int;
00167 double dSensorMeas;
00168
00169 if ( (chMSB & 0x80) == 0 ) {
00170
00171 s16int = (short) ((((unsigned short)chMSB)&0xFF)<<8)+(((unsigned short)chLSB)&0xFF);
00172 }
00173 else {
00174
00175
00176 s16int = (short)(((((unsigned short)chMSB)&0x7F)<<8)+(((unsigned short)chLSB)&0xFF)-32768);
00177 }
00178
00179
00180 if (eSensor == cmd540::eACCEL) {
00181 dSensorMeas = ((double)s16int)/cmd540::fSFACC_inv;
00182 }
00183 else {
00184 dSensorMeas = ((double)s16int)/cmd540::fSFGYRO_inv;
00185 }
00186 return (dSensorMeas);
00187 }
00188
00189
00190
00191
00192 int main(int argc, char **argv)
00193 {
00194 Smi540 one_smi540;
00195 ONESMI540MEAS sOneMeas;
00196 smi540::smi540meas msg;
00197 double dRate_Hz;
00198
00199 ros::init(argc, argv, "smi540");
00200 ros::NodeHandle n;
00201 ros::Publisher smi540_pub = n.advertise<smi540::smi540meas>("smi540", 100);
00202
00203 if (n.getParam("/drivers/smi540/rate_Hz", dRate_Hz) == false ) {
00204 dRate_Hz = cmd540::dDEFAULT_RATE_Hz;
00205 ROS_INFO("Using Default Sensor Sampling Rate of %f [Hz]", dRate_Hz);
00206 };
00207
00208 ros::Rate loop_rate(dRate_Hz);
00209
00210 while (n.ok())
00211 {
00212
00213 try {
00214 sOneMeas = one_smi540.GetOneMeas();
00215 }
00216 catch ( std::string strType ) {
00217 std::cout << " An exception occurred: " << strType << std::endl;
00218 std::exit(1);
00219 }
00220
00221
00222 if ( sOneMeas.bMeasAvailable == true ) {
00223 msg.fAcclX = sOneMeas.dAccX;
00224 msg.fAcclY = sOneMeas.dAccY;
00225 msg.fRateZ = sOneMeas.dRateZ;
00226 msg.header.stamp = sOneMeas.dtomeas;
00227 smi540_pub.publish(msg);
00228 }
00229 ros::spinOnce();
00230 loop_rate.sleep();
00231 }
00232 }