TestBotaDriverSignalQualityImu.cpp
Go to the documentation of this file.
1 
7 #include <gtest/gtest.h>
8 #include <sensor_msgs/Imu.h>
9 #include <Eigen/Dense>
10 #include <ros/ros.h>
11 
12 #define G_TO_METERS_PER_SECOND_SQUARED 9.80665
13 using namespace Eigen;
14 namespace bota_driver_testing
15 {
16 class BotaDriverSignalQualityImu : public ::testing::Test
17 {
18 protected:
20  ros::NodeHandle nh_{ "~" };
21  std::uint32_t msgCount_;
22  std::uint32_t maxCount_;
23  std::string topicName_;
24  VectorXd linAccXSamples_;
25  VectorXd linAccYSamples_;
26  VectorXd linAccZSamples_;
27  VectorXd angVelXSamples_;
28  VectorXd angVelYSamples_;
29  VectorXd angVelZSamples_;
31 
32  BotaDriverSignalQualityImu() : msgCount_(0), maxCount_(1000)
33  {
34  }
35 
37  {
38  // You can do clean-up work that doesn't throw exceptions here.
39  }
40 
41  // If the constructor and destructor are not enough for setting up
42  // and cleaning up each test, you can define the following methods:
43 
44  void SetUp() override
45  {
46  // Code here will be called immediately after the constructor (right
47  // before each test).
48  }
49 
50  void TearDown() override
51  {
52  // Code here will be called immediately after each test (right
53  // before the destructor).
54  }
55 
56 public:
57  void imuCallback(const sensor_msgs::Imu::ConstPtr& msg)
58  {
59  std::uint32_t lpos = msgCount_;
60  msgCount_++;
61  linAccXSamples_.conservativeResize(msgCount_);
62  linAccYSamples_.conservativeResize(msgCount_);
63  linAccZSamples_.conservativeResize(msgCount_);
64  angVelXSamples_.conservativeResize(msgCount_);
65  angVelYSamples_.conservativeResize(msgCount_);
66  angVelZSamples_.conservativeResize(msgCount_);
67 
68  linAccXSamples_(lpos) = msg->linear_acceleration.x;
69  linAccYSamples_(lpos) = msg->linear_acceleration.y;
70  linAccZSamples_(lpos) = msg->linear_acceleration.z;
71  angVelXSamples_(lpos) = msg->angular_velocity.x;
72  angVelYSamples_(lpos) = msg->angular_velocity.y;
73  angVelZSamples_(lpos) = msg->angular_velocity.z;
74  }
75 };
76 
78 {
79  SCOPED_TRACE("SignalQualityImu");
80  ros::Time time_offset;
81  ASSERT_EQ(nh_.getParam("topic_name", topicName_), true);
82  sub_ = nh_.subscribe(topicName_, 1, &BotaDriverSignalQualityImu::imuCallback, (BotaDriverSignalQualityImu*)this,
83  ros::TransportHints().tcpNoDelay());
84  ASSERT_EQ(nh_.getParam("test_duration", testDuration_), true);
85  time_offset = ros::Time::now() + ros::Duration(testDuration_);
86  while (ros::ok() && ros::Time::now() < time_offset && msgCount_ < maxCount_)
87  {
88  ros::spinOnce();
89  if (HasFatalFailure())
90  {
91  FAIL() << "Fatal errors occurred.\n";
92  return;
93  }
94  }
95 
96  EXPECT_GT(msgCount_, 0U);
97  double linacc_xsamples_mean, linacc_ysamples_mean, linacc_zsamples_mean, angvel_xsamples_mean, angvel_ysamples_mean,
98  angvel_zsamples_mean, linacc_mean, angvel_mean;
99  linacc_xsamples_mean = linAccXSamples_.mean();
100  linacc_ysamples_mean = linAccYSamples_.mean();
101  linacc_zsamples_mean = linAccZSamples_.mean();
102  // compute the mean of linear acceleration.
103  linacc_mean = std::sqrt(std::pow(linacc_xsamples_mean, 2) + std::pow(linacc_ysamples_mean, 2) +
104  std::pow(linacc_zsamples_mean, 2));
105  angvel_xsamples_mean = angVelXSamples_.mean();
106  angvel_ysamples_mean = angVelYSamples_.mean();
107  angvel_zsamples_mean = angVelZSamples_.mean();
108  // compute the mean of the angular velocities.
109  angvel_mean = std::sqrt(std::pow(angvel_xsamples_mean, 2) + std::pow(angvel_ysamples_mean, 2) +
110  std::pow(angvel_zsamples_mean, 2));
111  linAccXSamples_ = linAccXSamples_.array() - linAccXSamples_.mean();
112  double sigma_ax = std::sqrt(linAccXSamples_.squaredNorm() / msgCount_);
113  linAccYSamples_ = linAccYSamples_.array() - linAccYSamples_.mean();
114  double sigma_ay = std::sqrt(linAccYSamples_.squaredNorm() / msgCount_);
115  linAccZSamples_ = linAccZSamples_.array() - linAccZSamples_.mean();
116  double sigma_az = std::sqrt(linAccZSamples_.squaredNorm() / msgCount_);
117  angVelXSamples_ = angVelXSamples_.array() - angVelXSamples_.mean();
118  double sigma_vx = std::sqrt(angVelXSamples_.squaredNorm() / msgCount_);
119  angVelYSamples_ = angVelYSamples_.array() - angVelYSamples_.mean();
120  double sigma_vy = std::sqrt(angVelYSamples_.squaredNorm() / msgCount_);
121  angVelZSamples_ = angVelZSamples_.array() - angVelZSamples_.mean();
122  double sigma_vz = std::sqrt(angVelZSamples_.squaredNorm() / msgCount_);
123 
124  double max_sigma_axy, max_sigma_az, max_sigma_vxy, max_sigma_vz, mean_dev_lin_acc, mean_dev_ang_vel;
125  ASSERT_EQ(nh_.getParam("max_sigma_axy", max_sigma_axy), true);
126  ASSERT_EQ(nh_.getParam("max_sigma_az", max_sigma_az), true);
127  ASSERT_EQ(nh_.getParam("max_sigma_vxy", max_sigma_vxy), true);
128  ASSERT_EQ(nh_.getParam("max_sigma_vz", max_sigma_vz), true);
129  ASSERT_EQ(nh_.getParam("mean_dev_lin_acc", mean_dev_lin_acc), true);
130  ASSERT_EQ(nh_.getParam("mean_dev_ang_vel", mean_dev_ang_vel), true);
131 
132  // Assert mean linear acceleration is close to 1g and mean angular velocity close to 0.
133  ASSERT_NEAR(linacc_mean, 1.0 * G_TO_METERS_PER_SECOND_SQUARED, mean_dev_lin_acc);
134  ASSERT_NEAR(angvel_mean, 0.0, mean_dev_ang_vel);
135 
136  // Compute standard deviation of the signal.
137  ASSERT_GT(sigma_ax, 1e-7);
138  ASSERT_GT(sigma_ay, 1e-7);
139  ASSERT_GT(sigma_az, 1e-7);
140  ASSERT_GT(sigma_vx, 1e-7);
141  ASSERT_GT(sigma_vy, 1e-7);
142  ASSERT_GT(sigma_vz, 1e-7);
143  ASSERT_LT(sigma_ax, max_sigma_axy);
144  ASSERT_LT(sigma_ay, max_sigma_axy);
145  ASSERT_LT(sigma_az, max_sigma_az);
146  ASSERT_LT(sigma_vx, max_sigma_vxy);
147  ASSERT_LT(sigma_vy, max_sigma_vxy);
148  ASSERT_LT(sigma_vz, max_sigma_vz);
149 }
150 
151 } // namespace bota_driver_testing
#define G_TO_METERS_PER_SECOND_SQUARED
Tests Command.
Tests Command.
TEST_F(BotaDriverSignalQualityImu, SignalQuality)
ROSCPP_DECL bool ok()
void imuCallback(const sensor_msgs::Imu::ConstPtr &msg)
static Time now()
ROSCPP_DECL void spinOnce()


bota_driver_testing
Author(s):
autogenerated on Sat Apr 15 2023 02:51:37