diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..751553b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.bak
diff --git a/launch/can.launch b/launch/can.launch
index 9ed5388..267b02c 100755
--- a/launch/can.launch
+++ b/launch/can.launch
@@ -1,7 +1,18 @@
+
+
+
+
+
-
+
+
+
+
+
+
+
diff --git a/package.xml b/package.xml
index 29b0efa..309d643 100644
--- a/package.xml
+++ b/package.xml
@@ -16,6 +16,8 @@
rclcpp_components
can_msgs
sensor_msgs
+ diagnostic_updater
+
ament_cmake
diff --git a/src/tag_can_driver.cpp b/src/tag_can_driver.cpp
index 65cac32..e12fa5e 100755
--- a/src/tag_can_driver.cpp
+++ b/src/tag_can_driver.cpp
@@ -32,33 +32,66 @@
#include "rclcpp/rclcpp.hpp"
#include "can_msgs/msg/frame.hpp"
#include "sensor_msgs/msg/imu.hpp"
+#include "diagnostic_updater/diagnostic_updater.hpp"
+#include
+
+
+using namespace std::chrono_literals;
static unsigned int counter;
static int16_t raw_data;
+static int32_t raw_data2;
+static uint16_t imu_status;
+static bool use_fog;
+static bool use_ros_system;
+static bool ready = false;
+static float cov_x = 0.0;
+static float cov_y = 0.0;
+static float cov_z = 0.0;
+
+static diagnostic_updater::Updater* p_updater;
static sensor_msgs::msg::Imu imu_msg;
rclcpp::Publisher::SharedPtr pub;
+rclcpp::Clock::SharedPtr ros_clock;
void receive_CAN(const can_msgs::msg::Frame::ConstSharedPtr msg){
if(msg->id == 0x319)
{
imu_msg.header.frame_id = "imu";
- imu_msg.header.stamp = rclcpp::Clock(RCL_ROS_TIME).now();
+ imu_msg.header.stamp = msg->header.stamp;
- counter = msg->data[1] + (msg->data[0] << 8);
- raw_data = msg->data[3] + (msg->data[2] << 8);
- imu_msg.angular_velocity.x =
- raw_data * (200 / pow(2, 15)) * M_PI / 180; // LSB & unit [deg/s] => [rad/s]
- raw_data = msg->data[5] + (msg->data[4] << 8);
- imu_msg.angular_velocity.y =
- raw_data * (200 / pow(2, 15)) * M_PI / 180; // LSB & unit [deg/s] => [rad/s]
- raw_data = msg->data[7] + (msg->data[6] << 8);
- imu_msg.angular_velocity.z =
+ if (use_fog)
+ {
+ raw_data = msg->data[1] + (msg->data[0] << 8);
+ imu_msg.angular_velocity.x =
+ raw_data * (200 / pow(2, 15)) * M_PI / 180; // LSB & unit [deg/s] => [rad/s]
+ raw_data = msg->data[3] + (msg->data[2] << 8);
+ imu_msg.angular_velocity.y =
+ raw_data * (200 / pow(2, 15)) * M_PI / 180; // LSB & unit [deg/s] => [rad/s]
+ raw_data2 = (msg->data[7] + (msg->data[6] << 8)) + ((msg->data[5] << 16) + (msg->data[4] << 24));
+ imu_msg.angular_velocity.z =
+ raw_data2 * (200 / pow(2, 31)) * M_PI / 180; // LSB & unit [deg/s] => [rad/s]
+ }
+ else
+ {
+ counter = msg->data[1] + (msg->data[0] << 8);
+ raw_data = msg->data[3] + (msg->data[2] << 8);
+ imu_msg.angular_velocity.x =
+ raw_data * (200 / pow(2, 15)) * M_PI / 180; // LSB & unit [deg/s] => [rad/s]
+ raw_data = msg->data[5] + (msg->data[4] << 8);
+ imu_msg.angular_velocity.y =
+ raw_data * (200 / pow(2, 15)) * M_PI / 180; // LSB & unit [deg/s] => [rad/s]
+ raw_data = msg->data[7] + (msg->data[6] << 8);
+ imu_msg.angular_velocity.z =
raw_data * (200 / pow(2, 15)) * M_PI / 180; // LSB & unit [deg/s] => [rad/s]
+ }
+
}
- if(msg->id == 0x31A)
+ else if(msg->id == 0x31A)
{
+ imu_status = msg->data[1] + (msg->data[0] << 8);
raw_data = msg->data[3] + (msg->data[2] << 8);
imu_msg.linear_acceleration.x = raw_data * (100 / pow(2, 15)); // LSB & unit [m/s^2]
raw_data = msg->data[5] + (msg->data[4] << 8);
@@ -70,16 +103,94 @@ void receive_CAN(const can_msgs::msg::Frame::ConstSharedPtr msg){
imu_msg.orientation.y = 0.0;
imu_msg.orientation.z = 0.0;
imu_msg.orientation.w = 1.0;
+
+ if (use_ros_system)
+ {
+ imu_msg.linear_acceleration.y *= -1.0;
+ imu_msg.linear_acceleration.z *= -1.0;
+ imu_msg.angular_velocity.y *= -1.0;
+ imu_msg.angular_velocity.z *= -1.0;
+ }
+
+ imu_msg.angular_velocity_covariance = {cov_x, 0 , 0,
+ 0, cov_y, 0,
+ 0, 0 , cov_z};
+
pub->publish(imu_msg);
+
+ ready = true;
//std::cout << counter << std::endl;
}
+}
+
+static void check_bit_error(diagnostic_updater::DiagnosticStatusWrapper& stat)
+{
+ uint8_t level = 0; // OK
+ std::string msg = "OK";
+
+ if (imu_status >> 15)
+ {
+ level = 2; // ERROR
+ msg = "Built-In Test error";
+ }
+
+ stat.summary(level, msg);
+}
+
+static void check_connection(diagnostic_updater::DiagnosticStatusWrapper& stat)
+{
+ size_t level = 0; // OK
+ std::string msg = "OK";
+
+ auto now = ros_clock->now();
+
+ if (now - imu_msg.header.stamp > 1s) {
+ level = 2;
+ msg = "Message timeout";
+ }
+ stat.summary(level, msg);
+}
+
+void diagnostic_timer_callback()
+{
+ if(ready)
+ {
+ p_updater->force_update();
+ ready = false;
+ }
}
int main(int argc, char **argv){
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("tag_can_driver");
+ ros_clock = node->get_clock();
+
+ auto diagnostics_timer = rclcpp::create_timer(node,node->get_clock(),1s, &diagnostic_timer_callback);
+
+ node->declare_parameter("use_fog",false);
+ node->declare_parameter("cov_x",0.0);
+ node->declare_parameter("cov_y",0.0);
+ node->declare_parameter("cov_z",0.0);
+ node->declare_parameter("use_ros_system",true);
+ use_fog = node->get_parameter("use_fog").as_bool();
+ cov_x = node->get_parameter("cov_x").as_double();
+ cov_y = node->get_parameter("cov_y").as_double();
+ cov_z = node->get_parameter("cov_z").as_double();
+ use_ros_system = node->get_parameter("use_ros_system").as_bool();
+ RCLCPP_INFO(node->get_logger(), "use_fog: %d", use_fog);
+ RCLCPP_INFO(node->get_logger(), "cov_x: %.4f", cov_x);
+ RCLCPP_INFO(node->get_logger(), "cov_x: %.4f", cov_y);
+ RCLCPP_INFO(node->get_logger(), "cov_x: %.4f", cov_z);
+ RCLCPP_INFO(node->get_logger(), "use_ros_system: %d", use_ros_system);
+
+ diagnostic_updater::Updater updater(node);
+ p_updater = &updater;
+ updater.setHardwareID("tamagawa");
+ updater.add("imu_bit_error", check_bit_error);
+ updater.add("imu_connection", check_connection);
+
rclcpp::Subscription::SharedPtr sub = node->create_subscription("imu/can_tx", 100, receive_CAN);
pub = node->create_publisher("imu/data_raw", 100);
rclcpp::spin(node);
diff --git a/src/tag_serial_driver.cpp b/src/tag_serial_driver.cpp
index 7ab6cc7..28e8c2b 100644
--- a/src/tag_serial_driver.cpp
+++ b/src/tag_serial_driver.cpp
@@ -41,22 +41,78 @@
#include
#include
#include
+#include "diagnostic_updater/diagnostic_updater.hpp"
+#include
using namespace boost::asio;
+using namespace std::chrono_literals;
static std::string device = "/dev/ttyUSB0";
static std::string imu_type = "noGPS";
static std::string rate = "50";
+static bool ready = false;
+static int16_t imu_status;
+static sensor_msgs::msg::Imu imu_msg;
+
+static diagnostic_updater::Updater* p_updater;
+
+static void check_bit_error(diagnostic_updater::DiagnosticStatusWrapper& stat)
+{
+ uint8_t level = 0; // OK
+ std::string msg = "OK";
+
+ if (imu_status >> 15)
+ {
+ level = 2; // ERROR
+ msg = "Built-In Test error";
+ }
+
+ stat.summary(level, msg);
+}
+
+static void check_connection(diagnostic_updater::DiagnosticStatusWrapper& stat)
+{
+ size_t level = 0; // OK
+ std::string msg = "OK";
+
+ auto now = rclcpp::Clock(RCL_ROS_TIME).now();
+
+ if (now - imu_msg.header.stamp > 1s) {
+ level = 2;
+ msg = "Message timeout";
+ }
+
+ stat.summary(level, msg);
+}
+
+static void diagnostic_timer_callback()
+{
+ if(ready)
+ {
+ p_updater->force_update();
+ ready = false;
+ }
+}
+
int main(int argc, char** argv)
{
auto init_options = rclcpp::InitOptions();
- init_options.shutdown_on_sigint = false;
+ init_options.shutdown_on_signal = false;
rclcpp::init(argc, argv, init_options);
std::string node_name = "tag_serial_driver";
auto node = rclcpp::Node::make_shared(node_name);
auto pub = node->create_publisher("imu/data_raw", 100);
+ auto diagnostics_timer = rclcpp::create_timer(node,node->get_clock(),1s, &diagnostic_timer_callback);
+ // auto diagnostics_timer = node->create_wall_timer(1s, &diagnostic_timer_callback);
+
+ diagnostic_updater::Updater updater(node);
+ p_updater = &updater;
+ updater.setHardwareID("tamagawa");
+ updater.add("imu_bit_error", check_bit_error);
+ updater.add("imu_connection", check_connection);
+
io_service io;
// Use configured device
@@ -92,7 +148,6 @@ int main(int argc, char** argv)
serial_port.write_some(buffer(wbuf));
std::cout << "request: " << wbuf << std::endl;
- sensor_msgs::msg::Imu imu_msg;
imu_msg.header.frame_id = "imu";
imu_msg.orientation.x = 0.0;
imu_msg.orientation.y = 0.0;
@@ -117,6 +172,7 @@ int main(int argc, char** argv)
{
counter = ((rbuf[11] << 24) & 0xFF000000) | ((rbuf[12] << 16) & 0x00FF0000) | ((rbuf[13] << 8) & 0x0000FF00) |
(rbuf[14] & 0x000000FF);
+ imu_status = ((rbuf[13] << 8) & 0xFFFFFF00) | (rbuf[14] & 0x000000FF);
raw_data = ((((rbuf[17] << 8) & 0xFFFFFF00) | (rbuf[18] & 0x000000FF)));
imu_msg.angular_velocity.x =
raw_data * (200 / pow(2, 15)) * M_PI / 180; // LSB & unit [deg/s] => [rad/s]
@@ -137,6 +193,7 @@ int main(int argc, char** argv)
else if (strcmp(imu_type.c_str(), "withGPS") == 0)
{
counter = ((rbuf[11] << 8) & 0x0000FF00) | (rbuf[12] & 0x000000FF);
+ imu_status = ((rbuf[13] << 8) & 0xFFFFFF00) | (rbuf[14] & 0x000000FF);
raw_data = ((((rbuf[15] << 8) & 0xFFFFFF00) | (rbuf[16] & 0x000000FF)));
imu_msg.angular_velocity.x =
raw_data * (200 / pow(2, 15)) * M_PI / 180; // LSB & unit [deg/s] => [rad/s]