GCC Code Coverage Report


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