GCC Code Coverage Report


Directory: ./
File: include/pinocchio/algorithm/utils/motion.hpp
Date: 2024-08-27 18:20:05
Exec Total Coverage
Lines: 0 31 0.0%
Branches: 0 110 0.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2020 INRIA
3 //
4
5 #ifndef __pinocchio_algorithm_utils_motion_hpp__
6 #define __pinocchio_algorithm_utils_motion_hpp__
7
8 #include "pinocchio/spatial/se3.hpp"
9 #include "pinocchio/spatial/motion.hpp"
10 #include "pinocchio/multibody/fwd.hpp"
11
12 namespace pinocchio
13 {
14
15 ///
16 /// @copydoc changeReferenceFrame(const SE3Tpl<Scalar,Options> &,const MotionDense<MotionIn>
17 /// &,const ReferenceFrame,const ReferenceFrame) \param[out] m_out Resulting motion quantity.
18 ///
19 template<typename Scalar, int Options, typename MotionIn, typename MotionOut>
20 void changeReferenceFrame(
21 const SE3Tpl<Scalar, Options> & placement,
22 const MotionDense<MotionIn> & m_in,
23 const ReferenceFrame rf_in,
24 const ReferenceFrame rf_out,
25 MotionDense<MotionOut> & m_out)
26 {
27 if (rf_in == rf_out)
28 {
29 m_out = m_in;
30 return;
31 }
32
33 // case: LOCAL/WORLD and WORLD/LOCAL
34 if (rf_in == LOCAL && rf_out == WORLD)
35 {
36 m_out = placement.act(m_in);
37 return;
38 }
39 if (rf_in == WORLD && rf_out == LOCAL)
40 {
41 m_out = placement.actInv(m_in);
42 return;
43 }
44
45 // case: LOCAL/LOCAL_WORLD_ALIGNED and LOCAL_WORLD_ALIGNED/LOCAL
46 if (rf_in == LOCAL && rf_out == LOCAL_WORLD_ALIGNED)
47 {
48 m_out.linear().noalias() = placement.rotation() * m_in.linear();
49 m_out.angular().noalias() = placement.rotation() * m_in.angular();
50 return;
51 }
52 if (rf_in == LOCAL_WORLD_ALIGNED && rf_out == LOCAL)
53 {
54 m_out.linear().noalias() = placement.rotation().transpose() * m_in.linear();
55 m_out.angular().noalias() = placement.rotation().transpose() * m_in.angular();
56 return;
57 }
58
59 // case: WORLD/LOCAL_WORLD_ALIGNED and LOCAL_WORLD_ALIGNED/WORLD
60 if (rf_in == WORLD && rf_out == LOCAL_WORLD_ALIGNED)
61 {
62 m_out.angular() = m_in.angular();
63 m_out.linear().noalias() = m_in.linear() + m_in.angular().cross(placement.translation());
64 return;
65 }
66 if (rf_in == LOCAL_WORLD_ALIGNED && rf_out == WORLD)
67 {
68 m_out.angular() = m_in.angular();
69 m_out.linear().noalias() = m_in.linear() - m_in.angular().cross(placement.translation());
70 return;
71 }
72
73 assert(false && "This must never happened.");
74 }
75
76 ///
77 ///  \brief Change the expression of a given Motion vector from one reference frame to another
78 /// reference frame.
79 ///
80 ///  \example If ones has an initial m_in Motion expressed locally (rf_in=LOCAL) in a Frame
81 /// localized at a given placement value,   ones may want to retrieve its value inside
82 /// another reference frame e.g. the world (rf_out=WORLD).
83 ///
84 /// \param[in] placement Placement of the frame having velocity m_in
85 /// \param[in] m_in Input motion quantity.
86 /// \param[in] rf_in Reference frame in which m_in is expressed
87 /// \param[in] rf_out Reference frame in which the result m_out is expressed
88 /// \param[out] m_out Resulting motion quantity.
89 ///
90 template<typename Scalar, int Options, typename MotionIn>
91 typename MotionIn::MotionPlain changeReferenceFrame(
92 const SE3Tpl<Scalar, Options> & placement,
93 const MotionDense<MotionIn> & m_in,
94 const ReferenceFrame rf_in,
95 const ReferenceFrame rf_out)
96 {
97 typedef typename MotionIn::MotionPlain ReturnType;
98 ReturnType res;
99
100 changeReferenceFrame(placement, m_in, rf_in, rf_out, res);
101
102 return res;
103 }
104
105 } // namespace pinocchio
106
107 #endif // #ifndef __pinocchio_multibody_fwd_hpp__
108