d400-private.cpp
Go to the documentation of this file.
1 
4 #include "d400-private.h"
5 
6 using namespace std;
7 
8 
9 namespace librealsense
10 {
11  namespace ds
12  {
13  bool d400_try_fetch_usb_device(std::vector<platform::usb_device_info>& devices,
15  {
16  for (auto it = devices.begin(); it != devices.end(); ++it)
17  {
18  if (it->unique_id == info.unique_id)
19  {
20  bool found = false;
21  result = *it;
22  switch (info.pid)
23  {
24  case RS_USB2_PID:
25  case RS400_PID:
26  case RS405U_PID:
27  case RS410_PID:
28  case RS416_PID:
29  case RS460_PID:
30  case RS430_PID:
31  case RS420_PID:
32  case RS400_IMU_PID:
33  found = (result.mi == 3);
34  break;
35  case RS405_PID:
36  case RS430I_PID:
37  found = (result.mi == 4);
38  break;
39  case RS430_MM_PID:
40  case RS420_MM_PID:
41  case RS435I_PID:
42  case RS455_PID:
43  found = (result.mi == 6);
44  break;
45  case RS415_PID:
46  case RS416_RGB_PID:
47  case RS435_RGB_PID:
48  found = (result.mi == 5);
49  break;
50  default:
51  throw not_implemented_exception(rsutils::string::from() << "USB device "
52  << std::hex << info.pid << ":" << info.vid << std::dec << " is not supported.");
53  break;
54  }
55 
56  if (found)
57  {
58  devices.erase(it);
59  return true;
60  }
61  }
62  }
63  return false;
64  }
65 
66  std::vector<platform::uvc_device_info> filter_d400_device_by_capability(const std::vector<platform::uvc_device_info>& devices,
67  ds_caps caps)
68  {
69  std::vector<platform::uvc_device_info> results;
70 
71  switch (caps)
72  {
73  case ds_caps::CAP_FISHEYE_SENSOR:
74  std::copy_if(devices.begin(), devices.end(), std::back_inserter(results),
76  {
77  return d400_fisheye_pid.find(info.pid) != d400_fisheye_pid.end();
78  });
79  break;
80  default:
82  << "Capability filters are not implemented for val "
83  << std::hex << caps << std::dec);
84  }
85  return results;
86  }
87 
88  std::string extract_firmware_version_string( const std::vector< uint8_t > & fw_image )
89  {
90  auto version_offset = offsetof( platform::dfu_header, bcdDevice );
91  if( fw_image.size() < ( version_offset + sizeof( size_t ) ) )
92  throw std::runtime_error( "Firmware binary image might be corrupted - size is only: "
93  + std::to_string( fw_image.size() ) );
94 
95  auto version = fw_image.data() + version_offset;
96  uint8_t major = *( version + 3 );
97  uint8_t minor = *( version + 2 );
98  uint8_t patch = *( version + 1 );
99  uint8_t build = *( version );
100 
101  return std::to_string( major ) + "." + std::to_string( minor ) + "." + std::to_string( patch ) + "."
102  + std::to_string( build );
103  }
104 
106  {
107  switch (table_id)
108  {
109  case d400_calibration_table_id::coefficients_table_id:
110  {
112  }
113  case d400_calibration_table_id::fisheye_calibration_id:
114  {
115  return get_intrinsic_fisheye_table(raw_data, width, height);
116  }
117  case d400_calibration_table_id::rgb_calibration_id:
118  {
119  return get_d400_color_stream_intrinsic(raw_data, width, height);
120  }
121  default:
122  throw invalid_value_exception(rsutils::string::from() << "Parsing Calibration table type " << static_cast<int>(table_id) << " is not supported");
123  }
124  }
125 
127  {
128  auto table = check_calib<ds::d400_coefficients_table>(raw_data);
129 
130 #define intrinsics_string(res) #res << "\t" << array2str((float_4&)table->rect_params[res]) << endl
131 
132  LOG_DEBUG(endl
133  << "baseline = " << table->baseline << " mm" << endl
134  << "Rect params: \t fX\t\t fY\t\t ppX\t\t ppY \n"
145 
146 #undef intrinsics_string
147 
149 
150  if (width == 848 && height == 100) // Special 848x100 resolution is available in some firmware versions
151  // for this resolution we use the same base-intrinsics as for 848x480 and adjust them later
152  {
153  resolution = width_height_to_ds_rect_resolutions(width, 480);
154  }
155 
156  if (resolution < max_ds_rect_resolutions)
157  {
159  intrinsics.width = resolutions_list[resolution].x;
160  intrinsics.height = resolutions_list[resolution].y;
161 
162  auto rect_params = static_cast<const float4>(table->rect_params[resolution]);
163  // DS5U - assume ideal intrinsic params
164  if ((rect_params.x == rect_params.y) && (rect_params.z == rect_params.w))
165  {
166  rect_params.x = rect_params.y = intrinsics.width * 1.5f;
167  rect_params.z = intrinsics.width * 0.5f;
168  rect_params.w = intrinsics.height * 0.5f;
169  }
170  intrinsics.fx = rect_params[0];
171  intrinsics.fy = rect_params[1];
172  intrinsics.ppx = rect_params[2];
173  intrinsics.ppy = rect_params[3];
175  memset(intrinsics.coeffs, 0, sizeof(intrinsics.coeffs)); // All coefficients are zeroed since rectified depth is defined as CS origin
176 
177  // In case of the special 848x100 resolution adjust the intrinsics
178  if (width == 848 && height == 100)
179  {
180  intrinsics.height = 100;
181  intrinsics.ppy -= 190;
182  }
183 
184  return intrinsics;
185  }
186  else
187  {
188  // Intrinsics not found in the calibration table - use the generic calculation
189  ds_rect_resolutions resolution = res_1920_1080;
191  intrinsics.width = width;
192  intrinsics.height = height;
193 
194  auto rect_params = static_cast<const float4>(table->rect_params[resolution]);
195  // DS5U - assume ideal intrinsic params
196  if ((rect_params.x == rect_params.y) && (rect_params.z == rect_params.w))
197  {
198  rect_params.x = rect_params.y = intrinsics.width * 1.5f;
199  rect_params.z = intrinsics.width * 0.5f;
200  rect_params.w = intrinsics.height * 0.5f;
201  }
202 
203  // Special resolution for auto-calibration requires special treatment...
204  if (width == 256 && height == 144)
205  {
206  intrinsics.fx = rect_params[0];
207  intrinsics.fy = rect_params[1];
208  intrinsics.ppx = rect_params[2] - 832;
209  intrinsics.ppy = rect_params[3] - 468;
210  }
211  else
212  {
213  intrinsics.fx = rect_params[0] * width / resolutions_list[resolution].x;
214  intrinsics.fy = rect_params[1] * height / resolutions_list[resolution].y;
215  intrinsics.ppx = rect_params[2] * width / resolutions_list[resolution].x;
216  intrinsics.ppy = rect_params[3] * height / resolutions_list[resolution].y;
217  }
218 
220  memset(intrinsics.coeffs, 0, sizeof(intrinsics.coeffs)); // All coefficients are zeroed since rectified depth is defined as CS origin
221 
222  return intrinsics;
223  }
224  }
225 
226  pose get_d400_color_stream_extrinsic(const std::vector<uint8_t>& raw_data)
227  {
228  auto table = check_calib<d400_rgb_calibration_table>(raw_data);
229  float3 trans_vector = table->translation_rect;
230  float3x3 rect_rot_mat = table->rotation_matrix_rect;
231  float trans_scale = -0.001f; // Convert units from mm to meter. Extrinsic of color is referenced to the Depth Sensor CS
232 
233  trans_vector.x *= trans_scale;
234  trans_vector.y *= trans_scale;
235  trans_vector.z *= trans_scale;
236 
237  return{ rect_rot_mat,trans_vector };
238  }
239 
241  {
242  auto table = check_calib<ds::d400_rgb_calibration_table>(raw_data);
243 
244  // Compensate for aspect ratio as the normalized intrinsic is calculated with a single resolution
245  float3x3 intrin = table->intrinsic;
246  float calib_aspect_ratio = 9.f / 16.f; // shall be overwritten with the actual calib resolution
247 
248  if (table->calib_width && table->calib_height)
249  calib_aspect_ratio = float(table->calib_height) / float(table->calib_width);
250  else
251  {
252  LOG_WARNING("RGB Calibration resolution is not specified, using default 16/9 Aspect ratio");
253  }
254 
255  // Compensate for aspect ratio
256  float actual_aspect_ratio = height / (float)width;
257  if (actual_aspect_ratio < calib_aspect_ratio)
258  {
259  intrin(1, 1) *= calib_aspect_ratio / actual_aspect_ratio;
260  intrin(2, 1) *= calib_aspect_ratio / actual_aspect_ratio;
261  }
262  else
263  {
264  intrin(0, 0) *= actual_aspect_ratio / calib_aspect_ratio;
265  intrin(2, 0) *= actual_aspect_ratio / calib_aspect_ratio;
266  }
267 
268  // Calculate specific intrinsic parameters based on the normalized intrinsic and the sensor's resolution
269  rs2_intrinsics calc_intrinsic{
270  static_cast<int>(width),
271  static_cast<int>(height),
272  ((1 + intrin(2, 0)) * width) / 2.f,
273  ((1 + intrin(2, 1)) * height) / 2.f,
274  intrin(0, 0) * width / 2.f,
275  intrin(1, 1) * height / 2.f,
276  RS2_DISTORTION_INVERSE_BROWN_CONRADY // The coefficients shall be use for undistort
277  };
278  std::memcpy(calc_intrinsic.coeffs, table->distortion, sizeof(table->distortion));
279  //LOG_DEBUG(endl << array2str((float_4&)(calc_intrinsic.fx, calc_intrinsic.fy, calc_intrinsic.ppx, calc_intrinsic.ppy)) << endl);
280 
281  static rs2_intrinsics ref{};
282  if (memcmp(&calc_intrinsic, &ref, sizeof(rs2_intrinsics)))
283  {
284  LOG_DEBUG_THERMAL_LOOP("RGB Intrinsic: ScaleX, ScaleY = "
285  << std::setprecision(3) << intrin(0, 0) << ", " << intrin(1, 1)
286  << ". Fx,Fy = " << calc_intrinsic.fx << "," << calc_intrinsic.fy);
287  ref = calc_intrinsic;
288  }
289 
290  return calc_intrinsic;
291  }
292 
293  // Parse intrinsics from newly added RECPARAMSGET command
294  bool try_get_d400_intrinsic_by_resolution_new(const vector<uint8_t>& raw_data,
296  {
297  using namespace ds;
298  auto count = raw_data.size() / sizeof(new_calibration_item);
299  auto items = (new_calibration_item*)raw_data.data();
300  for (int i = 0; i < count; i++)
301  {
302  auto&& item = items[i];
303  if (item.width == width && item.height == height)
304  {
305  result->width = width;
306  result->height = height;
307  result->ppx = item.ppx;
308  result->ppy = item.ppy;
309  result->fx = item.fx;
310  result->fy = item.fy;
312  memset(result->coeffs, 0, sizeof(result->coeffs)); // All coefficients are zeroed since rectified depth is defined as CS origin
313 
314  return true;
315  }
316  }
317  return false;
318  }
319 
320  } // librealsense::ds
321 } // namespace librealsense
librealsense
Definition: algo.h:18
d400-private.h
librealsense::ds::res_848_480
@ res_848_480
Definition: ds-private.h:273
intrin
rs2_intrinsics intrin
Definition: test-distortion.cpp:14
count
GLint GLsizei count
Definition: glad/glad/glad.h:2301
uint8_t
unsigned char uint8_t
Definition: stdint.h:78
librealsense::ds::d500_gvd_offsets::version_offset
constexpr size_t version_offset
Definition: d500-private.h:51
librealsense::invalid_value_exception
Definition: librealsense-exception.h:114
std::to_string
std::string to_string(T value)
Definition: android_helpers.h:16
rs2::sw_update::version
rsutils::version version
Definition: versions-db-manager.h:30
librealsense::ds::get_intrinsic_fisheye_table
rs2_intrinsics get_intrinsic_fisheye_table(const std::vector< uint8_t > &raw_data, uint32_t width, uint32_t height)
Definition: ds-private.cpp:23
librealsense::ds::res_1920_1080
@ res_1920_1080
Definition: ds-private.h:270
librealsense::ds::RS415_PID
const uint16_t RS415_PID
Definition: d400-private.h:18
rsutils::number::float4
Definition: third-party/rsutils/include/rsutils/number/float3.h:47
rs2_intrinsics
Video stream intrinsics.
Definition: rs_types.h:58
librealsense::ds::res_1280_800
@ res_1280_800
Definition: ds-private.h:278
rsutils::number::float3::y
float y
Definition: third-party/rsutils/include/rsutils/number/float3.h:37
librealsense::ds::res_320_240
@ res_320_240
Definition: ds-private.h:276
librealsense::platform::dfu_header
Definition: usb-types.h:227
string
GLsizei const GLchar *const * string
Definition: glad/glad/glad.h:2861
devices
Definition: third-party/realdds/scripts/devices.py:1
librealsense::ds::res_960_540
@ res_960_540
Definition: ds-private.h:279
librealsense::ds::resolutions_list
static std::map< ds_rect_resolutions, int2 > resolutions_list
Definition: ds-private.h:545
librealsense::ds::RS455_PID
const uint16_t RS455_PID
Definition: d400-private.h:38
librealsense::ds::new_calibration_item
Definition: ds-private.h:290
LOG_DEBUG
#define LOG_DEBUG(...)
Definition: easyloggingpp.h:70
rspy.repo.build
build
Definition: repo.py:16
table
GLenum GLenum GLsizei void * table
Definition: glad/glad/glad.h:3584
librealsense::ds::RS460_PID
const uint16_t RS460_PID
Definition: d400-private.h:30
ref
GLint ref
Definition: glad/glad/glad.h:1460
librealsense::ds::RS416_RGB_PID
const uint16_t RS416_RGB_PID
Definition: d400-private.h:36
rsutils::number::float4::x
float x
Definition: third-party/rsutils/include/rsutils/number/float3.h:49
librealsense::ds::filter_d400_device_by_capability
std::vector< platform::uvc_device_info > filter_d400_device_by_capability(const std::vector< platform::uvc_device_info > &devices, ds_caps caps)
Definition: d400-private.cpp:66
LOG_WARNING
#define LOG_WARNING(...)
Definition: easyloggingpp.h:72
librealsense::ds::res_1280_720
@ res_1280_720
Definition: ds-private.h:271
width
GLint GLsizei width
Definition: glad/glad/glad.h:1397
librealsense::ds::RS416_PID
const uint16_t RS416_PID
Definition: d400-private.h:34
intrinsics_string
#define intrinsics_string(res)
librealsense::ds::RS420_PID
const uint16_t RS420_PID
Definition: d400-private.h:25
uint32_t
unsigned int uint32_t
Definition: stdint.h:80
rs2_intrinsics::fx
float fx
Definition: rs_types.h:64
test-device-fw-compatibility.fw_image
fw_image
Definition: test-device-fw-compatibility.py:89
librealsense::ds::RS410_PID
const uint16_t RS410_PID
Definition: d400-private.h:17
height
GLint GLsizei GLsizei height
Definition: glad/glad/glad.h:1397
librealsense::ds::RS420_MM_PID
const uint16_t RS420_MM_PID
Definition: d400-private.h:26
rsutils::number::float3::x
float x
Definition: third-party/rsutils/include/rsutils/number/float3.h:37
i
int i
Definition: rs-pcl-color.cpp:54
librealsense::ds::RS435_RGB_PID
const uint16_t RS435_RGB_PID
Definition: d400-private.h:31
librealsense::ds::d400_try_fetch_usb_device
bool d400_try_fetch_usb_device(std::vector< platform::usb_device_info > &devices, const platform::uvc_device_info &info, platform::usb_device_info &result)
Definition: d400-private.cpp:13
librealsense::ds::width_height_to_ds_rect_resolutions
ds_rect_resolutions width_height_to_ds_rect_resolutions(uint32_t width, uint32_t height)
Definition: ds-private.cpp:13
librealsense::ds::RS_USB2_PID
const uint16_t RS_USB2_PID
Definition: d400-private.h:21
find_librs_version.minor
minor
Definition: find_librs_version.py:23
rsutils::number::float3x3
Definition: third-party/rsutils/include/rsutils/number/float3.h:57
LOG_DEBUG_THERMAL_LOOP
#define LOG_DEBUG_THERMAL_LOOP(...)
Definition: ds-private.h:20
librealsense::ds::try_get_d400_intrinsic_by_resolution_new
bool try_get_d400_intrinsic_by_resolution_new(const vector< uint8_t > &raw_data, uint32_t width, uint32_t height, rs2_intrinsics *result)
Definition: d400-private.cpp:294
librealsense::ds::get_d400_intrinsic_by_resolution
rs2_intrinsics get_d400_intrinsic_by_resolution(const vector< uint8_t > &raw_data, d400_calibration_table_id table_id, uint32_t width, uint32_t height)
Definition: d400-private.cpp:105
librealsense::ds::RS435I_PID
const uint16_t RS435I_PID
Definition: d400-private.h:33
librealsense::ds::RS405U_PID
const uint16_t RS405U_PID
Definition: d400-private.h:32
librealsense::ds::ds_caps
ds_caps
Definition: ds-private.h:191
RS2_DISTORTION_BROWN_CONRADY
@ RS2_DISTORTION_BROWN_CONRADY
Definition: rs_types.h:51
librealsense::ds::RS400_IMU_PID
const uint16_t RS400_IMU_PID
Definition: d400-private.h:24
fps.info
info
Definition: fps.py:50
find_librs_version.patch
patch
Definition: find_librs_version.py:28
librealsense::ds::res_640_480
@ res_640_480
Definition: ds-private.h:272
librealsense::ds::res_640_360
@ res_640_360
Definition: ds-private.h:274
librealsense::ds::get_d400_color_stream_intrinsic
rs2_intrinsics get_d400_color_stream_intrinsic(const std::vector< uint8_t > &raw_data, uint32_t width, uint32_t height)
Definition: d400-private.cpp:240
librealsense::ds::RS405_PID
const uint16_t RS405_PID
Definition: d400-private.h:37
rsutils::string::from
Definition: from.h:19
test-fps.ds
ds
Definition: test-fps.py:77
std
Definition: android_helpers.h:13
librealsense::ds::get_d400_color_stream_extrinsic
pose get_d400_color_stream_extrinsic(const std::vector< uint8_t > &raw_data)
Definition: d400-private.cpp:226
realdds::topics::notification::stream_options::key::intrinsics
const std::string intrinsics
Definition: test-unit-transform.py:20
librealsense::ds::res_424_240
@ res_424_240
Definition: ds-private.h:275
librealsense::ds::get_d400_intrinsic_by_resolution_coefficients_table
rs2_intrinsics get_d400_intrinsic_by_resolution_coefficients_table(const std::vector< uint8_t > &raw_data, uint32_t width, uint32_t height)
Definition: d400-private.cpp:126
librealsense::ds::extract_firmware_version_string
std::string extract_firmware_version_string(const std::vector< uint8_t > &fw_image)
Definition: d400-private.cpp:88
librealsense::ds::RS430_PID
const uint16_t RS430_PID
Definition: d400-private.h:19
librealsense::ds::ds_rect_resolutions
ds_rect_resolutions
Definition: ds-private.h:268
librealsense::ds::max_ds_rect_resolutions
@ max_ds_rect_resolutions
Definition: ds-private.h:287
librealsense::ds::res_480_270
@ res_480_270
Definition: ds-private.h:277
librealsense::ds::d400_calibration_table_id
d400_calibration_table_id
Definition: d400-private.h:181
it
static auto it
Definition: openvino-face-detection.cpp:375
test-depth.result
result
Definition: test-depth.py:183
librealsense::ds::RS400_PID
const uint16_t RS400_PID
Definition: d400-private.h:16
librealsense::ds::RS430I_PID
const uint16_t RS430I_PID
Definition: d400-private.h:35
librealsense::not_implemented_exception
Definition: librealsense-exception.h:134
rsutils::number::float3::z
float z
Definition: third-party/rsutils/include/rsutils/number/float3.h:37
find_librs_version.major
major
Definition: find_librs_version.py:18
librealsense::platform::uvc_device_info
Definition: uvc-device-info.h:15
rsutils::number::float3
Definition: third-party/rsutils/include/rsutils/number/float3.h:35
librealsense::ds::RS430_MM_PID
const uint16_t RS430_MM_PID
Definition: d400-private.h:20
RS2_DISTORTION_INVERSE_BROWN_CONRADY
@ RS2_DISTORTION_INVERSE_BROWN_CONRADY
Definition: rs_types.h:49
librealsense::pose
Definition: src/pose.h:16
librealsense::platform::usb_device_info
Definition: usb-types.h:146


librealsense2
Author(s): LibRealSense ROS Team
autogenerated on Fri Aug 2 2024 08:30:02