mpusz / mp-units

The quantities and units library for C++
https://mpusz.github.io/mp-units/
MIT License
997 stars 79 forks source link

How to have scalar angular velocities in deg/s and rad/s and how to convert between those two ... #515

Closed aentinger closed 8 months ago

aentinger commented 8 months ago

Hi :coffee: :wave:

I've been playing w/ this library for quite some time already. However, I've been unable to get anything working re angular velocities with a scalar numeric value using units deg/s and rad/s.

#include <mp-units/systems/si/si.h>
#include <mp-units/systems/angular/angular.h>
// ...
using namespace mp_units;
using mp_units::angular::unit_symbols::deg;
using mp_units::angular::unit_symbols::rad;
using mp_units::si::unit_symbols::s;
// ...
quantity PAN_MAX_dps = 1. * deg/s;

Why doesn't this work? :cry:

I simply want to do next smth like

auto PAN_MAX_rps = PAN_MAX_dps.in(rad/s);

and then do away with encoding the type in the variable name altogether ...

:pray: help me here, I've perused code and documentation and I am non-the-wiser.

JohelEGP commented 8 months ago

and then do away with encoding the type in the variable name altogether ...

Since the code seems to work (https://godbolt.org/z/hWW4rrMGj), do you want #483?

aentinger commented 8 months ago

Interestingly enough, it works on godbolt, even w/ the GCC version that I am using (11.4.0) and mp-units v2.0.0.

However, the same code snippets in my production code simply don't work:

/home/alex/projects/107-systems/colcon_ws/src/l3xz_teleop/src/Node.cpp: In member function ‘void l3xz::Node::onJoyMsg(sensor_msgs::msg::Joy_<std::allocator<void> >::SharedPtr)’:
/home/alex/projects/107-systems/colcon_ws/src/l3xz_teleop/src/Node.cpp:134:30: error: no match for ‘operator/’ (operand types are ‘mp_units::quantity<mp_units::angular::degree(), double>’ and ‘const mp_units::si::second’)
  134 |   auto PAN_MAX_dps = 1. * deg/s;
      |                      ~~~~~~~~^~
      |                         |     |
      |                         |     const mp_units::si::second
      |                         mp_units::quantity<mp_units::angular::degree(), double>

Any idea why?

mp-units was installed system-wide via

git clone https://github.com/mpusz/mp-units && cd mp-units
git checkout v2.0.0
mkdir build && cd build
cmake -DMP_UNITS_AS_SYSTEM_HEADERS=ON -DMP_UNITS_BUILD_LA=OFF ..
make -j8
sudo make install

and is pulled into the ROS2 build project via

find_package(mp-units REQUIRED)
ament_target_dependencies(${L3XZ_TELEOP_TARGET} rclcpp std_msgs sensor_msgs geometry_msgs ros2_heartbeat mp-units)
mpusz commented 8 months ago

The quantity construction was relaxed after mp-units 2.0 was released. Starting from version 2.1, it should work fine. If you are on the 2.0 you need to do the following:

auto PAN_MAX_dps = 1. * (deg / s);
aentinger commented 8 months ago

I've recompiled mp-units for the master:HEAD (https://github.com/mpusz/mp-units/commit/0c0b48f725de3e7fb69db1744c36dbe358dd777f). This works now on my end :partying_face: Thank you for your support.

Here's the relevant diff.

There is real value for me having those worry free type conversions. Angles are usually degrees in the config files, since those are edited by humans who are more familiar with degrees than with radians. However, machines use radians and it's really easy to introduce a :bug: when you always manually convert back and forth.