snark
range_bearing_elevation.h
1 // This file is part of snark, a generic and flexible library
2 // for robotics research.
3 //
4 // Copyright (C) 2011 The University of Sydney
5 //
6 // snark is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // snark is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 // for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with snark. If not, see <http://www.gnu.org/licenses/>.
18 
19 #ifndef SNARK_MATH_RBE_H
20 #define SNARK_MATH_RBE_H
21 
22 #include <Eigen/Core>
23 #include <comma/math/compare.h>
24 
25 namespace snark{
26 
29 {
30 public:
33  range_bearing_elevation( double r, double b, double e ): m_rbe( r, b, e ) {}
34 
36  double range() const { return m_rbe[0]; }
37  double bearing() const { return m_rbe[0]; }
38  double elevation() const { return m_rbe[0]; }
39 
41  double r() const { return range(); }
42  double b() const { return bearing(); }
43  double e() const { return elevation(); }
44 
46  void range( double t );
47  void bearing( double t );
48  void elevation( double t );
49 
50  Eigen::Vector3d to_cartesian() const;
51 
52 private:
53  Eigen::Vector3d m_rbe;
54 };
55 
57 {
58  if( !comma::math::less( t, 0 ) )
59  {
60  m_rbe[0] = t;
61  }
62  else
63  {
64  m_rbe[0] = -t;
65  m_rbe[1] = -m_rbe[1];
66  m_rbe[2] = -m_rbe[2];
67  }
68 }
69 
70 void range_bearing_elevation::bearing( double t )
71 {
72  double b( std::fmod( t, ( double )( M_PI * 2 ) ) );
73  if( !comma::math::less( b, M_PI ) ) { b -= ( M_PI * 2 ); }
74  else if( comma::math::less( b, -M_PI ) ) { b += ( M_PI * 2 ); }
75  m_rbe[1] = b;
76 }
77 
78 void range_bearing_elevation::elevation( double t )
79 {
80  double e( std::fmod( t, ( double )( M_PI * 2 ) ) );
81  if( comma::math::less( e, 0 ) ) { e += M_PI * 2; }
82  if( !comma::math::less( e, M_PI / 2 ) )
83  {
84  if( !comma::math::less( e, M_PI ) )
85  {
86  if( !comma::math::less( e, M_PI * 3 / 2 ) )
87  {
88  e = e - M_PI * 2;
89  }
90  else
91  {
92  e = M_PI - e;
93  bearing( bearing() + M_PI );
94  }
95  }
96  else
97  {
98  e = M_PI - e;
99  bearing( bearing() + M_PI );
100  }
101  }
102  m_rbe[2] = e;
103 }
104 
105 Eigen::Vector3d range_bearing_elevation::to_cartesian() const
106 {
107  double xyProjection( range() * std::cos( elevation() ) );
108  return ::Eigen::Matrix< double, 3, 1 >( xyProjection * std::cos( bearing() )
109  , xyProjection * std::sin( bearing() )
110  , range() * std::sin( elevation() ) );
111 }
112 
113 }
114 
115 namespace comma { namespace visiting {
116 
118 template <>
119 struct traits< snark::range_bearing_elevation >
120 {
122  template < typename Key, class Visitor >
123  static void visit( const Key&, const snark::range_bearing_elevation& p, Visitor& v )
124  {
125  v.apply( "range", p.range() );
126  v.apply( "bearing", p.bearing() );
127  v.apply( "elevation", p.elevation() );
128  }
129 
131  template < typename Key, class Visitor >
132  static void visit( Key, snark::range_bearing_elevation& p, Visitor& v )
133  {
134  double r;
135  double b;
136  double e;
137  v.apply( "range", r );
138  v.apply( "bearing", b );
139  v.apply( "elevation", e );
140  p = snark::range_bearing_elevation( r, b, e );
141  }
142 };
143 
144 } } // namespace comma { namespace visiting {
145 
146 #endif // SNARK_MATH_RBE_H