Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
ZEDCam Class Reference

This class implements and interfaces with the most common ZEDSDK cameras and features. It is designed in such a way that multiple other classes/threads can safely call any method of an object of this class withing resource corruption or slowdown of the camera. More...

#include <ZEDCam.h>

Inheritance diagram for ZEDCam:
Collaboration diagram for ZEDCam:

Public Member Functions

 ZEDCam (const int nPropResolutionX, const int nPropResolutionY, const int nPropFramesPerSecond, const double dPropHorizontalFOV, const double dPropVerticalFOV, const bool bEnableRecordingFlag=false, const bool bExportSVORecordingFlag=false, const float fMinSenseDistance=constants::ZED_DEFAULT_MINIMUM_DISTANCE, const float fMaxSenseDistance=constants::ZED_DEFAULT_MAXIMUM_DISTANCE, const bool bMemTypeGPU=false, const bool bUseHalfDepthPrecision=false, const int nNumFrameRetrievalThreads=10, const unsigned int unCameraSerialNumber=0)
 Construct a new Zed Cam:: Zed Cam object.
 
 ~ZEDCam ()
 Destroy the Zed Cam:: Zed Cam object.
 
std::future< bool > RequestFrameCopy (cv::Mat &cvFrame) override
 Requests a regular BGRA image from the LEFT eye of the zed camera. Puts a frame pointer into a queue so a copy of a frame from the camera can be written to it. Remember this code will be ran in whatever class/thread calls it.
 
std::future< bool > RequestFrameCopy (cv::cuda::GpuMat &cvGPUFrame) override
 Grabs a regular BGRA image from the LEFT eye of the zed camera and stores it in a GPU mat. Puts a frame pointer into a queue so a copy of a frame from the camera can be written to it. Remember this code will be ran in whatever class/thread calls it.
 
std::future< bool > RequestDepthCopy (cv::Mat &cvDepth, const bool bRetrieveMeasure=true) override
 Requests a depth measure or image from the camera. Puts a frame pointer into a queue so a copy of a frame from the camera can be written to it. This image has the same shape as a grayscale image, but the values represent the depth in MILLIMETERS. The ZEDSDK will always return this measure in MILLIMETERS.
 
std::future< bool > RequestDepthCopy (cv::cuda::GpuMat &cvGPUDepth, const bool bRetrieveMeasure=true) override
 Requests a depth measure or image from the camera. Puts a frame pointer into a queue so a copy of a frame from the camera can be written to it. This image has the same shape as a grayscale image, but the values represent the depth in MILLIMETERS. The ZEDSDK will always return this measure in MILLIMETERS.
 
std::future< bool > RequestPointCloudCopy (cv::Mat &cvPointCloud) override
 Requests a point cloud image from the camera. This image has the same resolution as a normal image but with three XYZ values replacing the old color values in the 3rd dimension. The units and sign of the XYZ values are determined by ZED_MEASURE_UNITS and ZED_COORD_SYSTEM constants set in AutonomyConstants.h.
 
std::future< bool > RequestPointCloudCopy (cv::cuda::GpuMat &cvGPUPointCloud) override
 Grabs a point cloud image from the camera. This image has the same resolution as a normal image but with three XYZ values replacing the old color values in the 3rd dimension. The units and sign of the XYZ values are determined by ZED_MEASURE_UNITS and ZED_COORD_SYSTEM constants set in AutonomyConstants.h.
 
std::future< bool > RequestPositionalPoseCopy (Pose &stPose) override
 Requests the current pose of the camera relative to it's start pose or the origin of the set pose. Puts a Pose pointer into a queue so a copy of a pose from the camera can be written to it. If positional tracking is not enabled, this method will return false and the ZEDCam::Pose may be uninitialized.
 
std::future< bool > RequestFloorPlaneCopy (sl::Plane &slPlane) override
 Requests the current floor plane of the camera relative to it's current pose. Puts a Plane pointer into a queue so a copy of the floor plane from the camera can be written to it. If positional tracking is not enabled, this method will return false and the sl::Plane may be uninitialized.
 
std::future< bool > RequestSensorsCopy (sl::SensorsData &slSensorsData) override
 Requests the most up to date sensors data from the camera. This data include IMU pose and raw values, barometer, magnetometer, and temperature data.
 
std::future< bool > RequestObjectsCopy (std::vector< sl::ObjectData > &vObjectData) override
 Requests a current copy of the tracked objects from the camera. Puts a pointer to a vector containing sl::ObjectData into a queue so a copy of a frame from the camera can be written to it.
 
std::future< bool > RequestBatchedObjectsCopy (std::vector< sl::ObjectsBatch > &vBatchedObjectData) override
 If batching is enabled, this requests the normal objects and passes them to the the internal batching queue of the zed api. This performs short-term re-identification with deep learning and trajectories filtering. Batching must have been set to enabled when EnableObjectDetection() was called. Most of the time the vector will be empty and will be filled every ZED_OBJDETECTION_BATCH_LATENCY.
 
sl::ERROR_CODE ResetPositionalTracking () override
 Resets the cameras X,Y,Z translation and Roll,Pitch,Yaw orientation back to 0. THINK CAREFULLY! Do you actually want to reset this? It will also realign the coordinate system to whichever way the camera happens to be facing.
 
sl::ERROR_CODE TrackCustomBoxObjects (std::vector< ZedObjectData > &vCustomObjects) override
 A vector containing CustomBoxObjectData objects. These objects simply store information about your detected objects from an external object detection model. You will need to take your inference results and package them into a sl::CustomBoxObjectData so the the ZEDSDK can properly interpret your detections.
 
sl::ERROR_CODE RebootCamera () override
 Performs a hardware reset of the ZED2 or ZED2i camera.
 
sl::ERROR_CODE EnablePositionalTracking (const float fExpectedCameraHeightFromFloorTolerance=constants::ZED_DEFAULT_FLOOR_PLANE_ERROR) override
 Enable the positional tracking functionality of the camera.
 
void DisablePositionalTracking () override
 Disable to positional tracking functionality of the camera.
 
void SetPositionalPose (const double dX, const double dY, const double dZ, const double dXO, const double dYO, const double dZO) override
 Sets the pose of the positional tracking of the camera. XYZ will point in their respective directions according to ZED_COORD_SYSTEM defined in AutonomyConstants.h.
 
sl::ERROR_CODE EnableSpatialMapping () override
 Enabled the spatial mapping feature of the camera. Pose tracking will be enabled if it is not already.
 
void DisableSpatialMapping () override
 Disabled the spatial mapping feature of the camera.
 
sl::ERROR_CODE EnableObjectDetection (const bool bEnableBatching=false) override
 Enables the object detection and tracking feature of the camera.
 
void DisableObjectDetection () override
 Disables the object detection and tracking feature of the camera.
 
bool GetCameraIsOpen () override
 Accessor for the current status of the camera.
 
bool GetUsingGPUMem () const override
 Accessor for if this ZED is storing it's frames in GPU memory.
 
std::string GetCameraModel () override
 Accessor for the model enum from the ZEDSDK and represents the camera model as a string.
 
unsigned int GetCameraSerial () override
 Accessor for the camera's serial number.
 
bool GetPositionalTrackingEnabled () override
 Accessor for if the positional tracking functionality of the camera has been enabled and functioning.
 
sl::PositionalTrackingStatus GetPositionalTrackingState () override
 Accessor for the current positional tracking status of the camera.
 
sl::SPATIAL_MAPPING_STATE GetSpatialMappingState () override
 Accessor for the current state of the camera's spatial mapping feature.
 
sl::SPATIAL_MAPPING_STATE ExtractSpatialMapAsync (std::future< sl::Mesh > &fuMeshFuture) override
 Retrieve the built spatial map from the camera. Spatial mapping must be enabled. This method takes in an std::future<sl::FusedPointCloud> to eventually store the map in. It returns a enum code representing the successful scheduling of building the map. Any code other than SPATIAL_MAPPING_STATE::OK means the future will never be filled.
 
bool GetObjectDetectionEnabled () override
 Accessor for if the cameras object detection and tracking feature is enabled.
 
- Public Member Functions inherited from ZEDCamera
 ZEDCamera (const int nPropResolutionX, const int nPropResolutionY, const int nPropFramesPerSecond, const double dPropHorizontalFOV, const double dPropVerticalFOV, const bool bEnableRecordingFlag, const bool bMemTypeGPU, const bool bUseHalfDepthPrecision, const int nNumFrameRetrievalThreads, const unsigned int unCameraSerialNumber)
 Construct a new ZEDCamera object.
 
virtual ~ZEDCamera ()=default
 Destroy the ZEDCamera object.
 
- Public Member Functions inherited from Camera< cv::Mat >
 Camera (const int nPropResolutionX, const int nPropResolutionY, const int nPropFramesPerSecond, const PIXEL_FORMATS ePropPixelFormat, const double dPropHorizontalFOV, const double dPropVerticalFOV, const bool bEnableRecordingFlag, const int nNumFrameRetrievalThreads=5)
 Construct a new Camera object.
 
virtual ~Camera ()
 Destroy the Camera object.
 
void SetEnableRecordingFlag (const bool bEnableRecordingFlag)
 Mutator for the Enable Recording Flag private member.
 
void SetCameraPoseOffset (const Pose &stPoseOffset)
 Mutator for the Camera Pose Offset private member.
 
void SetCameraPoseOffset (const double dPosX, const double dPosY, const double dPosZ, const double dQX, const double dQY, const double dQZ, const double dQW)
 Mutator for the Camera Pose Offset private member.
 
cv::Size GetPropResolution () const
 Accessor for the Prop Resolution private member.
 
int GetPropFramesPerSecond () const
 Accessor for the Prop Frames Per Second private member.
 
PIXEL_FORMATS GetPropPixelFormat () const
 Accessor for the Prop Pixel Format private member.
 
double GetPropHorizontalFOV () const
 Accessor for the Prop Horizontal F O V private member.
 
double GetPropVerticalFOV () const
 Accessor for the Prop Vertical F O V private member.
 
bool GetEnableRecordingFlag () const
 Accessor for the Enable Recording Flag private member.
 
Pose GetCameraPoseOffset () const
 Accessor for the Camera Pose Offset private member.
 
- Public Member Functions inherited from AutonomyThread< void >
 AutonomyThread ()
 Construct a new Autonomy Thread object.
 
virtual ~AutonomyThread ()
 Destroy the Autonomy Thread object. If the parent object or main thread is destroyed or exited while this thread is still running, a race condition will occur. Stopping and joining the thread here insures that the main program can't exit if the user forgot to stop and join the thread.
 
void Start ()
 When this method is called, it starts a new thread that runs the code within the ThreadedContinuousCode method. This is the users main code that will run the important and continuous code for the class.
 
void RequestStop ()
 Signals threads to stop executing user code, terminate. DOES NOT JOIN. This method will not force the thread to exit, if the user code is not written properly and contains WHILE statement or any other long-executing or blocking code, then the thread will not exit until the next iteration.
 
void Join ()
 Waits for thread to finish executing and then closes thread. This method will block the calling code until thread is finished.
 
bool Joinable () const
 Check if the code within the thread and all pools created by it are finished executing and the thread is ready to be closed.
 
AutonomyThreadState GetThreadState () const
 Accessor for the Threads State private member.
 
std::string GetThreadUUID () const
 Accessor for the Thread U U I D private member.
 
IPSGetIPS ()
 Accessor for the Frame I P S private member.
 
void SetMainThreadPriority (AutonomyThreadPriority ePriority)
 Set the OS priority for the main continuous thread.
 
void SetPoolThreadPriority (AutonomyThreadPriority ePriority)
 Set the OS priority for the highly parallelized pool threads.
 

Private Member Functions

void ThreadedContinuousCode () override
 The code inside this private method runs in a separate thread, but still has access to this*. This method continuously calls the grab() function of the ZEDSDK, which updates all frames (RGB, depth, cloud) and all other data such as positional and spatial mapping. Then a thread pool is started and joined once per iteration to mass copy the frames and/or measure to any other thread waiting in the queues.
 
void PooledLinearCode () override
 This method holds the code that is ran in the thread pool started by the ThreadedLinearCode() method. It copies the data from the different data objects to references of the same type stored in a queue filled by the Request methods.
 

Private Attributes

sl::Camera m_slCamera
 
std::shared_mutex m_muCameraMutex
 
sl::InitParameters m_slCameraParams
 
sl::RuntimeParameters m_slRuntimeParams
 
sl::RecordingParameters m_slRecordingParams
 
sl::MEASURE m_slDepthMeasureType
 
sl::PositionalTrackingParameters m_slPoseTrackingParams
 
sl::Pose m_slCameraPose
 
sl::Plane m_slFloorPlane
 
sl::Transform m_slFloorTrackingTransform
 
sl::SensorsData m_slSensorsData
 
sl::SpatialMappingParameters m_slSpatialMappingParams
 
sl::ObjectDetectionParameters m_slObjectDetectionParams
 
sl::BatchParameters m_slObjectDetectionBatchParams
 
sl::Objects m_slDetectedObjects
 
std::vector< sl::ObjectsBatch > m_slDetectedObjectsBatched
 
sl::MEM m_slMemoryType
 
sl::MODEL m_slCameraModel
 
float m_fExpectedCameraHeightFromFloorTolerance
 
bool m_bCameraReopenAlreadyChecked
 
bool m_bEnablePositionalTrackingFlag
 
bool m_bEnableSpatialMappingFlag
 
bool m_bEnableObjectDetectionFlag
 
double m_dPoseOffsetX
 
double m_dPoseOffsetY
 
double m_dPoseOffsetZ
 
double m_dPoseOffsetXO
 
double m_dPoseOffsetYO
 
double m_dPoseOffsetZO
 
geoops::GPSCoordinate m_stCurrentGPSBasedPosition
 
sl::Mat m_slFrame
 
sl::Mat m_slDepthImage
 
sl::Mat m_slDepthMeasure
 
sl::Mat m_slPointCloud
 
std::queue< containers::FrameFetchContainer< cv::cuda::GpuMat > > m_qGPUFrameCopySchedule
 
std::queue< containers::DataFetchContainer< std::vector< ZedObjectData > > > m_qCustomBoxIngestSchedule
 
std::queue< containers::DataFetchContainer< Pose > > m_qPoseCopySchedule
 
std::queue< containers::DataFetchContainer< sl::Plane > > m_qFloorCopySchedule
 
std::queue< containers::DataFetchContainer< sl::SensorsData > > m_qSensorsCopySchedule
 
std::queue< containers::DataFetchContainer< std::vector< sl::ObjectData > > > m_qObjectDataCopySchedule
 
std::queue< containers::DataFetchContainer< std::vector< sl::ObjectsBatch > > > m_qObjectBatchedDataCopySchedule
 
std::shared_mutex m_muCustomBoxIngestMutex
 
std::shared_mutex m_muPoseCopyMutex
 
std::shared_mutex m_muFloorCopyMutex
 
std::shared_mutex m_muSensorsCopyMutex
 
std::shared_mutex m_muObjectDataCopyMutex
 
std::shared_mutex m_muObjectBatchedDataCopyMutex
 
bool m_bQueueTogglesAlreadyReset
 
std::atomic< bool > m_bNormalFramesQueued
 
std::atomic< bool > m_bDepthFramesQueued
 
std::atomic< bool > m_bPointCloudsQueued
 
std::atomic< bool > m_bPosesQueued
 
std::atomic< bool > m_bFloorsQueued
 
std::atomic< bool > m_bSensorsQueued
 
std::atomic< bool > m_bObjectsQueued
 
std::atomic< bool > m_bBatchedObjectsQueued
 

Additional Inherited Members

- Public Types inherited from AutonomyThread< void >
enum  AutonomyThreadState
 
enum  AutonomyThreadPriority
 
- Protected Member Functions inherited from AutonomyThread< void >
void RunPool (const unsigned int nNumTasksToQueue, const unsigned int nNumThreads=2, const bool bForceStopCurrentThreads=false)
 When this method is called, it starts/adds tasks to a thread pool that runs nNumTasksToQueue copies of the code within the PooledLinearCode() method using nNumThreads number of threads. This is meant to be used as an internal utility of the child class to further improve parallelization. Default value for nNumThreads is 2.
 
void RunDetachedPool (const unsigned int nNumTasksToQueue, const unsigned int nNumThreads=2, const bool bForceStopCurrentThreads=false)
 When this method is called, it starts a thread pool full of threads that don't return std::futures (like a placeholder for the thread return type). This means the thread will not have a return type and there is no way to determine if the thread has finished other than calling the Join() method. Only use this if you want to 'set and forget'. It will be faster as it doesn't return futures. Runs PooledLinearCode() method code. This is meant to be used as an internal utility of the child class to further improve parallelization.
 
void ParallelizeLoop (const int nNumThreads, const N tTotalIterations, F &&tLoopFunction)
 Given a ref-qualified looping function and an arbitrary number of iterations, this method will divide up the loop and run each section in a thread pool. This function must not return anything. This method will block until the loop has completed.
 
void ClearPoolQueue ()
 Clears any tasks waiting to be ran in the queue, tasks currently running will remain running.
 
void JoinPool ()
 Waits for pool to finish executing tasks. This method will block the calling code until thread is finished.
 
bool PoolJoinable () const
 Check if the internal pool threads are done executing code and the queue is empty.
 
void SetMainThreadIPSLimit (int nMaxIterationsPerSecond=0)
 Mutator for the Main Thread Max I P S private member.
 
int GetPoolNumOfThreads ()
 Accessor for the Pool Num Of Threads private member.
 
int GetPoolQueueLength ()
 Accessor for the Pool Queue Size private member.
 
std::vector< void > GetPoolResults ()
 Accessor for the Pool Results private member. The action of getting results will destroy and remove them from this object. This method blocks if the thread is not finished, so no need to call JoinPool() before getting results.
 
int GetMainThreadMaxIPS () const
 Accessor for the Main Thread Max I P S private member.
 
- Protected Attributes inherited from ZEDCamera
const std::memory_order ATOMIC_MEMORY_ORDER_METHOD = std::memory_order_relaxed
 
unsigned int m_unCameraSerialNumber
 
- Protected Attributes inherited from Camera< cv::Mat >
int m_nPropResolutionX
 
int m_nPropResolutionY
 
int m_nPropFramesPerSecond
 
int m_nNumFrameRetrievalThreads
 
PIXEL_FORMATS m_ePropPixelFormat
 
double m_dPropHorizontalFOV
 
double m_dPropVerticalFOV
 
Pose m_stCameraPoseOffset
 
std::atomic_bool m_bEnableRecordingFlag
 
std::queue< containers::FrameFetchContainer< cv::Mat > > m_qFrameCopySchedule
 
std::shared_mutex m_muPoolScheduleMutex
 
std::shared_mutex m_muFrameCopyMutex
 
- Protected Attributes inherited from AutonomyThread< void >
IPS m_IPS
 

Detailed Description

This class implements and interfaces with the most common ZEDSDK cameras and features. It is designed in such a way that multiple other classes/threads can safely call any method of an object of this class withing resource corruption or slowdown of the camera.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-09-21

Constructor & Destructor Documentation

◆ ZEDCam()

ZEDCam::ZEDCam ( const int  nPropResolutionX,
const int  nPropResolutionY,
const int  nPropFramesPerSecond,
const double  dPropHorizontalFOV,
const double  dPropVerticalFOV,
const bool  bEnableRecordingFlag = false,
const bool  bExportSVORecordingFlag = false,
const float  fMinSenseDistance = constants::ZED_DEFAULT_MINIMUM_DISTANCE,
const float  fMaxSenseDistance = constants::ZED_DEFAULT_MAXIMUM_DISTANCE,
const bool  bMemTypeGPU = false,
const bool  bUseHalfDepthPrecision = false,
const int  nNumFrameRetrievalThreads = 10,
const unsigned int  unCameraSerialNumber = 0 
)

Construct a new Zed Cam:: Zed Cam object.

Parameters
nPropResolutionX- X res of camera. Must be smaller than ZED_BASE_RESOLUTION.
nPropResolutionY- Y res of camera. Must be smaller than ZED_BASE_RESOLUTION.
nPropFramesPerSecond- FPS camera is running at.
dPropHorizontalFOV- The horizontal field of view.
dPropVerticalFOV- The vertical field of view.
bEnableRecordingFlag- Whether or not this camera should be recorded.
fMinSenseDistance- The minimum distance to include in depth measures.
fMaxSenseDistance- The maximum distance to include in depth measures.
bMemTypeGPU- Whether or not to use the GPU memory for operations.
bUseHalfPrecision- Whether or not to use a float16 instead of float32 for depth measurements.
bEnableFusionMaster- Enables ZEDSDK Fusion integration for this camera. This camera will serve as the master instance for all fusion functions.
nNumFrameRetrievalThreads- The number of threads to use for copying frames/data to requests.
unCameraSerialNumber- The serial number of the camera to open.
Note
Do not set bEnableFusionMaster to true if you want to subscribe the camera to another camera! Only one camera should have Fusion enabled! To subscribe a camera to the camera running the master fusion instance, use the GetFusionInstance() and GetCameraSerial() functions. Refer to Fusion documentation for info on working with fusion functions: https://www.stereolabs.com/docs/api/classsl_1_1Fusion.html
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-26
52 :
53 ZEDCamera(nPropResolutionX,
54 nPropResolutionY,
55 nPropFramesPerSecond,
56 dPropHorizontalFOV,
57 dPropVerticalFOV,
58 bEnableRecordingFlag,
59 bMemTypeGPU,
60 bUseHalfDepthPrecision,
61 nNumFrameRetrievalThreads,
62 unCameraSerialNumber)
63{
64 // Assign member variables.
65 bMemTypeGPU ? m_slMemoryType = sl::MEM::GPU : m_slMemoryType = sl::MEM::CPU;
66 bUseHalfDepthPrecision ? m_slDepthMeasureType = sl::MEASURE::DEPTH_U16_MM : m_slDepthMeasureType = sl::MEASURE::DEPTH;
67 m_dPoseOffsetX = 0.0;
68 m_dPoseOffsetY = 0.0;
69 m_dPoseOffsetZ = 0.0;
70 m_dPoseOffsetXO = 0.0;
71 m_dPoseOffsetYO = 0.0;
72 m_dPoseOffsetZO = 0.0;
73 m_bEnablePositionalTrackingFlag = false;
74 m_bEnableSpatialMappingFlag = false;
75 m_bEnableObjectDetectionFlag = false;
76 m_bCameraReopenAlreadyChecked = false;
77 // Initialize queued toggles.
78 m_bQueueTogglesAlreadyReset = false;
79 m_bNormalFramesQueued = false;
80 m_bDepthFramesQueued = false;
81 m_bPointCloudsQueued = false;
82 m_bPosesQueued = false;
83 m_bFloorsQueued = false;
84 m_bObjectsQueued = false;
85 m_bBatchedObjectsQueued = false;
86
87 // Setup camera params.
88 m_slCameraParams.camera_resolution = constants::ZED_BASE_RESOLUTION;
89 m_slCameraParams.camera_fps = nPropFramesPerSecond;
90 m_slCameraParams.coordinate_units = constants::ZED_MEASURE_UNITS;
91 m_slCameraParams.coordinate_system = constants::ZED_COORD_SYSTEM;
92 m_slCameraParams.sdk_verbose = constants::ZED_SDK_VERBOSE;
93 m_slCameraParams.depth_mode = constants::ZED_DEPTH_MODE;
94 m_slCameraParams.depth_minimum_distance = fMinSenseDistance;
95 m_slCameraParams.depth_maximum_distance = fMaxSenseDistance;
96 m_slCameraParams.depth_stabilization = constants::ZED_DEPTH_STABILIZATION;
97 // Only set serial number if necessary.
98 if (unCameraSerialNumber != static_cast<unsigned int>(0))
99 {
100 m_slCameraParams.input.setFromSerialNumber(unCameraSerialNumber);
101 }
102
103 // Setup camera runtime params.
104 m_slRuntimeParams.enable_fill_mode = constants::ZED_SENSING_FILL;
105 // Setup SVO recording parameters.
106 m_slRecordingParams.compression_mode = constants::ZED_SVO_COMPRESSION;
107 m_slRecordingParams.bitrate = constants::ZED_SVO_BITRATE;
108
109 // Setup positional tracking parameters.
110 m_slPoseTrackingParams.mode = constants::ZED_POSETRACK_MODE;
111 m_slPoseTrackingParams.enable_area_memory = constants::ZED_POSETRACK_AREA_MEMORY;
112 m_slPoseTrackingParams.enable_pose_smoothing = constants::ZED_POSETRACK_POSE_SMOOTHING;
113 m_slPoseTrackingParams.set_floor_as_origin = constants::ZED_POSETRACK_FLOOR_IS_ORIGIN;
114 m_slPoseTrackingParams.enable_imu_fusion = constants::ZED_POSETRACK_ENABLE_IMU_FUSION;
115 m_slPoseTrackingParams.depth_min_range = constants::ZED_POSETRACK_USABLE_DEPTH_MIN;
116 m_slPoseTrackingParams.set_gravity_as_origin = constants::ZED_POSETRACK_USE_GRAVITY_ORIGIN;
117
118 // Setup spatial mapping parameters.
119 m_slSpatialMappingParams.map_type = constants::ZED_MAPPING_TYPE;
120 m_slSpatialMappingParams.resolution_meter = constants::ZED_MAPPING_RESOLUTION_METER;
121 m_slSpatialMappingParams.save_texture = true;
122 m_slSpatialMappingParams.use_chunk_only = constants::ZED_MAPPING_USE_CHUNK_ONLY;
123 m_slSpatialMappingParams.stability_counter = constants::ZED_MAPPING_STABILITY_COUNTER;
124 // Set or auto-set max depth range for mapping.
125 if (constants::ZED_MAPPING_RANGE_METER <= 0)
126 {
127 // Automatically guess the best mapping depth range.
128 m_slSpatialMappingParams.range_meter = m_slSpatialMappingParams.getRecommendedRange(constants::ZED_MAPPING_RESOLUTION_METER, m_slCamera);
129 }
130 else
131 {
132 // Manually set.
133 m_slSpatialMappingParams.range_meter = constants::ZED_MAPPING_RANGE_METER;
134 }
135
136 // Setup object detection/tracking parameters.
137 m_slObjectDetectionParams.detection_model = sl::OBJECT_DETECTION_MODEL::CUSTOM_BOX_OBJECTS;
138 m_slObjectDetectionParams.enable_tracking = constants::ZED_OBJDETECTION_TRACK_OBJ;
139 m_slObjectDetectionParams.enable_segmentation = constants::ZED_OBJDETECTION_SEGMENTATION;
140 m_slObjectDetectionParams.filtering_mode = constants::ZED_OBJDETECTION_FILTERING;
141 m_slObjectDetectionParams.prediction_timeout_s = constants::ZED_OBJDETECTION_TRACKING_PREDICTION_TIMEOUT;
142 // Setup object detection/tracking batch parameters.
143 m_slObjectDetectionBatchParams.enable = false;
144 m_slObjectDetectionBatchParams.id_retention_time = constants::ZED_OBJDETECTION_BATCH_RETENTION_TIME;
145 m_slObjectDetectionBatchParams.latency = constants::ZED_OBJDETECTION_BATCH_LATENCY;
146 m_slObjectDetectionParams.batch_parameters = m_slObjectDetectionBatchParams;
147
148 // Attempt to open camera.
149 sl::ERROR_CODE slReturnCode = m_slCamera.open(m_slCameraParams);
150 // Check if the camera was successfully opened.
151 if (m_slCamera.isOpened())
152 {
153 // Update camera serial number if camera was opened with autodetect.
154 m_unCameraSerialNumber = m_slCamera.getCameraInformation().serial_number;
155 // Update camera model.
156 m_slCameraModel = m_slCamera.getCameraInformation().camera_model;
157 // Check if the camera should record and output an SVO file.
158 if (bExportSVORecordingFlag)
159 {
160 // Now that camera is opened get camera name and construct path.
161 std::string szSVOFilePath = constants::LOGGING_OUTPUT_PATH_ABSOLUTE + "/" + logging::g_szProgramStartTimeString + "/" + this->GetCameraModel() + "_" +
162 std::to_string(this->GetCameraSerial());
163 m_slRecordingParams.video_filename = szSVOFilePath.c_str();
164 // Enable recording.
165 sl::ERROR_CODE slReturnCode = m_slCamera.enableRecording(m_slRecordingParams);
166 // Check if recording was enabled successfully.
167 if (slReturnCode == sl::ERROR_CODE::SUCCESS)
168 {
169 // Submit logger message.
170 LOG_DEBUG(logging::g_qSharedLogger,
171 "Successfully enabled SVO recording for {} ZED stereo camera with serial number {}.",
172 this->GetCameraModel(),
173 m_unCameraSerialNumber);
174 }
175 else
176 {
177 // Submit logger message.
178 LOG_ERROR(logging::g_qSharedLogger,
179 "Failed to enable SVO recording for {} ZED stereo camera with serial number {}. sl::ERROR_CODE is {}",
180 this->GetCameraModel(),
181 m_unCameraSerialNumber,
182 sl::toString(slReturnCode).c_str());
183 }
184 }
185
186 // Submit logger message.
187 LOG_INFO(logging::g_qSharedLogger, "{} ZED stereo camera with serial number {} has been successfully opened.", this->GetCameraModel(), m_unCameraSerialNumber);
188 }
189 else
190 {
191 // Submit logger message.
192 LOG_ERROR(logging::g_qSharedLogger,
193 "Unable to open ZED stereo camera {} ({})! sl::ERROR_CODE is: {}",
194 sl::toString(m_slCameraModel).get(),
195 m_unCameraSerialNumber,
196 sl::toString(slReturnCode).get());
197 }
198
199 // Set max FPS of the ThreadedContinuousCode method.
200 this->SetMainThreadIPSLimit(nPropFramesPerSecond);
201}
void SetMainThreadIPSLimit(int nMaxIterationsPerSecond=0)
Mutator for the Main Thread Max I P S private member.
Definition AutonomyThread.hpp:530
unsigned int GetCameraSerial() override
Accessor for the camera's serial number.
Definition ZEDCam.cpp:1798
std::string GetCameraModel() override
Accessor for the model enum from the ZEDSDK and represents the camera model as a string.
Definition ZEDCam.cpp:1769
This class serves as a middle inheritor between the Camera interface and the ZEDCam class....
Definition ZEDCamera.hpp:33
__host__ cudaTextureObject_t get() const noexcept
Here is the call graph for this function:

◆ ~ZEDCam()

ZEDCam::~ZEDCam ( )

Destroy the Zed Cam:: Zed Cam object.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-26
211{
212 // Stop threaded code.
213 this->RequestStop();
214 this->Join();
215
216 // Close the ZEDCam.
217 m_slCamera.close();
218
219 // Submit logger message.
220 LOG_INFO(logging::g_qSharedLogger, "ZED stereo camera with serial number {} has been successfully closed.", m_unCameraSerialNumber);
221}
void Join()
Waits for thread to finish executing and then closes thread. This method will block the calling code ...
Definition AutonomyThread.hpp:203
void RequestStop()
Signals threads to stop executing user code, terminate. DOES NOT JOIN. This method will not force the...
Definition AutonomyThread.hpp:187
Here is the call graph for this function:

Member Function Documentation

◆ RequestFrameCopy() [1/2]

std::future< bool > ZEDCam::RequestFrameCopy ( cv::Mat cvFrame)
overridevirtual

Requests a regular BGRA image from the LEFT eye of the zed camera. Puts a frame pointer into a queue so a copy of a frame from the camera can be written to it. Remember this code will be ran in whatever class/thread calls it.

Parameters
cvFrame- A reference to the cv::Mat to copy the normal frame to.
Returns
std::future<bool> - A future that should be waited on before the passed in frame is used. Value will be true if frame was successfully retrieved.
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-09-09

Implements ZEDCamera.

865{
866 // Assemble the FrameFetchContainer.
867 containers::FrameFetchContainer<cv::Mat> stContainer(cvFrame, PIXEL_FORMATS::eBGRA);
868
869 // Acquire lock on frame copy queue.
870 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
871 // Append frame fetch container to the schedule queue.
872 m_qFrameCopySchedule.push(stContainer);
873 // Release lock on the frame schedule queue.
874 lkSchedulers.unlock();
875
876 // Check if frame queue toggle has already been set.
877 if (!m_bNormalFramesQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
878 {
879 // Signify that the frame queue is not empty.
880 m_bNormalFramesQueued.store(true, ATOMIC_MEMORY_ORDER_METHOD);
881 }
882
883 // Return the future from the promise stored in the container.
884 return stContainer.pCopiedFrameStatus->get_future();
885}
This struct is used to carry references to camera frames for scheduling and copying....
Definition FetchContainers.hpp:88

◆ RequestFrameCopy() [2/2]

std::future< bool > ZEDCam::RequestFrameCopy ( cv::cuda::GpuMat cvGPUFrame)
overridevirtual

Grabs a regular BGRA image from the LEFT eye of the zed camera and stores it in a GPU mat. Puts a frame pointer into a queue so a copy of a frame from the camera can be written to it. Remember this code will be ran in whatever class/thread calls it.

Parameters
cvGPUFrame- A reference to the cv::Mat to copy the normal frame to.
Returns
std::future<bool> - A future that should be waited on before the passed in frame is used. Value will be true if frame was successfully retrieved.
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-09-09

Reimplemented from ZEDCamera.

900{
901 // Assemble the FrameFetchContainer.
902 containers::FrameFetchContainer<cv::cuda::GpuMat> stContainer(cvGPUFrame, PIXEL_FORMATS::eBGRA);
903
904 // Acquire lock on frame copy queue.
905 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
906 // Append frame fetch container to the schedule queue.
907 m_qGPUFrameCopySchedule.push(stContainer);
908 // Release lock on the frame schedule queue.
909 lkSchedulers.unlock();
910
911 // Check if frame queue toggle has already been set.
912 if (!m_bNormalFramesQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
913 {
914 // Signify that the frame queue is not empty.
915 m_bNormalFramesQueued.store(true, ATOMIC_MEMORY_ORDER_METHOD);
916 }
917
918 // Return the future from the promise stored in the container.
919 return stContainer.pCopiedFrameStatus->get_future();
920}

◆ RequestDepthCopy() [1/2]

std::future< bool > ZEDCam::RequestDepthCopy ( cv::Mat cvDepth,
const bool  bRetrieveMeasure = true 
)
overridevirtual

Requests a depth measure or image from the camera. Puts a frame pointer into a queue so a copy of a frame from the camera can be written to it. This image has the same shape as a grayscale image, but the values represent the depth in MILLIMETERS. The ZEDSDK will always return this measure in MILLIMETERS.

Parameters
cvDepth- A reference to the cv::Mat to copy the depth frame to.
bRetrieveMeasure- False to get depth IMAGE instead of MEASURE. Do not use the 8-bit grayscale depth image purposes other than displaying depth.
Returns
std::future<bool> - A future that should be waited on before the passed in frame is used. Value will be true if frame was successfully retrieved.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-26

Implements ZEDCamera.

938{
939 // Create instance variables.
940 PIXEL_FORMATS eFrameType;
941
942 // Check if the container should be set to retrieve an image or a measure.
943 bRetrieveMeasure ? eFrameType = PIXEL_FORMATS::eDepthMeasure : eFrameType = PIXEL_FORMATS::eDepthImage;
944 // Assemble container.
945 containers::FrameFetchContainer<cv::Mat> stContainer(cvDepth, eFrameType);
946
947 // Acquire lock on frame copy queue.
948 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
949 // Append frame fetch container to the schedule queue.
950 m_qFrameCopySchedule.push(stContainer);
951 // Release lock on the frame schedule queue.
952 lkSchedulers.unlock();
953
954 // Check if frame queue toggle has already been set.
955 if (!m_bDepthFramesQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
956 {
957 // Signify that the frame queue is not empty.
958 m_bDepthFramesQueued.store(true, ATOMIC_MEMORY_ORDER_METHOD);
959 }
960
961 // Return the future from the promise stored in the container.
962 return stContainer.pCopiedFrameStatus->get_future();
963}

◆ RequestDepthCopy() [2/2]

std::future< bool > ZEDCam::RequestDepthCopy ( cv::cuda::GpuMat cvGPUDepth,
const bool  bRetrieveMeasure = true 
)
overridevirtual

Requests a depth measure or image from the camera. Puts a frame pointer into a queue so a copy of a frame from the camera can be written to it. This image has the same shape as a grayscale image, but the values represent the depth in MILLIMETERS. The ZEDSDK will always return this measure in MILLIMETERS.

Parameters
cvGPUDepth- A reference to the cv::Mat to copy the depth frame to.
bRetrieveMeasure- False to get depth IMAGE instead of MEASURE. Do not use the 8-bit grayscale depth image purposes other than displaying depth.
Returns
std::future<bool> - A future that should be waited on before the passed in frame is used. Value will be true if frame was successfully retrieved.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-26

Reimplemented from ZEDCamera.

981{
982 // Create instance variables.
983 PIXEL_FORMATS eFrameType;
984
985 // Check if the container should be set to retrieve an image or a measure.
986 bRetrieveMeasure ? eFrameType = PIXEL_FORMATS::eDepthMeasure : eFrameType = PIXEL_FORMATS::eDepthImage;
987 // Assemble container.
988 containers::FrameFetchContainer<cv::cuda::GpuMat> stContainer(cvGPUDepth, eFrameType);
989
990 // Acquire lock on frame copy queue.
991 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
992 // Append frame fetch container to the schedule queue.
993 m_qGPUFrameCopySchedule.push(stContainer);
994 // Release lock on the frame schedule queue.
995 lkSchedulers.unlock();
996
997 // Check if frame queue toggle has already been set.
998 if (!m_bDepthFramesQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
999 {
1000 // Signify that the frame queue is not empty.
1001 m_bDepthFramesQueued.store(true, ATOMIC_MEMORY_ORDER_METHOD);
1002 }
1003
1004 // Return the future from the promise stored in the container.
1005 return stContainer.pCopiedFrameStatus->get_future();
1006}

◆ RequestPointCloudCopy() [1/2]

std::future< bool > ZEDCam::RequestPointCloudCopy ( cv::Mat cvPointCloud)
overridevirtual

Requests a point cloud image from the camera. This image has the same resolution as a normal image but with three XYZ values replacing the old color values in the 3rd dimension. The units and sign of the XYZ values are determined by ZED_MEASURE_UNITS and ZED_COORD_SYSTEM constants set in AutonomyConstants.h.

A 4th value in the 3rd dimension exists as a float32 storing the BGRA values. Each color value is 8-bits and is in this order: 00000000 00000000 00000000 00000000 = 32 bits (float32) B G R A

Puts a frame pointer into a queue so a copy of a frame from the camera can be written to it.

Parameters
cvPointCloud- A reference to the cv::Mat to copy the point cloud frame to.
Returns
std::future<bool> - A future that should be waited on before the passed in frame is used. Value will be true if frame was successfully retrieved.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-26

Implements ZEDCamera.

1029{
1030 // Assemble the FrameFetchContainer.
1031 containers::FrameFetchContainer<cv::Mat> stContainer(cvPointCloud, PIXEL_FORMATS::eXYZBGRA);
1032
1033 // Acquire lock on frame copy queue.
1034 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
1035 // Append frame fetch container to the schedule queue.
1036 m_qFrameCopySchedule.push(stContainer);
1037 // Release lock on the frame schedule queue.
1038 lkSchedulers.unlock();
1039
1040 // Check if point cloud queue toggle has already been set.
1041 if (!m_bPointCloudsQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
1042 {
1043 // Signify that the point cloud queue is not empty.
1044 m_bPointCloudsQueued.store(true, ATOMIC_MEMORY_ORDER_METHOD);
1045 }
1046
1047 // Return the future from the promise stored in the container.
1048 return stContainer.pCopiedFrameStatus->get_future();
1049}

◆ RequestPointCloudCopy() [2/2]

std::future< bool > ZEDCam::RequestPointCloudCopy ( cv::cuda::GpuMat cvGPUPointCloud)
overridevirtual

Grabs a point cloud image from the camera. This image has the same resolution as a normal image but with three XYZ values replacing the old color values in the 3rd dimension. The units and sign of the XYZ values are determined by ZED_MEASURE_UNITS and ZED_COORD_SYSTEM constants set in AutonomyConstants.h.

A 4th value in the 3rd dimension exists as a float32 storing the BGRA values. Each color value is 8-bits and is in this order: 00000000 00000000 00000000 00000000 = 32 bits (float32) B G R A

Puts a frame pointer into a queue so a copy of a frame from the camera can be written to it.

Parameters
cvGPUPointCloud- A reference to the cv::Mat to copy the point cloud frame to.
Returns
std::future<bool> - A future that should be waited on before the passed in frame is used. Value will be true if frame was successfully retrieved.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-26

Reimplemented from ZEDCamera.

1072{
1073 // Assemble the FrameFetchContainer.
1074 containers::FrameFetchContainer<cv::cuda::GpuMat> stContainer(cvGPUPointCloud, PIXEL_FORMATS::eXYZBGRA);
1075
1076 // Acquire lock on frame copy queue.
1077 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
1078 // Append frame fetch container to the schedule queue.
1079 m_qGPUFrameCopySchedule.push(stContainer);
1080 // Release lock on the frame schedule queue.
1081 lkSchedulers.unlock();
1082
1083 // Check if point cloud queue toggle has already been set.
1084 if (!m_bPointCloudsQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
1085 {
1086 // Signify that the point cloud queue is not empty.
1087 m_bPointCloudsQueued.store(true, ATOMIC_MEMORY_ORDER_METHOD);
1088 }
1089
1090 // Return the future from the promise stored in the container.
1091 return stContainer.pCopiedFrameStatus->get_future();
1092}

◆ RequestPositionalPoseCopy()

std::future< bool > ZEDCam::RequestPositionalPoseCopy ( Pose stPose)
overridevirtual

Requests the current pose of the camera relative to it's start pose or the origin of the set pose. Puts a Pose pointer into a queue so a copy of a pose from the camera can be written to it. If positional tracking is not enabled, this method will return false and the ZEDCam::Pose may be uninitialized.

Parameters
stPose- A reference to the ZEDCam::Pose object to copy the current camera pose to.
Returns
std::future<bool> - A future that should be waited on before the passed in sl::Pose is used. Value will be true if pose was successfully retrieved.
Note
If this camera is acting as the ZEDSDK Fusion master instance, then the positional pose returned will be from the Fusion instance. aka The Fused GNSS and visual inertial odometry will be returned.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Implements ZEDCamera.

1110{
1111 // Acquire read lock.
1112 std::shared_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1113 // Check if positional tracking has been enabled.
1114 if (m_slCamera.isPositionalTrackingEnabled())
1115 {
1116 // Release lock.
1117 lkCameraLock.unlock();
1118 // Assemble the data container.
1119 containers::DataFetchContainer<Pose> stContainer(stPose);
1120
1121 // Acquire lock on pose copy queue.
1122 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
1123 // Append pose fetch container to the schedule queue.
1124 m_qPoseCopySchedule.push(stContainer);
1125 // Release lock on the pose schedule queue.
1126 lkSchedulers.unlock();
1127
1128 // Check if pose queue toggle has already been set.
1129 if (!m_bPosesQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
1130 {
1131 // Signify that the pose queue is not empty.
1132 m_bPosesQueued.store(true, ATOMIC_MEMORY_ORDER_METHOD);
1133 }
1134
1135 // Return the future from the promise stored in the container.
1136 return stContainer.pCopiedDataStatus->get_future();
1137 }
1138 else
1139 {
1140 // Release lock.
1141 lkCameraLock.unlock();
1142 // Submit logger message.
1143 LOG_WARNING(logging::g_qSharedLogger, "Attempted to get ZED positional pose but positional tracking is not enabled or is still initializing!");
1144
1145 // Create dummy promise to return the future.
1146 std::promise<bool> pmDummyPromise;
1147 std::future<bool> fuDummyFuture = pmDummyPromise.get_future();
1148 // Set future value.
1149 pmDummyPromise.set_value(false);
1150
1151 // Return unsuccessful.
1152 return fuDummyFuture;
1153 }
1154}
This struct is used to carry references to any datatype for scheduling and copying....
Definition FetchContainers.hpp:164

◆ RequestFloorPlaneCopy()

std::future< bool > ZEDCam::RequestFloorPlaneCopy ( sl::Plane &  slPlane)
overridevirtual

Requests the current floor plane of the camera relative to it's current pose. Puts a Plane pointer into a queue so a copy of the floor plane from the camera can be written to it. If positional tracking is not enabled, this method will return false and the sl::Plane may be uninitialized.

Parameters
slPlane- A reference to the sl::Plane object to copy the current camera floor plane to.
Returns
std::future<bool> - A future that should be waited on before the passed in sl::Plane is used. Value will be true if data was successfully retrieved.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-10-22

Reimplemented from ZEDCamera.

1169{
1170 // Acquire read lock.
1171 std::shared_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1172 // Check if positional tracking has been enabled.
1173 if (m_slCamera.isPositionalTrackingEnabled())
1174 {
1175 // Release lock.
1176 lkCameraLock.unlock();
1177 // Assemble the data container.
1178 containers::DataFetchContainer<sl::Plane> stContainer(slPlane);
1179
1180 // Acquire lock on pose copy queue.
1181 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
1182 // Append data fetch container to the schedule queue.
1183 m_qFloorCopySchedule.push(stContainer);
1184 // Release lock on the pose schedule queue.
1185 lkSchedulers.unlock();
1186
1187 // Check if pose queue toggle has already been set.
1188 if (!m_bFloorsQueued.load(std::memory_order_relaxed))
1189 {
1190 // Signify that the pose queue is not empty.
1191 m_bFloorsQueued.store(true, std::memory_order_relaxed);
1192 }
1193
1194 // Return the future from the promise stored in the container.
1195 return stContainer.pCopiedDataStatus->get_future();
1196 }
1197 else
1198 {
1199 // Release lock.
1200 lkCameraLock.unlock();
1201 // Submit logger message.
1202 LOG_WARNING(logging::g_qSharedLogger, "Attempted to get ZED floor plane but positional tracking is not enabled!");
1203
1204 // Create dummy promise to return the future.
1205 std::promise<bool> pmDummyPromise;
1206 std::future<bool> fuDummyFuture = pmDummyPromise.get_future();
1207 // Set future value.
1208 pmDummyPromise.set_value(false);
1209
1210 // Return unsuccessful.
1211 return fuDummyFuture;
1212 }
1213}

◆ RequestSensorsCopy()

std::future< bool > ZEDCam::RequestSensorsCopy ( sl::SensorsData &  slSensorsData)
overridevirtual

Requests the most up to date sensors data from the camera. This data include IMU pose and raw values, barometer, magnetometer, and temperature data.

Parameters
slSensorsData- A reference to the sl::SensorsData struct to copy data into.
Returns
std::future<bool> - A future that should be waited on before the passed in sl::SensorsData is used. Value will be true if data was successfully retrieved.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-08-26

Reimplemented from ZEDCamera.

1227{
1228 // Assemble the data container.
1229 containers::DataFetchContainer<sl::SensorsData> stContainer(slSensorsData);
1230
1231 // Acquire lock on sensors copy queue.
1232 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
1233 // Append sensors fetch container to the schedule queue.
1234 m_qSensorsCopySchedule.push(stContainer);
1235 // Release lock on the sensors schedule queue.
1236 lkSchedulers.unlock();
1237
1238 // Check if sensors queue toggle has already been set.
1239 if (!m_bSensorsQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
1240 {
1241 // Signify that the sensors queue is not empty.
1242 m_bSensorsQueued.store(true, ATOMIC_MEMORY_ORDER_METHOD);
1243 }
1244
1245 // Return the future from the promise stored in the container.
1246 return stContainer.pCopiedDataStatus->get_future();
1247}

◆ RequestObjectsCopy()

std::future< bool > ZEDCam::RequestObjectsCopy ( std::vector< sl::ObjectData > &  vObjectData)
overridevirtual

Requests a current copy of the tracked objects from the camera. Puts a pointer to a vector containing sl::ObjectData into a queue so a copy of a frame from the camera can be written to it.

Parameters
vObjectData- A vector that will have data copied to it containing sl::ObjectData objects.
Returns
std::future<bool> - A future that should be waited on before the passed in vector is used. Value will be true if data was successfully retrieved.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Reimplemented from ZEDCamera.

1261{
1262 // Acquire read lock.
1263 std::shared_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1264 // Check if object detection has been enabled.
1265 if (m_slCamera.isObjectDetectionEnabled())
1266 {
1267 // Release lock.
1268 lkCameraLock.unlock();
1269 // Assemble the data container.
1271
1272 // Acquire lock on object copy queue.
1273 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
1274 // Append data fetch container to the schedule queue.
1275 m_qObjectDataCopySchedule.push(stContainer);
1276 // Release lock on the object schedule queue.
1277 lkSchedulers.unlock();
1278
1279 // Check if objects queue toggle has already been set.
1280 if (!m_bObjectsQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
1281 {
1282 // Signify that the objects queue is not empty.
1283 m_bObjectsQueued.store(true, ATOMIC_MEMORY_ORDER_METHOD);
1284 }
1285
1286 // Return the future from the promise stored in the container.
1287 return stContainer.pCopiedDataStatus->get_future();
1288 }
1289 else
1290 {
1291 // Release lock.
1292 lkCameraLock.unlock();
1293 // Submit logger message.
1294 LOG_WARNING(logging::g_qSharedLogger, "Attempted to get ZED object data but object detection/tracking is not enabled!");
1295
1296 // Create dummy promise to return the future.
1297 std::promise<bool> pmDummyPromise;
1298 std::future<bool> fuDummyFuture = pmDummyPromise.get_future();
1299 // Set future value.
1300 pmDummyPromise.set_value(false);
1301
1302 // Return unsuccessful.
1303 return fuDummyFuture;
1304 }
1305}

◆ RequestBatchedObjectsCopy()

std::future< bool > ZEDCam::RequestBatchedObjectsCopy ( std::vector< sl::ObjectsBatch > &  vBatchedObjectData)
overridevirtual

If batching is enabled, this requests the normal objects and passes them to the the internal batching queue of the zed api. This performs short-term re-identification with deep learning and trajectories filtering. Batching must have been set to enabled when EnableObjectDetection() was called. Most of the time the vector will be empty and will be filled every ZED_OBJDETECTION_BATCH_LATENCY.

Parameters
vBatchedObjectData- A vector containing objects of sl::ObjectsBatch object that will have object data copied to.
Returns
std::future<bool> - A future that should be waited on before the passed in vector is used. Value will be true if data was successfully retrieved.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-30

Reimplemented from ZEDCamera.

1323{
1324 // Acquire read lock.
1325 std::shared_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1326 // Check if object detection and batching has been enabled.
1327 if (m_slCamera.isObjectDetectionEnabled() && m_slObjectDetectionBatchParams.enable)
1328 {
1329 // Release lock.
1330 lkCameraLock.unlock();
1331 // Assemble the data container.
1332 containers::DataFetchContainer<std::vector<sl::ObjectsBatch>> stContainer(vBatchedObjectData);
1333
1334 // Acquire lock on batched object copy queue.
1335 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
1336 // Append data fetch container to the schedule queue.
1337 m_qObjectBatchedDataCopySchedule.push(stContainer);
1338 // Release lock on the data schedule queue.
1339 lkSchedulers.unlock();
1340
1341 // Check if objects queue toggle has already been set.
1342 if (!m_bBatchedObjectsQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
1343 {
1344 // Signify that the objects queue is not empty.
1345 m_bBatchedObjectsQueued.store(true, ATOMIC_MEMORY_ORDER_METHOD);
1346 }
1347
1348 // Return the future from the promise stored in the container.
1349 return stContainer.pCopiedDataStatus->get_future();
1350 }
1351 else
1352 {
1353 // Release lock.
1354 lkCameraLock.unlock();
1355 // Submit logger message.
1356 LOG_WARNING(logging::g_qSharedLogger, "Attempted to get ZED batched object data but object detection/tracking is not enabled!");
1357
1358 // Create dummy promise to return the future.
1359 std::promise<bool> pmDummyPromise;
1360 std::future<bool> fuDummyFuture = pmDummyPromise.get_future();
1361 // Set future value.
1362 pmDummyPromise.set_value(false);
1363
1364 // Return unsuccessful.
1365 return fuDummyFuture;
1366 }
1367}

◆ ResetPositionalTracking()

sl::ERROR_CODE ZEDCam::ResetPositionalTracking ( )
overridevirtual

Resets the cameras X,Y,Z translation and Roll,Pitch,Yaw orientation back to 0. THINK CAREFULLY! Do you actually want to reset this? It will also realign the coordinate system to whichever way the camera happens to be facing.

Returns
sl::ERROR_CODE - Status of the positional tracking reset.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-26

Implements ZEDCamera.

1380{
1381 // Create new translation to set position back to user given values.
1382 sl::Translation slZeroTranslation(0, 0, 0);
1383 // Update offset member variables.
1384 m_dPoseOffsetX = 0.0;
1385 m_dPoseOffsetY = 0.0;
1386 m_dPoseOffsetZ = 0.0;
1387 // This will reset position and coordinate frame.
1388 sl::Rotation slZeroRotation;
1389 slZeroRotation.setEulerAngles(sl::float3(0.0, 0.0, 0.0), false);
1390
1391 // Store new translation and rotation in a transform object.
1392 sl::Transform slZeroTransform(slZeroRotation, slZeroTranslation);
1393
1394 // Submit logger message.
1395 LOG_NOTICE(logging::g_qSharedLogger, "Resetting positional tracking for camera {} ({})!", sl::toString(m_slCameraModel).get(), m_unCameraSerialNumber);
1396
1397 // Acquire write lock.
1398 std::unique_lock<std::shared_mutex> lkWriteCameraLock(m_muCameraMutex);
1399 // Reset the positional tracking location of the camera.
1400 return m_slCamera.resetPositionalTracking(slZeroTransform);
1401}
Here is the call graph for this function:

◆ TrackCustomBoxObjects()

sl::ERROR_CODE ZEDCam::TrackCustomBoxObjects ( std::vector< ZedObjectData > &  vCustomObjects)
overridevirtual

A vector containing CustomBoxObjectData objects. These objects simply store information about your detected objects from an external object detection model. You will need to take your inference results and package them into a sl::CustomBoxObjectData so the the ZEDSDK can properly interpret your detections.

Giving the bounding boxes of your detected objects to the ZEDSDK will enable positional tracking and velocity estimation for each object. Even when not in view. The IDs of objects will also become persistent.

Parameters
vCustomObjects- A vector of sl::CustomBoxObjectData objects.
Returns
sl::ERROR_CODE - The return status of ingestion.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-26

Reimplemented from ZEDCamera.

1420{
1421 // Create instance variables.
1422 std::vector<sl::CustomBoxObjectData> vCustomBoxData;
1423
1424 // Repack detection data into sl specific object.
1425 for (ZedObjectData stObjectData : vCustomObjects)
1426 {
1427 // Create new sl CustomBoxObjectData struct.
1428 sl::CustomBoxObjectData slCustomBox;
1429 std::vector<sl::uint2> vCorners;
1430
1431 // Assign simple attributes.
1432 slCustomBox.unique_object_id = sl::String(stObjectData.GetObjectUUID().c_str());
1433 slCustomBox.label = stObjectData.nClassNumber;
1434 slCustomBox.probability = stObjectData.fConfidence;
1435 slCustomBox.is_grounded = stObjectData.bObjectRemainsOnFloorPlane;
1436 // Repackage object corner data.
1437 vCorners.emplace_back(sl::uint2(stObjectData.cvBoundingBox.x, stObjectData.cvBoundingBox.y)); // Top-left corner
1438 vCorners.emplace_back(sl::uint2(stObjectData.cvBoundingBox.x + stObjectData.cvBoundingBox.width, stObjectData.cvBoundingBox.y)); // Top-right corner
1439 vCorners.emplace_back(sl::uint2(stObjectData.cvBoundingBox.x, stObjectData.cvBoundingBox.y + stObjectData.cvBoundingBox.height)); // Bottom-left corner
1440 vCorners.emplace_back(sl::uint2(stObjectData.cvBoundingBox.x + stObjectData.cvBoundingBox.width,
1441 stObjectData.cvBoundingBox.y + stObjectData.cvBoundingBox.height)); // Bottom-right corner
1442 slCustomBox.bounding_box_2d = vCorners;
1443
1444 // Append repackaged object to vector.
1445 vCustomBoxData.emplace_back(slCustomBox);
1446 }
1447
1448 // Acquire write lock.
1449 std::unique_lock<std::shared_mutex> lkWriteCameraLock(m_muCameraMutex);
1450 // Give the custom box data to the zed api.
1451 sl::ERROR_CODE slReturnCode = m_slCamera.ingestCustomBoxObjects(vCustomBoxData);
1452 // Release lock.
1453 lkWriteCameraLock.unlock();
1454
1455 // Check if successful.
1456 if (slReturnCode == sl::ERROR_CODE::SUCCESS)
1457 {
1458 // Submit logger message.
1459 LOG_WARNING(logging::g_qSharedLogger,
1460 "Failed to ingest new objects for camera {} ({})! sl::ERROR_CODE is: {}",
1461 sl::toString(m_slCameraModel).get(),
1462 m_unCameraSerialNumber,
1463 sl::toString(slReturnCode).get());
1464 }
1465
1466 // Return error code.
1467 return slReturnCode;
1468}
Here is the call graph for this function:

◆ RebootCamera()

sl::ERROR_CODE ZEDCam::RebootCamera ( )
overridevirtual

Performs a hardware reset of the ZED2 or ZED2i camera.

Returns
sl::ERROR_CODE - Whether or not the camera reboot was successful.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-26

Implements ZEDCamera.

1479{
1480 // Acquire write lock.
1481 std::unique_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1482 // Reboot this camera and return the status code.
1483 return sl::Camera::reboot(m_unCameraSerialNumber);
1484}

◆ EnablePositionalTracking()

sl::ERROR_CODE ZEDCam::EnablePositionalTracking ( const float  fExpectedCameraHeightFromFloorTolerance = constants::ZED_DEFAULT_FLOOR_PLANE_ERROR)
overridevirtual

Enable the positional tracking functionality of the camera.

Parameters
fExpectedCameraHeightFromFloorTolerance- The expected height of the camera from the floor. This aids with floor plane detection.
Returns
sl::ERROR_CODE - Whether or not positional tracking was successfully enabled.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-10-22

Implements ZEDCamera.

1497{
1498 // Assign member variable.
1499 m_fExpectedCameraHeightFromFloorTolerance = fExpectedCameraHeightFromFloorTolerance;
1500
1501 // Acquire write lock.
1502 std::unique_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1503 // Enable pose tracking and store return code.
1504 sl::ERROR_CODE slReturnCode = m_slCamera.enablePositionalTracking(m_slPoseTrackingParams);
1505 // Release lock.
1506 lkCameraLock.unlock();
1507
1508 // Check if positional tracking was enabled properly.
1509 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
1510 {
1511 // Submit logger message.
1512 LOG_ERROR(logging::g_qSharedLogger,
1513 "Failed to enable positional tracking for camera {} ({})! sl::ERROR_CODE is: {}",
1514 sl::toString(m_slCameraModel).get(),
1515 m_unCameraSerialNumber,
1516 sl::toString(slReturnCode).get());
1517 }
1518
1519 // Set flag.
1520 m_bEnablePositionalTrackingFlag = true;
1521
1522 // Return error code.
1523 return slReturnCode;
1524}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DisablePositionalTracking()

void ZEDCam::DisablePositionalTracking ( )
overridevirtual

Disable to positional tracking functionality of the camera.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-26

Implements ZEDCamera.

1534{
1535 // Acquire write lock.
1536 std::unique_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1537 // Disable pose tracking.
1538 m_slCamera.disablePositionalTracking();
1539 // Set flag.
1540 m_bEnablePositionalTrackingFlag = false;
1541}

◆ SetPositionalPose()

void ZEDCam::SetPositionalPose ( const double  dX,
const double  dY,
const double  dZ,
const double  dXO,
const double  dYO,
const double  dZO 
)
overridevirtual

Sets the pose of the positional tracking of the camera. XYZ will point in their respective directions according to ZED_COORD_SYSTEM defined in AutonomyConstants.h.

Warning: This method is slow and should not be called in a loop. Setting the pose will temporarily block the entire camera from grabbed or copying frames to new threads. This method should only be called occasionally when absolutely needed.

Parameters
dX- The X position of the camera in ZED_MEASURE_UNITS.
dY- The Y position of the camera in ZED_MEASURE_UNITS.
dZ- The Z position of the camera in ZED_MEASURE_UNITS.
dXO- The tilt of the camera around the X axis in degrees. (0-360)
dYO- The tilt of the camera around the Y axis in degrees. (0-360)
dZO- The tilt of the camera around the Z axis in degrees. (0-360)
Returns
sl::ERROR_CODE - Whether or not the pose was set successfully.
Bug:
The ZEDSDK currently cannot handle resetting the positional pose with large translational (dX, dY, dZ) values without breaking positional tracking. This is because the values are floats and not doubles. To fix this I (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om), have decided to just handle the translation offsets internally. So when SetPositionalPose() is called is assigns the dX, dY, and dZ values to private member variables of this class, then the offsets are added the the pose in the PooledLinearCode() under the pose requests section. If StereoLabs fixes this in the future, I will go back to using the sl::Translation to reset positional tracking.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Implements ZEDCamera.

1570{
1571 // Update offset member variables.
1572 m_dPoseOffsetX = dX - m_slCameraPose.getTranslation().x;
1573 m_dPoseOffsetY = dY - m_slCameraPose.getTranslation().y;
1574 m_dPoseOffsetZ = dZ - m_slCameraPose.getTranslation().z;
1575 // Find the angular distance from current and desired pose angles. This is complicated because zed uses different angle ranges.
1576 m_dPoseOffsetXO =
1577 numops::InputAngleModulus(numops::AngularDifference(numops::InputAngleModulus<double>(m_slCameraPose.getEulerAngles(false).x, 0.0, 360.0), dXO), 0.0, 360.0);
1578 m_dPoseOffsetYO =
1579 numops::InputAngleModulus(numops::AngularDifference(numops::InputAngleModulus<double>(m_slCameraPose.getEulerAngles(false).y, 0.0, 360.0), dYO), 0.0, 360.0);
1580 m_dPoseOffsetZO =
1581 numops::InputAngleModulus(numops::AngularDifference(numops::InputAngleModulus<double>(m_slCameraPose.getEulerAngles(false).z, 0.0, 360.0), dZO), 0.0, 360.0);
1582}
constexpr T InputAngleModulus(T tValue, T tMinValue, T tMaxValue)
Calculates the modulus of an input angle.
Definition NumberOperations.hpp:162
constexpr T AngularDifference(T tFirstValue, T tSecondValue)
Calculates the distance in degrees between two angles. This function accounts for wrap around so that...
Definition NumberOperations.hpp:201
Here is the call graph for this function:

◆ EnableSpatialMapping()

sl::ERROR_CODE ZEDCam::EnableSpatialMapping ( )
overridevirtual

Enabled the spatial mapping feature of the camera. Pose tracking will be enabled if it is not already.

Returns
sl::ERROR_CODE - Whether or not spatial mapping was successfully enabled.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Reimplemented from ZEDCamera.

1594{
1595 // Create instance variables.
1596 sl::Pose slCameraPose;
1597 sl::ERROR_CODE slReturnCode = sl::ERROR_CODE::SUCCESS;
1598
1599 // Acquire read lock.
1600 std::shared_lock<std::shared_mutex> lkReadCameraLock(m_muCameraMutex);
1601 // Check if positional tracking is enabled.
1602 if (!m_slCamera.isPositionalTrackingEnabled())
1603 {
1604 // Release lock.
1605 lkReadCameraLock.unlock();
1606 // Enable positional tracking.
1607 slReturnCode = this->EnablePositionalTracking();
1608 }
1609 else
1610 {
1611 // Release lock.
1612 lkReadCameraLock.unlock();
1613 }
1614
1615 // Check if positional tracking is or was enabled successfully.
1616 if (slReturnCode == sl::ERROR_CODE::SUCCESS)
1617 {
1618 // Acquire write lock.
1619 std::unique_lock<std::shared_mutex> lkWriteCameraLock(m_muCameraMutex);
1620 // Call camera grab function once to ensure the camera is initialized with data.
1621 m_slCamera.grab(m_slRuntimeParams);
1622 // Enable spatial mapping.
1623 slReturnCode = m_slCamera.enableSpatialMapping(m_slSpatialMappingParams);
1624 // Release lock.
1625 lkWriteCameraLock.unlock();
1626
1627 // Check if positional tracking was enabled properly.
1628 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
1629 {
1630 // Submit logger message.
1631 LOG_ERROR(logging::g_qSharedLogger,
1632 "Failed to enabled spatial mapping for camera {} ({})! sl::ERROR_CODE is: {}",
1633 sl::toString(m_slCameraModel).get(),
1634 m_unCameraSerialNumber,
1635 sl::toString(slReturnCode).get());
1636 }
1637 }
1638 else
1639 {
1640 // Submit logger message.
1641 LOG_ERROR(logging::g_qSharedLogger,
1642 "Failed to enabled spatial mapping for camera {} ({}) because positional tracking could not be enabled! sl::ERROR_CODE is: {}",
1643 sl::toString(m_slCameraModel).get(),
1644 m_unCameraSerialNumber,
1645 sl::toString(slReturnCode).get());
1646 }
1647
1648 // Set flag.
1649 m_bEnableSpatialMappingFlag = true;
1650
1651 // Return error code.
1652 return slReturnCode;
1653}
sl::ERROR_CODE EnablePositionalTracking(const float fExpectedCameraHeightFromFloorTolerance=constants::ZED_DEFAULT_FLOOR_PLANE_ERROR) override
Enable the positional tracking functionality of the camera.
Definition ZEDCam.cpp:1496
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DisableSpatialMapping()

void ZEDCam::DisableSpatialMapping ( )
overridevirtual

Disabled the spatial mapping feature of the camera.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Reimplemented from ZEDCamera.

1663{
1664 // Acquire write lock.
1665 std::unique_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1666 // Disable spatial mapping.
1667 m_slCamera.disableSpatialMapping();
1668 // Set flag.
1669 m_bEnableSpatialMappingFlag = false;
1670}

◆ EnableObjectDetection()

sl::ERROR_CODE ZEDCam::EnableObjectDetection ( const bool  bEnableBatching = false)
overridevirtual

Enables the object detection and tracking feature of the camera.

Returns
sl::ERROR_CODE - Whether or not object detection/tracking was successfully enabled.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Reimplemented from ZEDCamera.

1681{
1682 // Check if batching should be turned on.
1683 bEnableBatching ? m_slObjectDetectionBatchParams.enable = true : m_slObjectDetectionBatchParams.enable = false;
1684 // Give batch params to detection params.
1685 m_slObjectDetectionParams.batch_parameters = m_slObjectDetectionBatchParams;
1686
1687 // Acquire write lock.
1688 std::unique_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1689 // Enable object detection.
1690 sl::ERROR_CODE slReturnCode = m_slCamera.enableObjectDetection(m_slObjectDetectionParams);
1691 // Release lock.
1692 lkCameraLock.unlock();
1693
1694 // Check if positional tracking was enabled properly.
1695 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
1696 {
1697 // Submit logger message.
1698 LOG_ERROR(logging::g_qSharedLogger,
1699 "Failed to enabled object detection for camera {} ({})! sl::ERROR_CODE is: {}",
1700 sl::toString(m_slCameraModel).get(),
1701 m_unCameraSerialNumber,
1702 sl::toString(slReturnCode).get());
1703 }
1704
1705 // Set flag.
1706 m_bEnableObjectDetectionFlag = true;
1707
1708 // Return error code.
1709 return slReturnCode;
1710}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DisableObjectDetection()

void ZEDCam::DisableObjectDetection ( )
overridevirtual

Disables the object detection and tracking feature of the camera.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Reimplemented from ZEDCamera.

1720{
1721 // Acquire write lock.
1722 std::unique_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1723 // Disable object detection and tracking.
1724 m_slCamera.disableObjectDetection();
1725 // Set flag.
1726 m_bEnableObjectDetectionFlag = false;
1727}

◆ GetCameraIsOpen()

bool ZEDCam::GetCameraIsOpen ( )
overridevirtual

Accessor for the current status of the camera.

Returns
true - Camera is currently opened and functional.
false - Camera is not opened and/or connected.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Implements Camera< cv::Mat >.

1739{
1740 // Acquire read lock.
1741 std::shared_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1742 return this->GetThreadState() == AutonomyThreadState::eRunning && m_slCamera.isOpened();
1743}
AutonomyThreadState GetThreadState() const
Accessor for the Threads State private member.
Definition AutonomyThread.hpp:237
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetUsingGPUMem()

bool ZEDCam::GetUsingGPUMem ( ) const
overridevirtual

Accessor for if this ZED is storing it's frames in GPU memory.

Returns
true - Using GPU memory for mats.
false - Using CPU memory for mats.
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-09-09

Reimplemented from ZEDCamera.

1755{
1756 // Check if we are using GPU memory.
1757 return m_slMemoryType == sl::MEM::GPU;
1758}

◆ GetCameraModel()

std::string ZEDCam::GetCameraModel ( )
overridevirtual

Accessor for the model enum from the ZEDSDK and represents the camera model as a string.

Returns
std::string - The model of the zed camera. Possible values: ZED, ZED_MINI, ZED_2, ZED_2i, ZED_X, ZED_X_MINI, UNDEFINED_UNKNOWN
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Implements ZEDCamera.

1770{
1771 // Acquire read lock.
1772 std::shared_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1773 // Check if the camera is opened.
1774 if (m_slCamera.isOpened())
1775 {
1776 // Release lock.
1777 lkCameraLock.unlock();
1778 // Convert camera model to a string and return.
1779 return sl::toString(m_slCameraModel).get();
1780 }
1781 else
1782 {
1783 // Release lock.
1784 lkCameraLock.unlock();
1785 // Return the model string to show camera isn't opened.
1786 return "NOT_OPENED";
1787 }
1788}
Here is the caller graph for this function:

◆ GetCameraSerial()

unsigned int ZEDCam::GetCameraSerial ( )
overridevirtual

Accessor for the camera's serial number.

Returns
unsigned int - The serial number of the camera.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Reimplemented from ZEDCamera.

1799{
1800 // Return the model string to show camera isn't opened.
1801 return m_unCameraSerialNumber;
1802}
Here is the caller graph for this function:

◆ GetPositionalTrackingEnabled()

bool ZEDCam::GetPositionalTrackingEnabled ( )
overridevirtual

Accessor for if the positional tracking functionality of the camera has been enabled and functioning.

Returns
true - Positional tracking is enabled.
false - Positional tracking is not enabled.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Implements ZEDCamera.

1815{
1816 // Acquire read lock.
1817 std::shared_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1818 return m_slCamera.isPositionalTrackingEnabled() && m_slCamera.getPositionalTrackingStatus().odometry_status == sl::ODOMETRY_STATUS::OK;
1819}

◆ GetPositionalTrackingState()

sl::PositionalTrackingStatus ZEDCam::GetPositionalTrackingState ( )
overridevirtual

Accessor for the current positional tracking status of the camera.

Returns
sl::PositionalTrackingStatus - The sl::PositionalTrackingStatus struct storing information about the current VIO positional tracking state.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-04-20

Reimplemented from ZEDCamera.

1831{
1832 // Acquire read lock.
1833 std::shared_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1834 return m_slCamera.getPositionalTrackingStatus();
1835}

◆ GetSpatialMappingState()

sl::SPATIAL_MAPPING_STATE ZEDCam::GetSpatialMappingState ( )
overridevirtual

Accessor for the current state of the camera's spatial mapping feature.

Returns
sl::SPATIAL_MAPPING_STATE - The enum value of the spatial mapping state.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Reimplemented from ZEDCamera.

1846{
1847 // Acquire read lock.
1848 std::shared_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1849 // Return the current spatial mapping state of the camera.
1850 return m_slCamera.getSpatialMappingState();
1851}

◆ ExtractSpatialMapAsync()

sl::SPATIAL_MAPPING_STATE ZEDCam::ExtractSpatialMapAsync ( std::future< sl::Mesh > &  fuMeshFuture)
overridevirtual

Retrieve the built spatial map from the camera. Spatial mapping must be enabled. This method takes in an std::future<sl::FusedPointCloud> to eventually store the map in. It returns a enum code representing the successful scheduling of building the map. Any code other than SPATIAL_MAPPING_STATE::OK means the future will never be filled.

Parameters
std::future<sl::Mesh>- The future to eventually store the map in.
Returns
sl::SPATIAL_MAPPING_STATE - Whether or not the building of the map was successfully scheduled. Anything other than OK means the future will never be filled.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Reimplemented from ZEDCamera.

1867{
1868 // Acquire read lock.
1869 std::shared_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1870 // Get and store current state of spatial mapping.
1871 sl::SPATIAL_MAPPING_STATE slReturnState = m_slCamera.getSpatialMappingState();
1872
1873 // Check if spatial mapping has been enabled and ready
1874 if (slReturnState == sl::SPATIAL_MAPPING_STATE::OK)
1875 {
1876 // Request that the ZEDSDK begin processing the spatial map for export.
1877 m_slCamera.requestSpatialMapAsync();
1878
1879 // Start an async thread to wait for spatial map processing to finish. Return resultant future object.
1880 fuMeshFuture = std::async(std::launch::async,
1881 [this]()
1882 {
1883 // Create instance variables.
1884 sl::Mesh slSpatialMap;
1885
1886 // Loop until map is finished generating or the camera unexpectedly closes.
1887 while (m_slCamera.getSpatialMapRequestStatusAsync() == sl::ERROR_CODE::FAILURE && m_slCamera.isOpened())
1888 {
1889 // Sleep for 10ms.
1890 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1891 }
1892
1893 // Check if the spatial map was exported successfully.
1894 if (m_slCamera.getSpatialMapRequestStatusAsync() == sl::ERROR_CODE::SUCCESS && m_slCamera.isOpened())
1895 {
1896 // Get and store the spatial map.
1897 m_slCamera.retrieveSpatialMapAsync(slSpatialMap);
1898
1899 // Return spatial map.
1900 return slSpatialMap;
1901 }
1902 else
1903 {
1904 // Submit logger message.
1905 LOG_ERROR(logging::g_qSharedLogger,
1906 "Failed to extract ZED spatial map. sl::ERROR_CODE is: {}",
1907 sl::toString(m_slCamera.getSpatialMapRequestStatusAsync()).get());
1908
1909 // Return empty point cloud.
1910 return sl::Mesh();
1911 }
1912 });
1913 }
1914 else
1915 {
1916 // Submit logger message.
1917 LOG_WARNING(logging::g_qSharedLogger, "ZED spatial mapping was never enabled, can't extract spatial map!");
1918 }
1919
1920 // Return current spatial mapping state.
1921 return slReturnState;
1922}

◆ GetObjectDetectionEnabled()

bool ZEDCam::GetObjectDetectionEnabled ( )
overridevirtual

Accessor for if the cameras object detection and tracking feature is enabled.

Returns
true - Object detection and tracking is enabled.
false - Object detection and tracking is not enabled.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-27

Reimplemented from ZEDCamera.

1934{
1935 // Acquire read lock.
1936 std::shared_lock<std::shared_mutex> lkCameraLock(m_muCameraMutex);
1937 return m_slCamera.isObjectDetectionEnabled();
1938}

◆ ThreadedContinuousCode()

void ZEDCam::ThreadedContinuousCode ( )
overrideprivatevirtual

The code inside this private method runs in a separate thread, but still has access to this*. This method continuously calls the grab() function of the ZEDSDK, which updates all frames (RGB, depth, cloud) and all other data such as positional and spatial mapping. Then a thread pool is started and joined once per iteration to mass copy the frames and/or measure to any other thread waiting in the queues.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-09-01

Implements AutonomyThread< void >.

236{
237 // Acquire read lock for camera object.
238 std::shared_lock<std::shared_mutex> lkReadCameraLock(m_muCameraMutex);
239 // Check if camera is opened.
240 if (!m_slCamera.isOpened())
241 {
242 // Release lock.
243 lkReadCameraLock.unlock();
244
245 // If this is the first iteration of the thread the camera probably isn't present so stop thread to save resources.
246 if (this->GetThreadState() == AutonomyThreadState::eStarting)
247 {
248 // Shutdown threads for this ZEDCam.
249 this->RequestStop();
250 // Submit logger message.
251 LOG_CRITICAL(logging::g_qSharedLogger,
252 "Camera start was attempted for ZED camera with serial number {}, but camera never properly opened or it has been closed/rebooted!",
253 m_unCameraSerialNumber);
254 }
255 else
256 {
257 std::chrono::time_point tmCurrentTime = std::chrono::system_clock::now();
258 // Convert time point to seconds since epoch
259 int nTimeSinceEpoch = std::chrono::duration_cast<std::chrono::seconds>(tmCurrentTime.time_since_epoch()).count();
260
261 // Only try to reopen camera every 5 seconds.
262 if (nTimeSinceEpoch % 5 == 0 && !m_bCameraReopenAlreadyChecked)
263 {
264 // Acquire write lock for camera object.
265 std::unique_lock<std::shared_mutex> lkWriteCameraLock(m_muCameraMutex);
266 // Attempt to reopen camera.
267 sl::ERROR_CODE slReturnCode = m_slCamera.open(m_slCameraParams);
268 // Release lock.
269 lkWriteCameraLock.unlock();
270
271 // Check if camera was reopened.
272 if (slReturnCode == sl::ERROR_CODE::SUCCESS)
273 {
274 // Submit logger message.
275 LOG_WARNING(logging::g_qSharedLogger, "ZED stereo camera with serial number {} has been reconnected and reopened!", m_unCameraSerialNumber);
276
277 // Check if positional tracking was enabled.
278 if (m_bEnablePositionalTrackingFlag)
279 {
280 slReturnCode = this->EnablePositionalTracking();
281
282 // Check if positional tracking was re-enabled successfully.
283 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
284 {
285 // Submit logger message.
286 LOG_ERROR(logging::g_qSharedLogger,
287 "After reopening ZED stereo camera with serial number {}, positional tracking failed to reinitialize. sl::ERROR_CODE is: {}",
288 m_unCameraSerialNumber,
289 sl::toString(slReturnCode).get());
290 }
291 }
292 // Check if spatial mapping was enabled.
293 if (m_bEnableSpatialMappingFlag)
294 {
295 slReturnCode = this->EnableSpatialMapping();
296 // Check if spatial mapping was re-enabled successfully.
297 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
298 {
299 // Submit logger message.
300 LOG_ERROR(logging::g_qSharedLogger,
301 "After reopening ZED stereo camera with serial number {}, spatial mapping failed to reinitialize. sl::ERROR_CODE is: {}",
302 m_unCameraSerialNumber,
303 sl::toString(slReturnCode).get());
304 }
305 }
306 // Check if object detection was enabled.
307 if (m_bEnableObjectDetectionFlag)
308 {
309 slReturnCode = this->EnableObjectDetection();
310
311 // Check if object detection was re-enabled successfully.
312 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
313 {
314 // Submit logger message.
315 LOG_ERROR(logging::g_qSharedLogger,
316 "After reopening ZED stereo camera with serial number {}, object detection failed to reinitialize. sl::ERROR_CODE is: {}",
317 m_unCameraSerialNumber,
318 sl::toString(slReturnCode).get());
319 }
320 }
321 }
322 else
323 {
324 // Submit logger message.
325 LOG_WARNING(logging::g_qSharedLogger,
326 "Attempt to reopen ZED stereo camera with serial number {} has failed! Trying again in 5 seconds...",
327 m_unCameraSerialNumber);
328 }
329
330 // Set toggle.
331 m_bCameraReopenAlreadyChecked = true;
332 }
333 else if (nTimeSinceEpoch % 5 != 0)
334 {
335 // Reset toggle.
336 m_bCameraReopenAlreadyChecked = false;
337 }
338 }
339 }
340 else
341 {
342 // Release lock.
343 lkReadCameraLock.unlock();
344 // Acquire write lock for camera object.
345 std::unique_lock<std::shared_mutex> lkWriteCameraLock(m_muCameraMutex);
346 // Call generalized update method of zed api.
347 sl::ERROR_CODE slReturnCode = m_slCamera.grab(m_slRuntimeParams);
348 // Release camera lock.
349 lkWriteCameraLock.unlock();
350
351 // Check if new frame was computed successfully.
352 if (slReturnCode == sl::ERROR_CODE::SUCCESS)
353 {
354 // Check if normal frames have been requested.
355 if (m_bNormalFramesQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
356 {
357 // Grab regular image and store it in member variable.
358 slReturnCode = m_slCamera.retrieveImage(m_slFrame, constants::ZED_RETRIEVE_VIEW, m_slMemoryType, sl::Resolution(m_nPropResolutionX, m_nPropResolutionY));
359 // Check that the regular frame was retrieved successfully.
360 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
361 {
362 // Submit logger message.
363 LOG_WARNING(logging::g_qSharedLogger,
364 "Unable to retrieve new frame image for stereo camera {} ({})! sl::ERROR_CODE is: {}",
365 sl::toString(m_slCameraModel).get(),
366 m_unCameraSerialNumber,
367 sl::toString(slReturnCode).get());
368 }
369 }
370
371 // Check if depth frames have been requested.
372 if (m_bDepthFramesQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
373 {
374 // Grab depth measure and store it in member variable.
375 slReturnCode = m_slCamera.retrieveMeasure(m_slDepthMeasure, m_slDepthMeasureType, m_slMemoryType, sl::Resolution(m_nPropResolutionX, m_nPropResolutionY));
376 // Check that the regular frame was retrieved successfully.
377 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
378 {
379 // Submit logger message.
380 LOG_WARNING(logging::g_qSharedLogger,
381 "Unable to retrieve new depth measure for stereo camera {} ({})! sl::ERROR_CODE is: {}",
382 sl::toString(m_slCameraModel).get(),
383 m_unCameraSerialNumber,
384 sl::toString(slReturnCode).get());
385 }
386
387 // Grab depth grayscale image and store it in member variable.
388 slReturnCode = m_slCamera.retrieveImage(m_slDepthImage, sl::VIEW::DEPTH, m_slMemoryType, sl::Resolution(m_nPropResolutionX, m_nPropResolutionY));
389 // Check that the regular frame was retrieved successfully.
390 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
391 {
392 // Submit logger message.
393 LOG_WARNING(logging::g_qSharedLogger,
394 "Unable to retrieve new depth image for stereo camera {} ({})! sl::ERROR_CODE is: {}",
395 sl::toString(m_slCameraModel).get(),
396 m_unCameraSerialNumber,
397 sl::toString(slReturnCode).get());
398 }
399 }
400
401 // Check if point clouds have been requested.
402 if (m_bPointCloudsQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
403 {
404 // Grab regular resized image and store it in member variable.
405 slReturnCode = m_slCamera.retrieveMeasure(m_slPointCloud, sl::MEASURE::XYZBGRA, m_slMemoryType, sl::Resolution(m_nPropResolutionX, m_nPropResolutionY));
406 // Check that the regular frame was retrieved successfully.
407 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
408 {
409 // Submit logger message.
410 LOG_WARNING(logging::g_qSharedLogger,
411 "Unable to retrieve new point cloud for stereo camera {} ({})! sl::ERROR_CODE is: {}",
412 sl::toString(m_slCameraModel).get(),
413 m_unCameraSerialNumber,
414 sl::toString(slReturnCode).get());
415 }
416 }
417
418 // Check if positional tracking is enabled.
419 if (m_slCamera.isPositionalTrackingEnabled())
420 {
421 // Check if poses have been requested.
422 if (m_bPosesQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
423 {
424 // Create instance variable for storing the result of retrieving the pose.
425 sl::POSITIONAL_TRACKING_STATE slPoseTrackReturnCode;
426
427 // Get normal vision tracking pose from camera.
428 slPoseTrackReturnCode = m_slCamera.getPosition(m_slCameraPose, sl::REFERENCE_FRAME::WORLD);
429 // Check that the regular frame was retrieved successfully.
430 if (slPoseTrackReturnCode != sl::POSITIONAL_TRACKING_STATE::OK)
431 {
432 // Submit logger message.
433 LOG_WARNING(logging::g_qSharedLogger,
434 "Unable to retrieve new positional tracking pose for stereo camera {} ({})! sl::POSITIONAL_TRACKING_STATE is: {}",
435 sl::toString(m_slCameraModel).get(),
436 m_unCameraSerialNumber,
437 sl::toString(slPoseTrackReturnCode).get());
438 }
439 }
440
441 // Check if floor planes are being requested.
442 if (m_bFloorsQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
443 {
444 // Get the current pose of the camera.
445 slReturnCode = m_slCamera.findFloorPlane(m_slFloorPlane,
446 m_slFloorTrackingTransform,
447 m_slCameraPose.getTranslation().y,
448 m_slCameraPose.getRotationMatrix(),
449 m_fExpectedCameraHeightFromFloorTolerance);
450 // Check that the regular frame was retrieved successfully.
451 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
452 {
453 // Submit logger message.
454 LOG_WARNING(logging::g_qSharedLogger,
455 "Unable to retrieve new floor plane for stereo camera {} ({})! sl::ERROR_CODE is: {}",
456 sl::toString(m_slCameraModel).get(),
457 m_unCameraSerialNumber,
458 sl::toString(slReturnCode).get());
459 }
460 }
461 }
462
463 // Get the IMU, barometer, magnetometer, and temperature sensor info from the camera.
464 if (m_bSensorsQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
465 {
466 // Get the sensor data from the camera.
467 slReturnCode = m_slCamera.getSensorsData(m_slSensorsData, sl::TIME_REFERENCE::CURRENT);
468
469 // Check if the sensor data was retrieved successfully.
470 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
471 {
472 // Submit logger message.
473 LOG_WARNING(logging::g_qSharedLogger,
474 "Unable to retrieve sensor data for stereo camera {} ({})! sl::ERROR_CODE is: {}",
475 sl::toString(m_slCameraModel).get(),
476 m_unCameraSerialNumber,
477 sl::toString(slReturnCode).get());
478 }
479 }
480
481 // Check if object detection is enabled.
482 if (m_slCamera.isObjectDetectionEnabled())
483 {
484 // Check if objects have been requested.
485 if (m_bObjectsQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
486 {
487 // Get updated objects from camera.
488 slReturnCode = m_slCamera.retrieveObjects(m_slDetectedObjects);
489 // Check that the regular frame was retrieved successfully.
490 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
491 {
492 // Submit logger message.
493 LOG_WARNING(logging::g_qSharedLogger,
494 "Unable to retrieve new object data for stereo camera {} ({})! sl::ERROR_CODE is: {}",
495 sl::toString(m_slCameraModel).get(),
496 m_unCameraSerialNumber,
497 sl::toString(slReturnCode).get());
498 }
499 }
500
501 // Check if batched object data is enabled.
502 if (m_slObjectDetectionBatchParams.enable)
503 {
504 // Check if batched objects have been requested.
505 if (m_bBatchedObjectsQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
506 {
507 // Get updated batched objects from camera.
508 slReturnCode = m_slCamera.getObjectsBatch(m_slDetectedObjectsBatched);
509 // Check that the regular frame was retrieved successfully.
510 if (slReturnCode != sl::ERROR_CODE::SUCCESS)
511 {
512 // Submit logger message.
513 LOG_WARNING(logging::g_qSharedLogger,
514 "Unable to retrieve new batched object data for stereo camera {} ({})! sl::ERROR_CODE is: {}",
515 sl::toString(m_slCameraModel).get(),
516 m_unCameraSerialNumber,
517 sl::toString(slReturnCode).get());
518 }
519 }
520 }
521 }
522 // Detection not enabled, but got requests.
523 else if (m_bObjectsQueued.load(std::memory_order_relaxed) || m_bBatchedObjectsQueued.load(std::memory_order_relaxed))
524 {
525 // Submit logger message.
526 LOG_WARNING(logging::g_qSharedLogger,
527 "Unable to retrieve new object data for stereo camera {} ({})! Object detection is disabled!",
528 sl::toString(m_slCameraModel).get(),
529 m_unCameraSerialNumber);
530 }
531 }
532 else
533 {
534 // Submit logger message.
535 LOG_ERROR(logging::g_qSharedLogger,
536 "Unable to update stereo camera {} ({}) frames, measurements, and sensors! sl::ERROR_CODE is: {}. Closing camera...",
537 sl::toString(m_slCameraModel).get(),
538 m_unCameraSerialNumber,
539 sl::toString(slReturnCode).get());
540
541 // Release camera resources.
542 m_slCamera.close();
543 }
544 }
545
546 // Acquire a shared_lock on the frame copy queue.
547 std::shared_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
548 // Check if any requests have been made.
549 if (!m_qFrameCopySchedule.empty() || !m_qGPUFrameCopySchedule.empty() || !m_qCustomBoxIngestSchedule.empty() || !m_qPoseCopySchedule.empty() ||
550 !m_qFloorCopySchedule.empty() || !m_qSensorsCopySchedule.empty() || !m_qObjectDataCopySchedule.empty() || !m_qObjectBatchedDataCopySchedule.empty())
551 {
552 // Add the length of all queues together to determine how many tasks need to be run.
553 size_t siTotalQueueLength = m_qFrameCopySchedule.size() + m_qGPUFrameCopySchedule.size() + m_qCustomBoxIngestSchedule.size() + m_qPoseCopySchedule.size() +
554 m_qFloorCopySchedule.size() + m_qSensorsCopySchedule.size() + m_qObjectDataCopySchedule.size() +
555 m_qObjectBatchedDataCopySchedule.size();
556
557 // Start the thread pool to copy member variables to requesting other threads. Num of tasks queued depends on number of member variables updates and requests.
558 this->RunDetachedPool(siTotalQueueLength, m_nNumFrameRetrievalThreads);
559
560 // Get current time.
561 std::chrono::_V2::system_clock::duration tmCurrentTime = std::chrono::high_resolution_clock::now().time_since_epoch();
562 // Only reset once every couple seconds.
563 if (std::chrono::duration_cast<std::chrono::seconds>(tmCurrentTime).count() % 31 == 0 && !m_bQueueTogglesAlreadyReset)
564 {
565 // Reset queue counters.
566 m_bNormalFramesQueued.store(false, ATOMIC_MEMORY_ORDER_METHOD);
567 m_bDepthFramesQueued.store(false, ATOMIC_MEMORY_ORDER_METHOD);
568 m_bPointCloudsQueued.store(false, ATOMIC_MEMORY_ORDER_METHOD);
569 m_bPosesQueued.store(false, ATOMIC_MEMORY_ORDER_METHOD);
570 m_bFloorsQueued.store(false, ATOMIC_MEMORY_ORDER_METHOD);
571 m_bSensorsQueued.store(false, ATOMIC_MEMORY_ORDER_METHOD);
572 m_bObjectsQueued.store(false, ATOMIC_MEMORY_ORDER_METHOD);
573 m_bBatchedObjectsQueued.store(false, ATOMIC_MEMORY_ORDER_METHOD);
574
575 // Set reset toggle.
576 m_bQueueTogglesAlreadyReset = true;
577 }
578 // Crucial for toggle action. If time is not evenly devisable and toggles have previously been set, reset queue reset boolean.
579 else if (m_bQueueTogglesAlreadyReset)
580 {
581 // Reset reset toggle.
582 m_bQueueTogglesAlreadyReset = false;
583 }
584
585 // Wait for thread pool to finish.
586 this->JoinPool();
587 }
588
589 // Release lock on frame copy queue.
590 lkSchedulers.unlock();
591}
void RunDetachedPool(const unsigned int nNumTasksToQueue, const unsigned int nNumThreads=2, const bool bForceStopCurrentThreads=false)
When this method is called, it starts a thread pool full of threads that don't return std::futures (l...
Definition AutonomyThread.hpp:399
void JoinPool()
Waits for pool to finish executing tasks. This method will block the calling code until thread is fin...
Definition AutonomyThread.hpp:502
sl::ERROR_CODE EnableSpatialMapping() override
Enabled the spatial mapping feature of the camera. Pose tracking will be enabled if it is not already...
Definition ZEDCam.cpp:1593
sl::ERROR_CODE EnableObjectDetection(const bool bEnableBatching=false) override
Enables the object detection and tracking feature of the camera.
Definition ZEDCam.cpp:1680
Here is the call graph for this function:

◆ PooledLinearCode()

void ZEDCam::PooledLinearCode ( )
overrideprivatevirtual

This method holds the code that is ran in the thread pool started by the ThreadedLinearCode() method. It copies the data from the different data objects to references of the same type stored in a queue filled by the Request methods.

Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-09-08

Implements AutonomyThread< void >.

604{
606 // Frame queue.
608 // Check if we are using CPU or GPU mats.
609 if (m_slMemoryType == sl::MEM::CPU)
610 {
611 // Acquire mutex for getting frames out of the queue.
612 std::unique_lock<std::shared_mutex> lkFrameQueue(m_muFrameCopyMutex);
613 // Check if the queue is empty.
614 if (!m_qFrameCopySchedule.empty())
615 {
616 // Get frame container out of queue.
617 containers::FrameFetchContainer<cv::Mat> stContainer = m_qFrameCopySchedule.front();
618 // Pop out of queue.
619 m_qFrameCopySchedule.pop();
620 // Release lock.
621 lkFrameQueue.unlock();
622
623 // Determine which frame should be copied.
624 switch (stContainer.eFrameType)
625 {
626 case PIXEL_FORMATS::eBGRA: *stContainer.pFrame = imgops::ConvertSLMatToCVMat(m_slFrame); break;
627 case PIXEL_FORMATS::eDepthMeasure: *stContainer.pFrame = imgops::ConvertSLMatToCVMat(m_slDepthMeasure); break;
628 case PIXEL_FORMATS::eDepthImage: *stContainer.pFrame = imgops::ConvertSLMatToCVMat(m_slDepthImage); break;
629 case PIXEL_FORMATS::eXYZBGRA: *stContainer.pFrame = imgops::ConvertSLMatToCVMat(m_slPointCloud); break;
630 default: *stContainer.pFrame = imgops::ConvertSLMatToCVMat(m_slFrame); break;
631 }
632
633 // Signal future that the frame has been successfully retrieved.
634 stContainer.pCopiedFrameStatus->set_value(true);
635 }
636
637 // Check if anything has been added to the GPU queue.
638 if (!m_qGPUFrameCopySchedule.empty())
639 {
640 // Submit logger error.
641 LOG_ERROR(logging::g_qSharedLogger,
642 "ZEDCam ({}) is in CPU sl::Mat mode but a GPU mat has been added to the copy queue! Whichever thread queued the frame will now appear frozen if "
643 "future.get() is called. Either switch the camera to GPU Mat mode in AutonomyConstants.h or stop queueing frames of type cv::Mat.",
644 m_unCameraSerialNumber);
645 }
646 }
647 // Use GPU mat.
648 else
649 {
650 // Acquire mutex for getting frames out of the queue.
651 std::unique_lock<std::shared_mutex> lkFrameQueue(m_muFrameCopyMutex);
652 // Check if the queue is empty.
653 if (!m_qGPUFrameCopySchedule.empty())
654 {
655 // Get frame container out of queue.
656 containers::FrameFetchContainer<cv::cuda::GpuMat> stContainer = m_qGPUFrameCopySchedule.front();
657 // Pop out of queue.
658 m_qGPUFrameCopySchedule.pop();
659 // Release lock.
660 lkFrameQueue.unlock();
661
662 // Determine which frame should be copied.
663 switch (stContainer.eFrameType)
664 {
665 case PIXEL_FORMATS::eBGRA: *stContainer.pFrame = imgops::ConvertSLMatToGPUMat(m_slFrame); break;
666 case PIXEL_FORMATS::eDepthMeasure: *stContainer.pFrame = imgops::ConvertSLMatToGPUMat(m_slDepthMeasure); break;
667 case PIXEL_FORMATS::eDepthImage: *stContainer.pFrame = imgops::ConvertSLMatToGPUMat(m_slDepthImage); break;
668 case PIXEL_FORMATS::eXYZBGRA: *stContainer.pFrame = imgops::ConvertSLMatToGPUMat(m_slPointCloud); break;
669 default: *stContainer.pFrame = imgops::ConvertSLMatToGPUMat(m_slFrame); break;
670 }
671
672 // Signal future that the frame has been successfully retrieved.
673 stContainer.pCopiedFrameStatus->set_value(true);
674 }
675
676 // Check if anything has been added to the GPU queue.
677 if (!m_qFrameCopySchedule.empty())
678 {
679 // Submit logger error.
680 LOG_ERROR(logging::g_qSharedLogger,
681 "ZEDCam ({}) is in GPU sl::Mat mode but a CPU mat has been added to the copy queue! Whichever thread queued the frame will now appear frozen if "
682 "future.get() is called. Either switch the camera to GPU Mat mode in AutonomyConstants.h or stop queueing frames of type cv::cuda::GpuMat.",
683 m_unCameraSerialNumber);
684 }
685 }
686
688 // Pose queue.
690 // Acquire mutex for getting data out of the pose queue.
691 std::unique_lock<std::shared_mutex> lkPoseQueue(m_muPoseCopyMutex);
692 // Check if the queue is empty.
693 if (!m_qPoseCopySchedule.empty())
694 {
695 // Get pose container out of queue.
696 containers::DataFetchContainer<Pose> stContainer = m_qPoseCopySchedule.front();
697 // Pop out of queue.
698 m_qPoseCopySchedule.pop();
699 // Release lock.
700 lkPoseQueue.unlock();
701
702 // Rotate the ZED position coordinate frame to realign with the UTM global coordinate frame.
703 std::vector<numops::CoordinatePoint<double>> vPointCloud;
704 vPointCloud.emplace_back(m_slCameraPose.getTranslation().x, m_slCameraPose.getTranslation().y, m_slCameraPose.getTranslation().z);
705 // Get angle realignments.
706 double dNewXO = numops::InputAngleModulus<double>(m_slCameraPose.getEulerAngles(false).x + m_dPoseOffsetXO, 0.0, 360.0);
707 double dNewYO = numops::InputAngleModulus<double>(m_slCameraPose.getEulerAngles(false).y + m_dPoseOffsetYO, 0.0, 360.0);
708 double dNewZO = numops::InputAngleModulus<double>(m_slCameraPose.getEulerAngles(false).z + m_dPoseOffsetZO, 0.0, 360.0);
709 // Rotate coordinate frame.
710 numops::CoordinateFrameRotate3D(vPointCloud, m_dPoseOffsetXO, m_dPoseOffsetYO, m_dPoseOffsetZO);
711 // Repack values into pose.
712 Pose stPose(vPointCloud[0].tX + m_dPoseOffsetX, vPointCloud[0].tY + m_dPoseOffsetY, vPointCloud[0].tZ + m_dPoseOffsetZ, dNewXO, dNewYO, dNewZO);
713
714 // ISSUE NOTE: Might be in the future if we ever change our coordinate system on the ZED. This can be used to fix the directions of the Pose's coordinate system.
715 // // Check ZED coordinate system.
716 // switch (m_slCameraParams.coordinate_system)
717 // {
718 // case sl::COORDINATE_SYSTEM::LEFT_HANDED_Y_UP:
719 // {
720 // // Realign based in the signedness of this coordinate system. Z is backwards.
721 // stPose.stTranslation.dZ *= -1;
722 // break;
723 // }
724 // default:
725 // {
726 // // No need to flip signs for other coordinate systems.
727 // break;
728 // }
729 // }
730
731 // Copy pose.
732 *stContainer.pData = stPose;
733
734 // Signal future that the data has been successfully retrieved.
735 stContainer.pCopiedDataStatus->set_value(true);
736 }
737 else
738 {
739 // Release lock.
740 lkPoseQueue.unlock();
741 }
742
744 // Plane queue.
746 // Acquire mutex for getting frames out of the plane queue.
747 std::unique_lock<std::shared_mutex> lkPlaneQueue(m_muFloorCopyMutex);
748 // Check if the queue is empty.
749 if (!m_qFloorCopySchedule.empty())
750 {
751 // Get frame container out of queue.
752 containers::DataFetchContainer<sl::Plane> stContainer = m_qFloorCopySchedule.front();
753 // Pop out of queue.
754 m_qFloorCopySchedule.pop();
755 // Release lock.
756 lkPlaneQueue.unlock();
757
758 // Copy pose.
759 *stContainer.pData = sl::Plane(m_slFloorPlane);
760
761 // Signal future that the data has been successfully retrieved.
762 stContainer.pCopiedDataStatus->set_value(true);
763 }
764 else
765 {
766 // Release lock.
767 lkPlaneQueue.unlock();
768 }
769
771 // Sensors queue.
773 // Acquire mutex for getting frames out of the sensors queue.
774 std::unique_lock<std::shared_mutex> lkSensorsQueue(m_muSensorsCopyMutex);
775 // Check if the queue is empty.
776 if (!m_qSensorsCopySchedule.empty())
777 {
778 // Get frame container out of queue.
779 containers::DataFetchContainer<sl::SensorsData> stContainer = m_qSensorsCopySchedule.front();
780 // Pop out of queue.
781 m_qSensorsCopySchedule.pop();
782 // Release lock.
783 lkSensorsQueue.unlock();
784
785 // Copy pose.
786 *stContainer.pData = sl::SensorsData(m_slSensorsData);
787
788 // Signal future that the data had been successfully retrieved.
789 stContainer.pCopiedDataStatus->set_value(true);
790 }
791 else
792 {
793 // Release lock.
794 lkSensorsQueue.unlock();
795 }
796
798 // ObjectData queue.
800 // Acquire mutex for getting data out of the pose queue.
801 std::unique_lock<std::shared_mutex> lkObjectDataQueue(m_muObjectDataCopyMutex);
802 // Check if the queue is empty.
803 if (!m_qObjectDataCopySchedule.empty())
804 {
805 // Get frame container out of queue.
806 containers::DataFetchContainer<std::vector<sl::ObjectData>> stContainer = m_qObjectDataCopySchedule.front();
807 // Pop out of queue.
808 m_qObjectDataCopySchedule.pop();
809 // Release lock.
810 lkObjectDataQueue.unlock();
811
812 // Make copy of object vector. (Apparently the assignment operator actually does a deep copy)
813 *stContainer.pData = m_slDetectedObjects.object_list;
814
815 // Signal future that the data has been successfully retrieved.
816 stContainer.pCopiedDataStatus->set_value(true);
817 }
818 else
819 {
820 // Release lock.
821 lkObjectDataQueue.unlock();
822 }
823
825 // ObjectData Batched queue.
827 // Acquire mutex for getting data out of the pose queue.
828 std::unique_lock<std::shared_mutex> lkObjectBatchedDataQueue(m_muObjectBatchedDataCopyMutex);
829 // Check if the queue is empty.
830 if (!m_qObjectBatchedDataCopySchedule.empty())
831 {
832 // Get frame container out of queue.
833 containers::DataFetchContainer<std::vector<sl::ObjectsBatch>> stContainer = m_qObjectBatchedDataCopySchedule.front();
834 // Pop out of queue.
835 m_qObjectBatchedDataCopySchedule.pop();
836 // Release lock.
837 lkObjectBatchedDataQueue.unlock();
838
839 // Make copy of object vector. (Apparently the assignment operator actually does a deep copy)
840 *stContainer.pData = m_slDetectedObjectsBatched;
841
842 // Signal future that the data has been successfully retrieved.
843 stContainer.pCopiedDataStatus->set_value(true);
844 }
845 else
846 {
847 // Release lock.
848 lkObjectBatchedDataQueue.unlock();
849 }
850}
cv::cuda::GpuMat ConvertSLMatToGPUMat(sl::Mat &slInputMat)
Convert a ZEDSDK sl::Mat object into an OpenCV cv::cuda::GpuMat object. Keeps all Mat memory in GPU V...
Definition ImageOperations.hpp:127
cv::Mat ConvertSLMatToCVMat(sl::Mat &slInputMat)
Convert a ZEDSDK sl::Mat object into an OpenCV cv::Mat object. This copies the mat from GPU memory to...
Definition ImageOperations.hpp:106
constexpr void CoordinateFrameRotate3D(std::vector< CoordinatePoint< T > > &vPointCloud, const double dXRotationDegrees, const double dYRotationDegrees, const double dZRotationDegrees)
This method will rotate a list of 3D coordinate points a variable amount of degrees around the X,...
Definition NumberOperations.hpp:266
Here is the call graph for this function:

The documentation for this class was generated from the following files: