Initial commit
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
cmake_minimum_required(VERSION 2.8.3)
|
||||
project(lpms_ig1_ros)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11")
|
||||
|
||||
find_package(catkin REQUIRED COMPONENTS
|
||||
roscpp
|
||||
std_msgs
|
||||
message_generation
|
||||
)
|
||||
|
||||
|
||||
generate_messages(
|
||||
DEPENDENCIES
|
||||
std_msgs
|
||||
)
|
||||
|
||||
link_directories("${IG1_LIB}")
|
||||
|
||||
set(lpms_ig1_node_SRCS
|
||||
src/lpms_ig1_node.cpp
|
||||
)
|
||||
|
||||
|
||||
|
||||
## Declare a catkin package
|
||||
catkin_package()
|
||||
|
||||
## Build
|
||||
include_directories(include ${catkin_INCLUDE_DIRS})
|
||||
|
||||
# lpms_ig1_node
|
||||
add_executable(lpms_ig1_node ${lpms_ig1_node_SRCS})
|
||||
target_link_libraries(lpms_ig1_node
|
||||
${catkin_LIBRARIES}
|
||||
LpmsIG1_OpenSourceLib.so
|
||||
)
|
||||
add_dependencies(lpms_ig1_node ${catkin_EXPORTED_TARGETS})
|
||||
|
||||
# imudata_rad_to_deg_node
|
||||
add_executable(imudata_rad_to_deg_node src/imudata_rad_to_deg_node.cpp)
|
||||
target_link_libraries(imudata_rad_to_deg_node ${catkin_LIBRARIES})
|
||||
add_dependencies(imudata_rad_to_deg_node ${catkin_EXPORTED_TARGETS})
|
||||
@@ -0,0 +1,21 @@
|
||||
<launch>
|
||||
<!-- IG1 Sensor node -->
|
||||
<node name="lpms_ig1" pkg="lpms_ig1_ros" type="lpms_ig1_node" output="screen">
|
||||
<param name="port" value="/dev/ttyUSB1" type="string" />
|
||||
<param name="baudrate" value="921600" type="int" />
|
||||
<param name="frame_id" value="imu" type="string" />
|
||||
</node>
|
||||
|
||||
<!-- imudata rad to deg conversion node -->
|
||||
<node name="imudata_deg" pkg="lpms_ig1_ros" type="imudata_rad_to_deg_node" />
|
||||
|
||||
<!-- Plots -->
|
||||
<!-- <node name="plot_imu_gyro" pkg="rqt_plot" type="rqt_plot"
|
||||
args="/angular_vel_deg" /> -->
|
||||
|
||||
<!-- <node name="plot_imu_euler" pkg="rqt_plot" type="rqt_plot"
|
||||
args="/rpy_deg" /> -->
|
||||
|
||||
<!-- <node name="plot_acc" pkg="rqt_plot" type="rqt_plot"
|
||||
args="/acc_vector" /> -->
|
||||
</launch>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0"?>
|
||||
<package format="2">
|
||||
<name>lpms_ig1_ros</name>
|
||||
<version>0.0.0</version>
|
||||
<description>The lpms_ig1_ros package</description>
|
||||
|
||||
<!-- One maintainer tag required, multiple allowed, one person per tag -->
|
||||
<!-- Example: -->
|
||||
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
|
||||
<maintainer email="buaazs17@163.com">zhangshu</maintainer>
|
||||
|
||||
|
||||
<!-- One license tag required, multiple allowed, one license per tag -->
|
||||
<!-- Commonly used license strings: -->
|
||||
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
|
||||
<license>TODO</license>
|
||||
|
||||
|
||||
<!-- Url tags are optional, but multiple are allowed, one per tag -->
|
||||
<!-- Optional attribute type can be: website, bugtracker, or repository -->
|
||||
<!-- Example: -->
|
||||
<!-- <url type="website">http://wiki.ros.org/lpms_ig1_ros</url> -->
|
||||
|
||||
|
||||
<!-- Author tags are optional, multiple are allowed, one per tag -->
|
||||
<!-- Authors do not have to be maintainers, but could be -->
|
||||
<!-- Example: -->
|
||||
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
|
||||
|
||||
|
||||
<!-- The *depend tags are used to specify dependencies -->
|
||||
<!-- Dependencies can be catkin packages or system dependencies -->
|
||||
<!-- Examples: -->
|
||||
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
|
||||
<!-- <depend>roscpp</depend> -->
|
||||
<!-- Note that this is equivalent to the following: -->
|
||||
<!-- <build_depend>roscpp</build_depend> -->
|
||||
<!-- <exec_depend>roscpp</exec_depend> -->
|
||||
<!-- Use build_depend for packages you need at compile time: -->
|
||||
<!-- <build_depend>message_generation</build_depend> -->
|
||||
<!-- Use build_export_depend for packages you need in order to build against this package: -->
|
||||
<!-- <build_export_depend>message_generation</build_export_depend> -->
|
||||
<!-- Use buildtool_depend for build tool packages: -->
|
||||
<!-- <buildtool_depend>catkin</buildtool_depend> -->
|
||||
<!-- Use exec_depend for packages you need at runtime: -->
|
||||
<!-- <exec_depend>message_runtime</exec_depend> -->
|
||||
<!-- Use test_depend for packages you need only for testing: -->
|
||||
<!-- <test_depend>gtest</test_depend> -->
|
||||
<!-- Use doc_depend for packages you need only for building documentation: -->
|
||||
<!-- <doc_depend>doxygen</doc_depend> -->
|
||||
<buildtool_depend>catkin</buildtool_depend>
|
||||
<build_depend>roscpp</build_depend>
|
||||
<build_depend>sensor_msgs</build_depend>
|
||||
<build_depend>std_msgs</build_depend>
|
||||
|
||||
<build_export_depend>roscpp</build_export_depend>
|
||||
<build_export_depend>sensor_msgs</build_export_depend>
|
||||
<build_export_depend>sensor_msgs</build_export_depend>
|
||||
|
||||
<exec_depend>roscpp</exec_depend>
|
||||
<exec_depend>sensor_msgs</exec_depend>
|
||||
<exec_depend>std_msgs</exec_depend>
|
||||
|
||||
|
||||
<!-- The export tag contains other, unspecified, tags -->
|
||||
<export>
|
||||
<!-- Other tools can request additional information be placed here -->
|
||||
|
||||
</export>
|
||||
</package>
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "ros/ros.h"
|
||||
#include "sensor_msgs/Imu.h"
|
||||
#include <iostream>
|
||||
#include <tf/transform_datatypes.h>
|
||||
|
||||
ros::Publisher angular_vel_deg_publisher;
|
||||
ros::Publisher acc_publisher;
|
||||
ros::Publisher rpy_deg_publisher;
|
||||
ros::Subscriber imudata_subscriber;
|
||||
|
||||
const float r2d = 57.29577951f;
|
||||
|
||||
void MsgCallback(const sensor_msgs::Imu::ConstPtr& msg)
|
||||
{
|
||||
|
||||
geometry_msgs::Vector3 angular_vel;
|
||||
angular_vel.x = msg->angular_velocity.x*r2d;
|
||||
angular_vel.y = msg->angular_velocity.y*r2d;
|
||||
angular_vel.z = msg->angular_velocity.z*r2d;
|
||||
|
||||
angular_vel_deg_publisher.publish(angular_vel);
|
||||
|
||||
geometry_msgs::Vector3 acc_data;
|
||||
acc_data.x = msg->linear_acceleration.y;
|
||||
// acc_data.y = msg->linear_acceleration.x;
|
||||
// acc_data.z = msg->linear_acceleration.z;
|
||||
acc_publisher.publish(acc_data);
|
||||
|
||||
|
||||
tf::Quaternion q(msg->orientation.x, msg->orientation.y, msg->orientation.z, msg->orientation.w);
|
||||
tf::Matrix3x3 m(q);
|
||||
double roll, pitch, yaw;
|
||||
m.getRPY(roll, pitch, yaw);
|
||||
|
||||
geometry_msgs::Vector3 rpy;
|
||||
rpy.x = roll*r2d;
|
||||
rpy.y = pitch*r2d;
|
||||
rpy.z = yaw*r2d;
|
||||
|
||||
rpy_deg_publisher.publish(rpy);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ros::init(argc, argv, "imu_listener");
|
||||
ros::NodeHandle n;
|
||||
angular_vel_deg_publisher = n.advertise<geometry_msgs::Vector3>("angular_vel_deg", 1000);
|
||||
rpy_deg_publisher = n.advertise<geometry_msgs::Vector3>("rpy_deg", 1000);
|
||||
acc_publisher = n.advertise<geometry_msgs::Vector3>("/acc_vector", 1000);
|
||||
imudata_subscriber = n.subscribe("/imu/data", 1000, MsgCallback);
|
||||
|
||||
ROS_INFO("waiting for imu data");
|
||||
ros::spin();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
|
||||
#include <string>
|
||||
#include "ros/ros.h"
|
||||
#include "sensor_msgs/Imu.h"
|
||||
#include "sensor_msgs/MagneticField.h"
|
||||
#include "std_srvs/SetBool.h"
|
||||
#include "std_srvs/Trigger.h"
|
||||
#include "std_msgs/Bool.h"
|
||||
|
||||
#include "lpsensor/LpmsIG1I.h"
|
||||
#include "lpsensor/SensorDataI.h"
|
||||
#include "lpsensor/LpmsIG1Registers.h"
|
||||
|
||||
struct IG1Command
|
||||
{
|
||||
short command;
|
||||
union Data {
|
||||
uint32_t i[64];
|
||||
float f[64];
|
||||
unsigned char c[256];
|
||||
} data;
|
||||
int dataLength;
|
||||
};
|
||||
|
||||
class LpIG1Proxy
|
||||
{
|
||||
public:
|
||||
// Node handler
|
||||
ros::NodeHandle nh, private_nh;
|
||||
ros::Timer updateTimer;
|
||||
|
||||
// Publisher
|
||||
ros::Publisher imu_pub;
|
||||
ros::Publisher mag_pub;
|
||||
ros::Publisher autocalibration_status_pub;
|
||||
|
||||
// Service
|
||||
ros::ServiceServer autocalibration_serv;
|
||||
ros::ServiceServer autoReconnect_serv;
|
||||
ros::ServiceServer gyrocalibration_serv;
|
||||
ros::ServiceServer resetHeading_serv;
|
||||
ros::ServiceServer getImuData_serv;
|
||||
ros::ServiceServer setStreamingMode_serv;
|
||||
ros::ServiceServer setCommandMode_serv;
|
||||
|
||||
sensor_msgs::Imu imu_msg;
|
||||
sensor_msgs::MagneticField mag_msg;
|
||||
|
||||
// Parameters
|
||||
std::string comportNo;
|
||||
int baudrate;
|
||||
bool autoReconnect;
|
||||
std::string frame_id;
|
||||
int rate;
|
||||
|
||||
LpIG1Proxy(ros::NodeHandle h) :
|
||||
nh(h),
|
||||
private_nh("~")
|
||||
{
|
||||
// Get node parameters
|
||||
private_nh.param<std::string>("port", comportNo, "/dev/ttyUSB0");
|
||||
private_nh.param("baudrate", baudrate, 921600);
|
||||
private_nh.param("autoreconnect", autoReconnect, true);
|
||||
private_nh.param<std::string>("frame_id", frame_id, "imu");
|
||||
private_nh.param("rate", rate, 200);
|
||||
|
||||
// Create LpmsIG1 object
|
||||
sensor1 = IG1Factory();
|
||||
sensor1->setVerbose(VERBOSE_INFO);
|
||||
sensor1->setAutoReconnectStatus(autoReconnect);
|
||||
|
||||
ROS_INFO("Settings");
|
||||
ROS_INFO("Port: %s", comportNo.c_str());
|
||||
ROS_INFO("Baudrate: %d", baudrate);
|
||||
ROS_INFO("Auto reconnect: %s", autoReconnect? "Enabled":"Disabled");
|
||||
|
||||
imu_pub = nh.advertise<sensor_msgs::Imu>("data",1);
|
||||
mag_pub = nh.advertise<sensor_msgs::MagneticField>("mag",1);
|
||||
autocalibration_status_pub = nh.advertise<std_msgs::Bool>("is_autocalibration_active", 1, true);
|
||||
|
||||
autocalibration_serv = nh.advertiseService("enable_gyro_autocalibration", &LpIG1Proxy::setAutocalibration, this);
|
||||
autoReconnect_serv = nh.advertiseService("enable_auto_reconnect", &LpIG1Proxy::setAutoReconnect, this);
|
||||
gyrocalibration_serv = nh.advertiseService("calibrate_gyroscope", &LpIG1Proxy::calibrateGyroscope, this);
|
||||
resetHeading_serv = nh.advertiseService("reset_heading", &LpIG1Proxy::resetHeading, this);
|
||||
getImuData_serv = nh.advertiseService("get_imu_data", &LpIG1Proxy::getImuData, this);
|
||||
setStreamingMode_serv = nh.advertiseService("set_streaming_mode", &LpIG1Proxy::setStreamingMode, this);
|
||||
setCommandMode_serv = nh.advertiseService("set_command_mode", &LpIG1Proxy::setCommandMode, this);
|
||||
|
||||
// Connects to sensor
|
||||
if (!sensor1->connect(comportNo, baudrate))
|
||||
{
|
||||
ROS_ERROR("Error connecting to sensor\n");
|
||||
sensor1->release();
|
||||
ros::Duration(3).sleep(); // sleep 3 s
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
ROS_INFO("Waiting for sensor to connect %d", sensor1->getStatus());
|
||||
ros::Duration(1).sleep();
|
||||
} while(
|
||||
ros::ok() &&
|
||||
(
|
||||
!(sensor1->getStatus() == STATUS_CONNECTED) &&
|
||||
!(sensor1->getStatus() == STATUS_CONNECTION_ERROR)
|
||||
)
|
||||
);
|
||||
|
||||
if (sensor1->getStatus() == STATUS_CONNECTED)
|
||||
{
|
||||
ROS_INFO("Sensor connected");
|
||||
ros::Duration(1).sleep();
|
||||
sensor1->commandGotoStreamingMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
ROS_INFO("Sensor connection error: %d.", sensor1->getStatus());
|
||||
ros::shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
~LpIG1Proxy(void)
|
||||
{
|
||||
sensor1->release();
|
||||
}
|
||||
|
||||
void update(const ros::TimerEvent& te)
|
||||
{
|
||||
static bool runOnce = false;
|
||||
|
||||
if (sensor1->getStatus() == STATUS_CONNECTED &&
|
||||
sensor1->hasImuData())
|
||||
{
|
||||
if (!runOnce)
|
||||
{
|
||||
publishIsAutocalibrationActive();
|
||||
runOnce = true;
|
||||
}
|
||||
IG1ImuDataI sd;
|
||||
sensor1->getImuData(sd);
|
||||
|
||||
/* Fill the IMU message */
|
||||
|
||||
// Fill the header
|
||||
imu_msg.header.stamp = ros::Time::now();
|
||||
imu_msg.header.frame_id = frame_id;
|
||||
|
||||
// Fill orientation quaternion
|
||||
imu_msg.orientation.w = sd.quaternion.data[0];
|
||||
imu_msg.orientation.x = -sd.quaternion.data[1];
|
||||
imu_msg.orientation.y = -sd.quaternion.data[2];
|
||||
imu_msg.orientation.z = -sd.quaternion.data[3];
|
||||
|
||||
// Fill angular velocity data
|
||||
// - scale from deg/s to rad/s
|
||||
imu_msg.angular_velocity.x = sd.gyroIAlignmentCalibrated.data[0]*3.1415926/180;
|
||||
imu_msg.angular_velocity.y = sd.gyroIAlignmentCalibrated.data[1]*3.1415926/180;
|
||||
imu_msg.angular_velocity.z = sd.gyroIAlignmentCalibrated.data[2]*3.1415926/180;
|
||||
|
||||
// Fill linear acceleration data
|
||||
imu_msg.linear_acceleration.x = -sd.accCalibrated.data[0]*9.81;
|
||||
imu_msg.linear_acceleration.y = -sd.accCalibrated.data[1]*9.81;
|
||||
imu_msg.linear_acceleration.z = -sd.accCalibrated.data[2]*9.81;
|
||||
|
||||
/* Fill the magnetometer message */
|
||||
mag_msg.header.stamp = imu_msg.header.stamp;
|
||||
mag_msg.header.frame_id = frame_id;
|
||||
|
||||
// Units are microTesla in the LPMS library, Tesla in ROS.
|
||||
mag_msg.magnetic_field.x = sd.magRaw.data[0]*1e-6;
|
||||
mag_msg.magnetic_field.y = sd.magRaw.data[1]*1e-6;
|
||||
mag_msg.magnetic_field.z = sd.magRaw.data[2]*1e-6;
|
||||
|
||||
// Publish the messages
|
||||
imu_pub.publish(imu_msg);
|
||||
mag_pub.publish(mag_msg);
|
||||
}
|
||||
}
|
||||
|
||||
void run(void)
|
||||
{
|
||||
// The timer ensures periodic data publishing
|
||||
updateTimer = ros::Timer(nh.createTimer(ros::Duration(1.0f/rate),
|
||||
&LpIG1Proxy::update,
|
||||
this));
|
||||
}
|
||||
|
||||
void publishIsAutocalibrationActive()
|
||||
{
|
||||
std_msgs::Bool msg;
|
||||
IG1SettingsI settings;
|
||||
sensor1->getSettings(settings);
|
||||
msg.data = settings.enableGyroAutocalibration;
|
||||
autocalibration_status_pub.publish(msg);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Service Callbacks
|
||||
///////////////////////////////////////////////////
|
||||
bool setAutocalibration (std_srvs::SetBool::Request &req, std_srvs::SetBool::Response &res)
|
||||
{
|
||||
ROS_INFO("set_autocalibration");
|
||||
|
||||
// clear current settings
|
||||
IG1SettingsI settings;
|
||||
sensor1->getSettings(settings);
|
||||
|
||||
// Send command
|
||||
cmdSetEnableAutocalibration(req.data);
|
||||
ros::Duration(0.2).sleep();
|
||||
cmdGetEnableAutocalibration();
|
||||
ros::Duration(0.1).sleep();
|
||||
|
||||
double retryElapsedTime = 0;
|
||||
int retryCount = 0;
|
||||
while (!sensor1->hasSettings())
|
||||
{
|
||||
ros::Duration(0.1).sleep();
|
||||
ROS_INFO("set_autocalibration wait");
|
||||
|
||||
retryElapsedTime += 0.1;
|
||||
if (retryElapsedTime > 2.0)
|
||||
{
|
||||
retryElapsedTime = 0;
|
||||
cmdGetEnableAutocalibration();
|
||||
retryCount++;
|
||||
}
|
||||
|
||||
if (retryCount > 5)
|
||||
break;
|
||||
}
|
||||
ROS_INFO("set_autocalibration done");
|
||||
|
||||
// Get settings
|
||||
sensor1->getSettings(settings);
|
||||
|
||||
std::string msg;
|
||||
if (settings.enableGyroAutocalibration == req.data)
|
||||
{
|
||||
res.success = true;
|
||||
msg.append(std::string("[Success] autocalibration status set to: ") + (settings.enableGyroAutocalibration?"True":"False"));
|
||||
}
|
||||
else
|
||||
{
|
||||
res.success = false;
|
||||
msg.append(std::string("[Failed] current autocalibration status set to: ") + (settings.enableGyroAutocalibration?"True":"False"));
|
||||
}
|
||||
|
||||
ROS_INFO("%s", msg.c_str());
|
||||
res.message = msg;
|
||||
|
||||
publishIsAutocalibrationActive();
|
||||
return res.success;
|
||||
}
|
||||
|
||||
// Auto reconnect
|
||||
bool setAutoReconnect (std_srvs::SetBool::Request &req, std_srvs::SetBool::Response &res)
|
||||
{
|
||||
ROS_INFO("set_auto_reconnect");
|
||||
|
||||
sensor1->setAutoReconnectStatus(req.data);
|
||||
|
||||
res.success = true;
|
||||
std::string msg;
|
||||
msg.append(std::string("[Success] auto reconnection status set to: ") + (sensor1->getAutoReconnectStatus()?"True":"False"));
|
||||
|
||||
ROS_INFO("%s", msg.c_str());
|
||||
res.message = msg;
|
||||
|
||||
return res.success;
|
||||
}
|
||||
|
||||
// reset heading
|
||||
bool resetHeading (std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
|
||||
{
|
||||
ROS_INFO("reset_heading");
|
||||
|
||||
// Send command
|
||||
cmdResetHeading();
|
||||
|
||||
res.success = true;
|
||||
res.message = "[Success] Heading reset";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool calibrateGyroscope (std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
|
||||
{
|
||||
ROS_INFO("calibrate_gyroscope: Please make sure the sensor is stationary for 4 seconds");
|
||||
|
||||
cmdCalibrateGyroscope();
|
||||
|
||||
ros::Duration(4).sleep();
|
||||
res.success = true;
|
||||
res.message = "[Success] Gyroscope calibration procedure completed";
|
||||
ROS_INFO("calibrate_gyroscope: Gyroscope calibration procedure completed");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getImuData (std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
|
||||
{
|
||||
cmdGotoCommandMode();
|
||||
ros::Duration(0.1).sleep();
|
||||
cmdGetImuData();
|
||||
res.success = true;
|
||||
res.message = "[Success] Get imu data";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool setStreamingMode (std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
|
||||
{
|
||||
cmdGotoStreamingMode();
|
||||
res.success = true;
|
||||
res.message = "[Success] Set streaming mode";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool setCommandMode (std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
|
||||
{
|
||||
cmdGotoCommandMode();
|
||||
res.success = true;
|
||||
res.message = "[Success] Set command mode";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Helpers
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
void cmdGotoCommandMode ()
|
||||
{
|
||||
IG1Command cmd;
|
||||
cmd.command = GOTO_COMMAND_MODE;
|
||||
cmd.dataLength = 0;
|
||||
sensor1->sendCommand(cmd.command, cmd.dataLength, cmd.data.c);
|
||||
}
|
||||
|
||||
void cmdGotoStreamingMode ()
|
||||
{
|
||||
IG1Command cmd;
|
||||
cmd.command = GOTO_STREAM_MODE;
|
||||
cmd.dataLength = 0;
|
||||
sensor1->sendCommand(cmd.command, cmd.dataLength, cmd.data.c);
|
||||
}
|
||||
|
||||
void cmdGetImuData()
|
||||
{
|
||||
IG1Command cmd;
|
||||
cmd.command = GET_IMU_DATA;
|
||||
cmd.dataLength = 0;
|
||||
sensor1->sendCommand(cmd.command, cmd.dataLength, cmd.data.c);
|
||||
}
|
||||
|
||||
void cmdCalibrateGyroscope()
|
||||
{
|
||||
IG1Command cmd;
|
||||
cmd.command = START_GYR_CALIBRATION;
|
||||
cmd.dataLength = 0;
|
||||
sensor1->sendCommand(cmd.command, cmd.dataLength, cmd.data.c);
|
||||
}
|
||||
|
||||
void cmdResetHeading()
|
||||
{
|
||||
IG1Command cmd;
|
||||
cmd.command = SET_ORIENTATION_OFFSET;
|
||||
cmd.dataLength = 4;
|
||||
cmd.data.i[0] = LPMS_OFFSET_MODE_HEADING;
|
||||
sensor1->sendCommand(cmd.command, cmd.dataLength, cmd.data.c);
|
||||
}
|
||||
|
||||
void cmdSetEnableAutocalibration(int status)
|
||||
{
|
||||
IG1Command cmd;
|
||||
cmd.command = SET_ENABLE_GYR_AUTOCALIBRATION;
|
||||
cmd.dataLength = 4;
|
||||
cmd.data.i[0] = status;
|
||||
sensor1->sendCommand(cmd.command, cmd.dataLength, cmd.data.c);
|
||||
}
|
||||
|
||||
void cmdGetEnableAutocalibration()
|
||||
{
|
||||
IG1Command cmd;
|
||||
cmd.command = GET_ENABLE_GYR_AUTOCALIBRATION;
|
||||
cmd.dataLength = 0;
|
||||
sensor1->sendCommand(cmd.command, cmd.dataLength, cmd.data.c);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Access to LPMS data
|
||||
IG1I* sensor1;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
ros::init(argc, argv, "lpms_ig1_node");
|
||||
ros::NodeHandle nh("imu");
|
||||
|
||||
ros::AsyncSpinner spinner(0);
|
||||
spinner.start();
|
||||
|
||||
LpIG1Proxy lpIG1(nh);
|
||||
|
||||
lpIG1.run();
|
||||
ros::waitForShutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
#include "ros/ros.h"
|
||||
#include "sensor_msgs/Imu.h"
|
||||
#include <iostream>
|
||||
#include <tf/transform_datatypes.h>
|
||||
|
||||
ros::Publisher rpy_publisher;
|
||||
ros::Subscriber quat_subscriber;
|
||||
|
||||
const float r2d = 57.29577951f;
|
||||
|
||||
void MsgCallback(const sensor_msgs::Imu::ConstPtr& msg)
|
||||
{
|
||||
tf::Quaternion q(msg->orientation.x, msg->orientation.y, msg->orientation.z, msg->orientation.w);
|
||||
tf::Matrix3x3 m(q);
|
||||
double roll, pitch, yaw;
|
||||
m.getRPY(roll, pitch, yaw);
|
||||
|
||||
geometry_msgs::Vector3 rpy;
|
||||
rpy.x = roll;
|
||||
rpy.y = pitch;
|
||||
rpy.z = yaw;
|
||||
|
||||
rpy_publisher.publish(rpy);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ros::init(argc, argv, "imu_listener");
|
||||
ros::NodeHandle n;
|
||||
rpy_publisher = n.advertise<geometry_msgs::Vector3>("rpy_angles", 1000);
|
||||
quat_subscriber = n.subscribe("/imu/data", 1000, MsgCallback);
|
||||
|
||||
ROS_INFO("waiting for imu data");
|
||||
ros::spin();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user