environment.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2015 Intel Corporation. All Rights Reserved.
3 
4 #include "environment.h"
5 
6 namespace librealsense
7 {
9  : _locks_count(0)
10  {
11  _id = std::make_shared<lazy<rs2_extrinsics>>([]()
12  {
13  return identity_matrix();
14  });
15  }
16 
18  {
19  extrinsics_lock l(*this);
20  return l;
21  }
22 
24  {
25  register_extrinsics(from, to, _id);
26  }
27 
29  {
30  std::lock_guard<std::mutex> lock(_mutex);
31 
32  // First, trim any dead stream, to make sure we are not keep gaining memory
34 
35  // Second, register new extrinsics
36  auto from_idx = find_stream_profile(from);
37  // If this is a new index, add it to the map preemptively,
38  // This way find on to will be able to return another new index
39  if (_extrinsics.find(from_idx) == _extrinsics.end())
40  _extrinsics.insert({from_idx, {}});
41 
42  auto to_idx = find_stream_profile(to);
43 
44  _extrinsics[from_idx][to_idx] = extr;
45  _extrinsics[to_idx][from_idx] = std::shared_ptr<lazy<rs2_extrinsics>>(nullptr);
46  }
47 
49  {
50  auto lazy_extr = std::make_shared<lazy<rs2_extrinsics>>([=]() {return extr; });
51  _external_extrinsics.push_back(lazy_extr);
52  register_extrinsics(from, to, lazy_extr);
53  }
54 
56  {
57  std::lock_guard<std::mutex> lock( _mutex );
58 
59  // First, trim any dead stream, to make sure we are not keep gaining memory
61 
62  // The extrinsics must already exist!
63  auto from_idx = find_stream_profile( from, false ); // do not add if not there
64  auto from_it = _extrinsics.find( from_idx );
65  if( from_it == _extrinsics.end() )
66  throw std::runtime_error( "override_extrinsics called for invalid <from> stream" );
67  auto& from_map = from_it->second;
68 
69  auto to_idx = find_stream_profile( to, false ); // do not add if not there
70  auto to_it = from_map.find( to_idx );
71  if( to_it == from_map.end() )
72  throw std::runtime_error( "override_extrinsics called for invalid <to> stream" );
73  auto& weak_ptr = to_it->second;
74  auto sp = weak_ptr.lock();
75  if( !sp )
76  throw std::runtime_error( "override_extrinsics called for out-of-date stream" );
77 
78  auto & lazy_extr = *sp;
79  lazy_extr = [=]() { return extr; };
80  }
81 
83  {
84  if (_locks_count.load()) return;
85 
86  auto counter = 0;
87  std::vector<int> invalid_ids;
88  for (auto&& kvp : _streams)
89  {
90  if (!kvp.second.lock())
91  {
92  auto invalid_id = kvp.first;
93  // Delete all extrinsics going out of this stream
94  _extrinsics.erase(invalid_id);
95  ++counter;
96  invalid_ids.push_back(invalid_id);
97  }
98  }
99 
100  for (auto removed_id : invalid_ids)
101  {
102  _streams.erase(removed_id);
103  for (auto&& elem : _extrinsics)
104  {
105  // Delete any extrinsics going into the stream
106  elem.second.erase(removed_id);
107  ++counter;
108  }
109  }
110 
111  if (!invalid_ids.empty())
112  LOG_INFO("Found " << invalid_ids.size() << " unreachable streams, " << std::dec << counter << " extrinsics deleted");
113  }
114 
115  int extrinsics_graph::find_stream_profile(const stream_interface& p, bool add_if_not_there)
116  {
117  auto sp = p.shared_from_this();
118  auto max = 0;
119  for (auto&& kvp : _streams)
120  {
121  if (kvp.second.lock().get() == sp.get())
122  return kvp.first;
123  max = std::max( max, kvp.first );
124  }
125  if( !add_if_not_there )
126  return -1;
127  _streams[max + 1] = sp;
128  return max + 1;
129 
130  }
131 
133  {
134  std::lock_guard<std::mutex> lock(_mutex);
136  auto from_idx = find_stream_profile(from);
137  auto to_idx = find_stream_profile(to);
138 
139  if (from_idx == to_idx)
140  {
141  *extr = identity_matrix();
142  return true;
143  }
144 
145  std::set<int> visited;
146  return try_fetch_extrinsics(from_idx, to_idx, visited, extr);
147  }
148 
149  bool extrinsics_graph::try_fetch_extrinsics(int from, int to, std::set<int>& visited, rs2_extrinsics* extr)
150  {
151  if (visited.count(from)) return false;
152 
153  auto it = _extrinsics.find(from);
154  if (it != _extrinsics.end())
155  {
156  auto back_edge = fetch_edge(to, from);
157  auto fwd_edge = fetch_edge(from, to);
158 
159  // Make sure both parts of the edge are still available
160  if (fwd_edge.get() || back_edge.get())
161  {
162  if (fwd_edge.get())
163  *extr = fwd_edge->operator*(); // Evaluate the expression
164  else
165  *extr = inverse(back_edge->operator*());
166 
167  return true;
168  }
169  else
170  {
171  visited.insert(from);
172  for (auto&& kvp : it->second)
173  {
174  auto new_from = kvp.first;
175  auto way = kvp.second;
176 
177  // Lock down the edge in both directions to ensure we can evaluate the extrinsics
178  back_edge = fetch_edge(new_from, from);
179  fwd_edge = fetch_edge(from, new_from);
180 
181  if ((back_edge.get() || fwd_edge.get()) &&
182  try_fetch_extrinsics(new_from, to, visited, extr))
183  {
184  const auto local = [&]() {
185  if (fwd_edge.get())
186  return fwd_edge->operator*(); // Evaluate the expression
187  else
188  return inverse(back_edge->operator*());
189  }();
190 
191  auto pose = to_pose(*extr) * to_pose(local);
192  *extr = from_pose(pose);
193  return true;
194  }
195  }
196  }
197  } // If there are no extrinsics from from, there are none to it, so it is completely isolated
198  return false;
199  }
200 
201  std::shared_ptr<lazy<rs2_extrinsics>> extrinsics_graph::fetch_edge(int from, int to)
202  {
203  auto it = _extrinsics.find(from);
204  if (it != _extrinsics.end())
205  {
206  auto it2 = it->second.find(to);
207  if (it2 != it->second.end())
208  {
209  return it2->second.lock();
210  }
211  }
212 
213  return nullptr;
214  }
215 
216 
218  {
219  static environment env;
220  return env;
221  }
222 
224  {
225  return _extrinsics;
226  }
227 
228  void environment::set_time_service(std::shared_ptr<platform::time_service> ts)
229  {
230  _ts = ts;
231  }
232 
233  std::shared_ptr<platform::time_service> environment::get_time_service()
234  {
235  return _ts;
236  }
237 }
std::vector< std::shared_ptr< lazy< rs2_extrinsics > > > _external_extrinsics
Definition: environment.h:51
rs2_extrinsics from_pose(pose a)
Definition: src/types.h:602
std::shared_ptr< platform::time_service > get_time_service()
std::map< int, std::map< int, std::weak_ptr< lazy< rs2_extrinsics > > > > _extrinsics
Definition: environment.h:60
GLfloat GLfloat p
Definition: glext.h:12687
std::atomic< int > _locks_count
Definition: environment.h:59
void register_same_extrinsics(const stream_interface &from, const stream_interface &to)
Definition: environment.cpp:23
std::map< int, std::weak_ptr< const stream_interface > > _streams
Definition: environment.h:62
void override_extrinsics(const stream_interface &from, const stream_interface &to, rs2_extrinsics const &extr)
Definition: environment.cpp:55
rs2_extrinsics identity_matrix()
Definition: src/types.h:611
Definition: parser.hpp:154
pose inverse(const pose &a)
Definition: src/types.h:592
pose to_pose(const rs2_extrinsics &a)
Definition: src/types.h:593
void register_extrinsics(const stream_interface &from, const stream_interface &to, std::weak_ptr< lazy< rs2_extrinsics >> extr)
Definition: environment.cpp:28
GLuint counter
Definition: glext.h:5684
PRIVATE_TESTABLE int to
Definition: environment.h:54
void set_time_service(std::shared_ptr< platform::time_service > ts)
static environment & get_instance()
extrinsics_graph & get_extrinsics_graph()
Cross-stream extrinsics: encodes the topology describing how the different devices are oriented...
Definition: rs_sensor.h:96
LOG_INFO("Log message using LOG_INFO()")
int find_stream_profile(const stream_interface &p, bool add_if_not_there=true)
std::shared_ptr< lazy< rs2_extrinsics > > _id
Definition: environment.h:49
static auto it
rs2_extrinsics extr
Definition: test-pose.cpp:258
bool try_fetch_extrinsics(const stream_interface &from, const stream_interface &to, rs2_extrinsics *extr)


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:14