Skip to content

Commit 7e00759

Browse files
kristkisclaude
andauthored
rviz_imu_plugin: fix invisible-arrow and stale-direction bugs in ImuAccVisual (#226)
Bugs fixed in this commit: * Invisible acceleration arrow for raw-IMU publishers that don't estimate orientation (issues #86, #219 likely root cause). * "Derotate Acceleration" checkbox didn't visibly change the arrow until a new message arrived. , Aliensense Signed-off-by: kristkis <kisyuk.kristina@gmail.com> , Aliensense Signed-off-by: Claude <noreply@anthropic.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 00cc74b commit 7e00759

2 files changed

Lines changed: 67 additions & 16 deletions

File tree

rviz_imu_plugin/src/imu_acc_visual.cpp

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,18 @@
3232
#include <OgreSceneManager.h>
3333

3434
#include "imu_acc_visual.h"
35+
36+
#include <cmath>
37+
#include <rclcpp/rclcpp.hpp>
38+
#include <rviz_common/logging.hpp>
3539
#include <rviz_rendering/objects/arrow.hpp>
3640

3741
namespace rviz_imu_plugin {
3842

3943
ImuAccVisual::ImuAccVisual(Ogre::SceneManager* scene_manager,
4044
Ogre::SceneNode* parent_node)
4145
: acc_vector_(NULL),
46+
quat_valid_(true),
4247
arrow_length_(9.81),
4348
arrow_radius_(0.50),
4449
head_length_(1.00),
@@ -92,25 +97,46 @@ void ImuAccVisual::hide()
9297

9398
void ImuAccVisual::setMessage(const sensor_msgs::msg::Imu::ConstSharedPtr msg)
9499
{
95-
direction_ =
100+
raw_acc_ =
96101
Ogre::Vector3(msg->linear_acceleration.x, msg->linear_acceleration.y,
97102
msg->linear_acceleration.z);
103+
arrow_length_ = raw_acc_.length();
98104

99-
// Rotate the acceleration vector by the IMU orientation. This makes
100-
// sense since the visualization of the IMU is also rotated by the
101-
// orientation. In this way, both appear in the inertial frame.
102-
if (derotated_)
105+
if (checkQuaternionValidity(msg))
103106
{
104-
Ogre::Quaternion orientation(msg->orientation.w, msg->orientation.x,
105-
msg->orientation.y, msg->orientation.z);
106-
107-
direction_ = orientation * direction_;
107+
if (!quat_valid_)
108+
{
109+
RVIZ_COMMON_LOG_INFO_STREAM(
110+
"rviz_imu_plugin got valid quaternion, "
111+
"applying acceleration derotation");
112+
quat_valid_ = true;
113+
}
114+
orientation_ = Ogre::Quaternion(msg->orientation.w, msg->orientation.x,
115+
msg->orientation.y, msg->orientation.z);
116+
} else
117+
{
118+
if (quat_valid_)
119+
{
120+
RVIZ_COMMON_LOG_WARNING_STREAM(
121+
"rviz_imu_plugin got invalid quaternion ("
122+
<< msg->orientation.w << "," << msg->orientation.x << ","
123+
<< msg->orientation.y << "," << msg->orientation.z
124+
<< "); skipping acceleration derotation");
125+
quat_valid_ = false;
126+
}
127+
orientation_ = Ogre::Quaternion();
108128
}
109129

110-
arrow_length_ =
111-
sqrt(msg->linear_acceleration.x * msg->linear_acceleration.x +
112-
msg->linear_acceleration.y * msg->linear_acceleration.y +
113-
msg->linear_acceleration.z * msg->linear_acceleration.z);
130+
updateDirection();
131+
}
132+
133+
void ImuAccVisual::updateDirection()
134+
{
135+
direction_ = raw_acc_;
136+
if (derotated_ && quat_valid_)
137+
{
138+
direction_ = orientation_ * direction_;
139+
}
114140

115141
if (acc_vector_)
116142
{
@@ -150,9 +176,7 @@ void ImuAccVisual::setAlpha(float alpha)
150176
void ImuAccVisual::setDerotated(bool derotated)
151177
{
152178
derotated_ = derotated;
153-
if (acc_vector_)
154-
acc_vector_->setColor(color_.redF(), color_.greenF(), color_.blueF(),
155-
alpha_);
179+
updateDirection();
156180
}
157181

158182
void ImuAccVisual::setFramePosition(const Ogre::Vector3& position)
@@ -165,4 +189,23 @@ void ImuAccVisual::setFrameOrientation(const Ogre::Quaternion& orientation)
165189
frame_node_->setOrientation(orientation);
166190
}
167191

192+
bool ImuAccVisual::checkQuaternionValidity(
193+
const sensor_msgs::msg::Imu::ConstSharedPtr msg)
194+
{
195+
// REP-145: orientation_covariance[0] == -1 signals "not estimated".
196+
if (msg->orientation_covariance[0] == -1.0)
197+
{
198+
return false;
199+
}
200+
double x = msg->orientation.x, y = msg->orientation.y,
201+
z = msg->orientation.z, w = msg->orientation.w;
202+
// Near-zero length indicates the default (0, 0, 0, 0) quaternion,
203+
// which would silently zero out any vector multiplication.
204+
if (std::sqrt(x * x + y * y + z * z + w * w) < 0.0001)
205+
{
206+
return false;
207+
}
208+
return true;
209+
}
210+
168211
} // namespace rviz_imu_plugin

rviz_imu_plugin/src/imu_acc_visual.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,19 @@ class ImuAccVisual
9191

9292
private:
9393
void create();
94+
void updateDirection();
95+
96+
static bool checkQuaternionValidity(
97+
const sensor_msgs::msg::Imu::ConstSharedPtr msg);
9498

9599
rviz_rendering::Arrow* acc_vector_;
96100

97101
Ogre::Vector3 direction_; // computed from IMU message
98102

103+
Ogre::Vector3 raw_acc_;
104+
Ogre::Quaternion orientation_;
105+
bool quat_valid_;
106+
99107
float arrow_length_; // computed from IMU message
100108
float arrow_radius_;
101109
float head_length_;

0 commit comments

Comments
 (0)