snark
velodyne_stream.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_SENSORS_VELODYNE_VELODYNESTREAM_H_
20 #define SNARK_SENSORS_VELODYNE_VELODYNESTREAM_H_
21 
22 #ifndef WIN32
23 #include <stdlib.h>
24 #endif
25 #include <snark/sensors/velodyne/stream.h>
26 #include <snark/visiting/eigen.h>
27 
28 namespace snark {
29 
32 {
33  boost::posix_time::ptime timestamp;
34  comma::uint32 id;
35  comma::uint32 intensity;
36  std::pair< ::Eigen::Vector3d, ::Eigen::Vector3d > ray;
37  double azimuth;
38  double range;
39  bool valid;
40  comma::uint32 scan;
41 };
42 
44 template < typename S >
46 {
47 public:
48  velodyne_stream( const velodyne::db& db
49  , bool outputInvalidpoints
50  , boost::optional< std::size_t > from = boost::optional< std::size_t >(), boost::optional< std::size_t > to = boost::optional< std::size_t >() );
51 
52  template < typename P >
53  velodyne_stream( const P& p
54  , const velodyne::db& db
55  , bool outputInvalidpoints
56  , boost::optional< std::size_t > from = boost::optional< std::size_t >(), boost::optional< std::size_t > to = boost::optional< std::size_t >() );
57 
58  bool read();
59  const velodyne_point& point() const { return m_point; }
60 
61 private:
62  velodyne::stream< S > m_stream;
63  velodyne::db m_db;
64  velodyne_point m_point;
65  boost::optional< std::size_t > m_to;
66 };
67 
68 template < typename S >
69 velodyne_stream< S >::velodyne_stream ( const velodyne::db& db, bool outputInvalidpoints
70  , boost::optional< std::size_t > from
71  , boost::optional< std::size_t > to ):
72  m_stream( new S, outputInvalidpoints ),
73  m_db( db ),
74  m_to( to )
75 {
76  if( from ) { while( m_stream.scan() < *from ) { m_stream.skipscan(); } }
77 }
78 
79 template < typename S >
80 template < typename P >
81 velodyne_stream< S >::velodyne_stream ( const P& p, const velodyne::db& db, bool outputInvalidpoints
82  , boost::optional< std::size_t > from
83  , boost::optional< std::size_t > to ):
84  m_stream( new S( p ), outputInvalidpoints ),
85  m_db( db ),
86  m_to( to )
87 {
88  if( from ) { while( m_stream.scan() < *from ) { m_stream.skipscan(); } }
89 }
90 
93 template < typename S >
95 {
96  if( m_to && m_stream.scan() > *m_to )
97  {
98  return false;
99  }
100 
101  const velodyne::laser_return* r = m_stream.read();
102 
103  if( r == NULL ) { return false; }
104  m_point.timestamp = r->timestamp;
105  m_point.id = r->id;
106  m_point.intensity = r->intensity;
107  m_point.valid = !comma::math::equal( r->range, 0 ); // quick and dirty
108  m_point.ray = m_db.lasers[ m_point.id ].ray( r->range, r->azimuth );
109  m_point.range = m_db.lasers[ m_point.id ].range( r->range );
110  m_point.scan = m_stream.scan();
111  m_point.azimuth = m_db.lasers[ m_point.id ].azimuth( r->azimuth );
112  return true;
113 }
114 
116 template <>
117 class velodyne_stream< comma::csv::input_stream< velodyne_point> >
118 {
119 public:
120 
121  velodyne_stream( const comma::csv::options& options ): m_stream( std::cin, options ) {}
122 
123  bool read();
124  const velodyne_point& point() const { return m_point; }
125 
126 private:
127  comma::csv::input_stream< velodyne_point > m_stream;
128  velodyne_point m_point;
129 };
130 
134 {
135  const velodyne_point* point = m_stream.read();
136  if( point == NULL )
137  {
138  return false;
139  }
140  m_point = *point;
141  return true;
142 }
143 
144 
145 }
146 
147 
148 namespace comma { namespace visiting {
149 
150 template <> struct traits< snark::velodyne_point >
151 {
152  template < typename K, typename V > static void visit( const K&, snark::velodyne_point& p, V& v )
153  {
154  v.apply( "t", p.timestamp );
155  v.apply( "id", p.id );
156  v.apply( "intensity", p.intensity );
157  v.apply( "ray", p.ray );
158  v.apply( "azimuth", p.azimuth );
159  v.apply( "range", p.range );
160  v.apply( "valid", p.valid );
161  v.apply( "scan", p.scan );
162  }
163 
164  template < typename K, typename V > static void visit( const K&, const snark::velodyne_point& p, V& v )
165  {
166  v.apply( "t", p.timestamp );
167  v.apply( "id", p.id );
168  v.apply( "intensity", p.intensity );
169  v.apply( "ray", p.ray );
170  v.apply( "azimuth", p.azimuth );
171  v.apply( "range", p.range );
172  v.apply( "valid", p.valid );
173  v.apply( "scan", p.scan );
174  }
175 };
176 
177 } } // namespace comma { namespace visiting {
178 
179 #endif // SNARK_SENSORS_VELODYNE_VELODYNESTREAM_H_