35 #ifdef ROS_DISTRO_IS_ROLLING
36 #include <tf2_ros/transform_listener.hpp>
38 #include <tf2_ros/transform_listener.h>
41 #include <Eigen/Eigen>
42 #include <auterion_core_msgs/msg/camera_info.hpp>
43 #include <auterion_core_msgs/msg/image1m.hpp>
44 #include <auterion_core_msgs/msg/image8m.hpp>
47 #include <opencv2/core/mat.hpp>
48 #include <rclcpp/rclcpp.hpp>
49 #include <sensor_msgs/msg/camera_info.hpp>
57 using namespace std::chrono_literals;
60 class CameraMonitorImpl;
89 ImageHeader(
int width_,
int height_, Encoding encoding_,
int step_ = 0);
91 template <
typename ImageT = auterion_core_msgs::msg::Image8m>
93 : width(image.width), height(image.height), step(image.step), timestamp(image.stamp) {
94 const int encoding_len =
95 strnlen(
reinterpret_cast<const char*
>(image.encoding.data()), image.encoding.size());
96 const std::string encoding_str(
reinterpret_cast<const char*
>(image.encoding.data()),
98 if (encoding_str ==
"mono8") {
99 encoding = Encoding::Y800;
100 }
else if (encoding_str ==
"mono16") {
101 encoding = Encoding::Y16;
102 }
else if (encoding_str ==
"uyvy") {
103 encoding = Encoding::UYVY;
104 }
else if (encoding_str ==
"yuyv") {
105 encoding = Encoding::YUY2;
106 }
else if (encoding_str ==
"i420") {
109 encoding = Encoding::I420;
110 }
else if (encoding_str ==
"nv12") {
112 encoding = Encoding::NV12;
113 }
else if (encoding_str ==
"rgb8") {
114 encoding = Encoding::RGB8;
115 }
else if (encoding_str ==
"rgba8") {
116 encoding = Encoding::RGBA;
117 }
else if (encoding_str ==
"bgr8") {
118 encoding = Encoding::BGR8;
119 }
else if (encoding_str ==
"bayer_bggr8") {
120 encoding = Encoding::BA81;
121 }
else if (encoding_str ==
"bayer_gbrg8") {
122 encoding = Encoding::GBRG;
123 }
else if (encoding_str ==
"bayer_grbg8") {
124 encoding = Encoding::GRBG;
125 }
else if (encoding_str ==
"bayer_rggb8") {
126 encoding = Encoding::RGGB;
130 template <
typename ImageT = auterion_core_msgs::msg::Image8m>
131 void toImage(ImageT& image) {
133 image.height = height;
135 image.stamp = timestamp;
137 case Encoding::Unknown:
138 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"unknown",
139 image.encoding.size());
142 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"mono8",
143 image.encoding.size());
146 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"mono16",
147 image.encoding.size());
150 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"uyvy",
151 image.encoding.size());
154 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"yuyv",
155 image.encoding.size());
158 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"i420",
159 image.encoding.size());
162 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"nv12",
163 image.encoding.size());
166 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"rgb8",
167 image.encoding.size());
170 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"bgr8",
171 image.encoding.size());
174 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"rgba8",
175 image.encoding.size());
178 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"bayer_bggr8",
179 image.encoding.size());
182 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"bayer_gbrg8",
183 image.encoding.size());
186 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"bayer_grbg8",
187 image.encoding.size());
190 strncpy(
reinterpret_cast<char*
>(image.encoding.data()),
"bayer_rggb8",
191 image.encoding.size());
196 size_t planeOffset(
int plane)
const;
197 size_t planeSizeBytes(
int plane)
const;
198 size_t imageSizeBytes()
const;
203 Encoding encoding{Encoding::Unknown};
204 rclcpp::Time timestamp{};
215 Image(
ImageHeader header, uint8_t* data) : _header(std::move(header)), _data(data) {}
217 const ImageHeader& header()
const {
return _header; }
219 uint8_t* data() {
return _data; }
220 const uint8_t* data()
const {
return _data; }
222 int width()
const {
return _header.width; }
223 int height()
const {
return _header.height; }
233 uint8_t* _data{
nullptr};
241 enum class SensorType {
249 enum class MountOrientation {
259 enum class MountOrientationDetail {
266 enum class PrimaryPurpose {
276 Eigen::Quaterniond rotation{-0.5, 0.5, -0.5, 0.5};
277 Eigen::Vector3d translation{0.0, 0.0, 0.0};
281 explicit CameraDescriptor(
const auterion_core_msgs::msg::CameraInfo& camera_info);
283 operator auterion_core_msgs::msg::CameraInfo()
const;
285 std::string unique_name;
287 std::string camera_model;
289 SensorType sensor_type{SensorType::Unknown};
290 MountOrientation mount_orientation{MountOrientation::Unknown};
291 MountOrientationDetail mount_orientation_detail{MountOrientationDetail::Unknown};
292 PrimaryPurpose primary_purpose{PrimaryPurpose::Unknown};
293 ExtrinsicCalibration extrinsic_calibration;
306 const NotificationCallback& on_camera_removed =
nullptr);
311 std::shared_ptr<CameraMonitorImpl> _impl;
330 "waitForCamera with 'camera_descriptor' not used anymore. This will be removed in some "
331 "later release.")]]
static Camera
332 waitForCamera(
SDK& sdk,
333 std::optional<auterion::CameraDescriptor> camera_descriptor = std::nullopt);
335 static std::optional<Camera> open(
SDK& sdk,
const std::string& unique_name,
336 const std::chrono::seconds& timeout = 30s);
337 static std::optional<Camera> open(
339 const std::chrono::seconds& timeout = 30s);
340 static std::optional<Camera> openFirst(
SDK& sdk,
const std::chrono::seconds& timeout = 30s);
342 using ImageCallback = std::function<void(
const Image& image)>;
351 void subscribeCameraInfo(
352 std::function<
void(
const sensor_msgs::msg::CameraInfo::SharedPtr)> callback);
389 bool getPoseBodyCamera(Eigen::Quaterniond& q_body_camera, Eigen::Vector3d& t_body_camera)
const;
410 const tf2::TimePoint& time = tf2::TimePointZero)
const;
442 tf2::TimePoint& time_start, tf2::TimePoint& time_end);
455 std::shared_ptr<CameraImpl> _impl;
Monitor for new or removed cameras. This will also list all existing cameras upon creating the object...
Definition: camera.hpp:301
Camera client to subscribe to a camera image stream.
Definition: camera.hpp:318
bool cameraInfoValid() const
Determine whether a camera info message contains valid data.
bool getCameraInfo(sensor_msgs::msg::CameraInfo &camera_info) const
Get the camera information data for the camera.
bool getPoseBodyCamera(Eigen::Quaterniond &q_body_camera, Eigen::Vector3d &t_body_camera) const
Get the pose of the camera with respect to the body frame.
void subscribeImage(const ImageCallback &callback)
std::optional< cv::Size > getLastImageSize() const
Returns the last image size based on the camera image message.
Eigen::Vector3d unprojectImagePoint(const cv::Point &image_point) const
Determine the (relative) camera-frame 3D position of a point in an image.
bool getDeltaRotationWorldCamera(Eigen::Quaterniond &q_delta_world_camera, tf2::TimePoint &time_start, tf2::TimePoint &time_end)
Calculates how much the camera has rotated between two points in time based only on gyro data.
static Camera waitForCamera(SDK &sdk, const std::function< bool(const CameraDescriptor &)> &find_callback)
bool getPoseWorldCamera(Eigen::Quaterniond &q_enu_camera, Eigen::Vector3d &t_enu_camera, const tf2::TimePoint &time=tf2::TimePointZero) const
Get the pose of the camera with respect to the ENU world frame.
Contains image data with a specific encoding.
Definition: camera.hpp:213
cv::Mat asOpenCVMat(int plane=-1) const
SDK execution class. All callbacks are called on the same thread.
Definition: auterion.hpp:97
std::ostream & operator<<(std::ostream &os, const TrackingState &state)
Overloaded << operator to stringify the TrackingState enum.
Definition: camera.hpp:275
Struct describing a camera configuration.
Definition: camera.hpp:240