vulp  2.3.0
bullet_utils.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: Apache-2.0
2 // Copyright 2022 Stéphane Caron
3 
4 #pragma once
5 
6 #include <spdlog/spdlog.h>
7 
8 #include <string>
9 
10 #include "RobotSimulator/b3RobotSimulatorClientAPI.h"
12 
13 namespace vulp::actuation {
14 
21 inline btQuaternion bullet_from_eigen(const Eigen::Quaterniond& quat) {
22  return btQuaternion(quat.x(), quat.y(), quat.z(), quat.w());
23 }
24 
31 inline btVector3 bullet_from_eigen(const Eigen::Vector3d& v) {
32  return btVector3(v.x(), v.y(), v.z());
33 }
34 
41 inline Eigen::Quaterniond eigen_from_bullet(const btQuaternion& quat) {
42  return Eigen::Quaterniond(quat.getW(), quat.getX(), quat.getY(), quat.getZ());
43 }
44 
51 inline Eigen::Vector3d eigen_from_bullet(const btVector3& v) {
52  return Eigen::Vector3d(v.getX(), v.getY(), v.getZ());
53 }
54 
63 inline int find_link_index(b3RobotSimulatorClientAPI& bullet, int robot,
64  const std::string& link_name) noexcept {
65  b3JointInfo joint_info;
66  int nb_joints = bullet.getNumJoints(robot);
67  for (int joint_index = 0; joint_index < nb_joints; ++joint_index) {
68  bullet.getJointInfo(robot, joint_index, &joint_info);
69  if (std::string(joint_info.m_linkName) == link_name) {
70  return joint_index; // link and joint indices are the same in Bullet
71  }
72  }
73  return -1;
74 }
75 
84 inline void read_imu_data(BulletImuData& imu_data,
85  b3RobotSimulatorClientAPI& bullet, int robot,
86  const int imu_link_index, double dt) {
87  b3LinkState link_state;
88  bullet.getLinkState(robot, imu_link_index, /* computeVelocity = */ true,
89  /* computeForwardKinematics = */ true, &link_state);
90 
91  Eigen::Quaterniond orientation_imu_in_world;
92  orientation_imu_in_world.w() = link_state.m_worldLinkFrameOrientation[3];
93  orientation_imu_in_world.x() = link_state.m_worldLinkFrameOrientation[0];
94  orientation_imu_in_world.y() = link_state.m_worldLinkFrameOrientation[1];
95  orientation_imu_in_world.z() = link_state.m_worldLinkFrameOrientation[2];
96 
97  // The attitude reference system frame has +x forward, +y right and +z down,
98  // whereas our world frame has +x forward, +y left and +z up:
99  // https://github.com/mjbots/pi3hat/blob/master/docs/reference.md#orientation
100  Eigen::Matrix3d rotation_world_to_ars =
101  Eigen::Vector3d{1.0, -1.0, -1.0}.asDiagonal();
102 
103  Eigen::Matrix3d rotation_imu_to_world =
104  orientation_imu_in_world.toRotationMatrix();
105  Eigen::Matrix3d rotation_imu_to_ars =
106  rotation_world_to_ars * rotation_imu_to_world;
107  Eigen::Quaterniond orientation_imu_in_ars(rotation_imu_to_ars);
108 
109  Eigen::Vector3d linear_velocity_imu_in_world = {
110  link_state.m_worldLinearVelocity[0],
111  link_state.m_worldLinearVelocity[1],
112  link_state.m_worldLinearVelocity[2],
113  };
114 
115  Eigen::Vector3d angular_velocity_imu_to_world_in_world = {
116  link_state.m_worldAngularVelocity[0],
117  link_state.m_worldAngularVelocity[1],
118  link_state.m_worldAngularVelocity[2],
119  };
120 
121  // Compute linear acceleration in the world frame by discrete differentiation
122  const auto& previous_linear_velocity = imu_data.linear_velocity_imu_in_world;
123  Eigen::Vector3d linear_acceleration_imu_in_world =
124  (linear_velocity_imu_in_world - previous_linear_velocity) / dt;
125 
126  auto rotation_world_to_imu = orientation_imu_in_world.normalized().inverse();
127  Eigen::Vector3d angular_velocity_imu_in_imu =
128  rotation_world_to_imu * angular_velocity_imu_to_world_in_world;
129  Eigen::Vector3d linear_acceleration_imu_in_imu =
130  rotation_world_to_imu * linear_acceleration_imu_in_world;
131 
132  // Fill out regular IMU data
133  imu_data.orientation_imu_in_ars = orientation_imu_in_ars;
134  imu_data.angular_velocity_imu_in_imu = angular_velocity_imu_in_imu;
135  imu_data.linear_acceleration_imu_in_imu = linear_acceleration_imu_in_imu;
136 
137  // ... and the extra field for the Bullet interface
138  imu_data.linear_velocity_imu_in_world = linear_velocity_imu_in_world;
139 }
140 
141 } // namespace vulp::actuation
Send actions to actuators or simulators.
Definition: bullet_utils.h:13
void read_imu_data(BulletImuData &imu_data, b3RobotSimulatorClientAPI &bullet, int robot, const int imu_link_index, double dt)
Compute IMU readings from the IMU link state.
Definition: bullet_utils.h:84
Eigen::Quaterniond eigen_from_bullet(const btQuaternion &quat)
Convert a Bullet quaternion to an Eigen one.
Definition: bullet_utils.h:41
btQuaternion bullet_from_eigen(const Eigen::Quaterniond &quat)
Convert an Eigen quaternion to a Bullet one.
Definition: bullet_utils.h:21
int find_link_index(b3RobotSimulatorClientAPI &bullet, int robot, const std::string &link_name) noexcept
Find the index of a link.
Definition: bullet_utils.h:63
Eigen::Vector3d linear_velocity_imu_in_world
Spatial linear velocity in [m] / [s]², used to compute the acceleration.
Definition: BulletImuData.h:15
Eigen::Quaterniond orientation_imu_in_ars
Orientation from the IMU frame to the attitude reference system (ARS) frame.
Definition: ImuData.h:20
Eigen::Vector3d linear_acceleration_imu_in_imu
Body linear acceleration of the IMU, in [m] / [s]².
Definition: ImuData.h:39
Eigen::Vector3d angular_velocity_imu_in_imu
Body angular velocity of the IMU frame in [rad] / [s].
Definition: ImuData.h:30