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
SIMZEDCam Class Reference

This class implements and interfaces with the SIM cameras and data. 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 <SIMZEDCam.h>

Inheritance diagram for SIMZEDCam:
Collaboration diagram for SIMZEDCam:

Public Member Functions

 SIMZEDCam (const std::string szCameraPath, const int nPropResolutionX, const int nPropResolutionY, const int nPropFramesPerSecond, const double dPropHorizontalFOV, const double dPropVerticalFOV, const bool bEnableRecordingFlag, const int nNumFrameRetrievalThreads=10, const unsigned int unCameraSerialNumber=0)
 Construct a new SIM Cam:: SIM Cam object.
 
 ~SIMZEDCam ()
 Destroy the SIM Cam:: SIM Cam object.
 
std::future< bool > RequestFrameCopy (cv::Mat &cvFrame) override
 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)
 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)
 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 > RequestPositionalPoseCopy (Pose &stPose) override
 Puts a sl::GeoPose pointer into a queue so a copy of a GeoPose from the camera can be written to it.
 
std::future< bool > RequestSensorsCopy (sl::SensorsData &slSensorsData) override
 Requests a copy of the sensors data from the camera.
 
sl::ERROR_CODE ResetPositionalTracking () override
 This method is used to reset the positional tracking of the camera. Because this is a simulation camera, and then ZEDSDK is not available, this method will just reset the offsets to zero.
 
sl::ERROR_CODE RebootCamera () override
 This method is used to reboot the camera. This method will stop the camera thread, join the camera thread, destroy the camera stream objects, reconstruct the camera stream objects, set the frame callbacks, and restart the camera thread. This simulates a camera reboot since the ZED SDK is not available.
 
sl::ERROR_CODE EnablePositionalTracking (const float fExpectedCameraHeightFromFloorTolerance=constants::ZED_DEFAULT_FLOOR_PLANE_ERROR) override
 This method is used to enable positional tracking on the camera. Since this is a simulation camera, this method will just set the member variable and then use the NavBoard to simulate the camera's position.
 
void DisablePositionalTracking () override
 This method is used to disable positional tracking on the camera. Since this is a simulation camera, this method will just set the member variable.
 
void SetPositionalPose (const double dX, const double dY, const double dZ, const double dXO, const double dYO, const double dZO) override
 This method is used to set the positional pose of the camera. Since this is a simulation camera, this method will just set the offset member variables.
 
bool GetCameraIsOpen () override
 Accessor for the camera open status.
 
bool GetUsingGPUMem () const override
 Returns if the camera is using GPU memory. This is a simulation camera, so this method will always return false.
 
std::string GetCameraModel () override
 Accessor for the name of this model of camera.
 
bool GetPositionalTrackingEnabled () override
 Accessor for the if the camera's positional tracking is enabled. Since this is a simulation camera, this method will just return the member variable.
 
- 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.
 
virtual std::future< bool > RequestFrameCopy (cv::cuda::GpuMat &cvGPUFrame)
 Puts a frame pointer into a queue so a copy of a frame from the camera can be written to it.
 
virtual std::future< bool > RequestDepthCopy (cv::cuda::GpuMat &cvGPUDepth, const bool bRetrieveMeasure=true)
 Puts a frame pointer into a queue so a copy of a depth frame from the camera can be written to it.
 
virtual std::future< bool > RequestPointCloudCopy (cv::cuda::GpuMat &cvGPUPointCloud)
 Puts a frame pointer into a queue so a copy of a point cloud from the camera can be written to it.
 
virtual std::future< bool > RequestFloorPlaneCopy (sl::Plane &slFloorPlane)
 Puts a FloorPlane pointer into a queue so a copy of a FloorPlane from the camera can be written to it.
 
virtual std::future< bool > RequestObjectsCopy (std::vector< sl::ObjectData > &vObjectData)
 Puts a vector of ObjectData pointers into a queue so a copy of a vector of ObjectData from the camera can be written to it.
 
virtual std::future< bool > RequestBatchedObjectsCopy (std::vector< sl::ObjectsBatch > &vBatchedObjectData)
 Puts a vector of ObjectsBatch pointers into a queue so a copy of a vector of ObjectsBatch from the camera can be written to it.
 
virtual sl::ERROR_CODE TrackCustomBoxObjects (std::vector< ZedObjectData > &vCustomObjects)
 Tracks custom bounding boxes in the camera's field of view.
 
virtual sl::ERROR_CODE EnableSpatialMapping ()
 Enables spatial mapping.
 
virtual void DisableSpatialMapping ()
 Disables spatial mapping.
 
virtual sl::ERROR_CODE EnableObjectDetection (const bool bEnableBatching=false)
 Enables object detection.
 
virtual void DisableObjectDetection ()
 Disables object detection.
 
virtual unsigned int GetCameraSerial ()
 Accessor for the Camera Serial private member.
 
virtual sl::PositionalTrackingStatus GetPositionalTrackingState ()
 Accessor for the Positional Tracking State private member.
 
virtual sl::SPATIAL_MAPPING_STATE GetSpatialMappingState ()
 Accessor for the Spatial Mapping State private member.
 
virtual sl::SPATIAL_MAPPING_STATE ExtractSpatialMapAsync (std::future< sl::Mesh > &fuMeshFuture)
 Puts a Mesh pointer into a queue so a copy of a spatial mapping mesh from the camera can be written to it.
 
virtual bool GetObjectDetectionEnabled ()
 Accessor for the Object Detection Enabled private member.
 
- 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 get new frames from the OpenCV VideoCapture object and stores it in a member variable. 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 vector queued up by the Grab methods.
 
void SetCallbacks ()
 This method sets the callbacks for the WebRTC connections.
 
void EstimateDepthMeasure (const cv::Mat &cvDepthImage, cv::Mat &cvDepthMeasure)
 This method estimates the depth measure from the depth image.
 
void CalculatePointCloud (const cv::Mat &cvDepthMeasure, cv::Mat &cvPointCloud)
 This method calculates a point cloud from the decoded depth measure use some simple trig and the camera FOV.
 

Private Attributes

const std::function< void(const rovecomm::RoveCommPacket< double > &, const sockaddr_in &)> ProcessIMUData
 Callback function to process incoming IMU data from RoveComm for the SIM ZED Camera. Normally, this data would come from the physical ZED camera's IMU over USB,.
 
std::string m_szCameraPath
 
std::atomic< bool > m_bCameraPositionalTrackingEnabled
 
std::string m_szFullStreamName
 
sl::SensorsData m_stIMUData
 
std::unique_ptr< WebRTCm_pRGBStream
 
std::unique_ptr< WebRTCm_pDepthImageStream
 
double m_dPoseOffsetX
 
double m_dPoseOffsetY
 
double m_dPoseOffsetZ
 
double m_dPoseOffsetXO
 
double m_dPoseOffsetYO
 
double m_dPoseOffsetZO
 
geoops::RoverPose m_stCurrentRoverPose
 
std::shared_mutex m_muCurrentRoverPoseMutex
 
cv::Mat m_cvFrame
 
cv::Mat m_cvDepthImageBuffer
 
cv::Mat m_cvDepthImage
 
cv::Mat m_cvDepthMeasure
 
cv::Mat m_cvPointCloud
 
std::queue< containers::DataFetchContainer< Pose > > m_qPoseCopySchedule
 
std::queue< containers::DataFetchContainer< sl::SensorsData > > m_qSensorsCopySchedule
 
std::shared_mutex m_muWebRTCRGBImageCopyMutex
 
std::shared_mutex m_muWebRTCDepthImageCopyMutex
 
std::shared_mutex m_muPoseCopyMutex
 
std::shared_mutex m_muSensorsCopyMutex
 
bool m_bQueueTogglesAlreadyReset
 
std::atomic< bool > m_bPosesQueued
 
std::atomic< bool > m_bSensorsQueued
 

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 SIM cameras and data. 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-30

Constructor & Destructor Documentation

◆ SIMZEDCam()

SIMZEDCam::SIMZEDCam ( const std::string  szCameraPath,
const int  nPropResolutionX,
const int  nPropResolutionY,
const int  nPropFramesPerSecond,
const double  dPropHorizontalFOV,
const double  dPropVerticalFOV,
const bool  bEnableRecordingFlag,
const int  nNumFrameRetrievalThreads = 10,
const unsigned int  unCameraSerialNumber = 0 
)

Construct a new SIM Cam:: SIM Cam object.

Parameters
szCameraPath- The file path to the camera hardware.
nPropResolutionX- X res of camera.
nPropResolutionY- Y res of camera.
nPropFramesPerSecond- FPS camera is running at.
ePropPixelFormat- The pixel layout/format of the image.
dPropHorizontalFOV- The horizontal field of view.
dPropVerticalFOV- The vertical field of view.
bEnableRecordingFlag- Whether or not this camera should be recorded.
nNumFrameRetrievalThreads- The number of threads to use for frame queueing and copying.
unCameraSerialNumber- 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-09-30
51 :
52 ZEDCamera(nPropResolutionX,
53 nPropResolutionY,
54 nPropFramesPerSecond,
55 dPropHorizontalFOV,
56 dPropVerticalFOV,
57 bEnableRecordingFlag,
58 false,
59 false,
60 nNumFrameRetrievalThreads,
61 unCameraSerialNumber)
62{
63 // Create instance variables.
64 std::string szWebsocketAddress = "";
65 std::string szFullStreamName = "";
66
67 // Split the websocket URL from the stream name.
68 size_t siPos = szCameraPath.rfind('/');
69
70 // Ensure we found a slash and it's not just the protocol 'ws://'
71 if (siPos != std::string::npos && siPos > 6)
72 {
73 // Assign directly to your instance variables (this copies the data safely)
74 szWebsocketAddress = szCameraPath.substr(0, siPos);
75 szFullStreamName = szCameraPath.substr(siPos + 1);
76
77 LOG_NOTICE(logging::g_qSharedLogger, "Address: {}, Identifier: {}", szWebsocketAddress, szFullStreamName);
78 }
79 else
80 {
81 LOG_ERROR(logging::g_qSharedLogger, "Invalid Camera Path: {}", szCameraPath);
82 }
83
84 // Assign member variables.
85 m_szCameraPath = szWebsocketAddress;
86 m_szFullStreamName = szFullStreamName;
87 m_nNumFrameRetrievalThreads = nNumFrameRetrievalThreads;
88 m_bQueueTogglesAlreadyReset = false;
89
90 // Initialize OpenCV mats to a black/empty image the size of the camera resolution.
91 m_cvFrame = cv::Mat::zeros(nPropResolutionY, nPropResolutionX, CV_8UC4);
92 m_cvDepthImage = cv::Mat::zeros(nPropResolutionY, nPropResolutionX, CV_8UC1);
93 m_cvDepthMeasure = cv::Mat::zeros(nPropResolutionY, nPropResolutionX, CV_32FC1);
94 m_cvPointCloud = cv::Mat::zeros(nPropResolutionY, nPropResolutionX, CV_32FC4);
95
96 // Construct camera stream objects. Append proper camera path arguments to each URL camera path.
97 m_pRGBStream = std::make_unique<WebRTC>(szWebsocketAddress, m_szFullStreamName + "RGB");
98 m_pDepthImageStream = std::make_unique<WebRTC>(szWebsocketAddress, m_szFullStreamName + "DepthImage");
99
100 // Set callbacks for the WebRTC connections.
101 this->SetCallbacks();
102
103 // Subscribe to RoveSoSimulator packets.
104 rovecomm::RoveCommPacket<u_int8_t> stSubscribePacket;
105 stSubscribePacket.unDataId = manifest::System::SUBSCRIBE_DATA_ID;
106 stSubscribePacket.unDataCount = 0;
107 stSubscribePacket.eDataType = manifest::DataTypes::UINT8_T;
108 stSubscribePacket.vData = std::vector<uint8_t>{};
109 // Set RoveComm callbacks for the data from the sim.
110 if (network::g_pRoveCommUDPNode)
111 {
112 // Determine the IP address to send the subscribe packet to.
113 const char* cIPAddress = constants::MODE_SIM ? constants::SIM_IP_ADDRESS.c_str() : manifest::RoveSoSimulator::IP_ADDRESS.IP_STR.c_str();
114
115 // Send subscribe packet to RoveSoSimulator.
116 network::g_pRoveCommUDPNode->SendUDPPacket(stSubscribePacket, cIPAddress, constants::ROVECOMM_OUTGOING_UDP_PORT);
117
118 // Set RoveComm callbacks.
119 network::g_pRoveCommUDPNode->AddUDPCallback<double>(ProcessIMUData, manifest::RoveSoSimulator::TELEMETRY.find("IMU")->second.DATA_ID);
120 }
121
122 // Set max FPS of the ThreadedContinuousCode method.
123 this->SetMainThreadIPSLimit(nPropFramesPerSecond);
124}
void SetMainThreadIPSLimit(int nMaxIterationsPerSecond=0)
Mutator for the Main Thread Max I P S private member.
Definition AutonomyThread.hpp:530
void SetCallbacks()
This method sets the callbacks for the WebRTC connections.
Definition SIMZEDCam.cpp:157
const std::function< void(const rovecomm::RoveCommPacket< double > &, const sockaddr_in &)> ProcessIMUData
Callback function to process incoming IMU data from RoveComm for the SIM ZED Camera....
Definition SIMZEDCam.h:96
This class serves as a middle inheritor between the Camera interface and the ZEDCam class....
Definition ZEDCamera.hpp:33
static CV_NODISCARD_STD MatExpr zeros(int rows, int cols, int type)
Here is the call graph for this function:

◆ ~SIMZEDCam()

SIMZEDCam::~SIMZEDCam ( )

Destroy the SIM Cam:: SIM Cam object.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-09-30
134{
135 // Close the WebRTC connections.
136 if (m_pRGBStream)
137 {
138 m_pRGBStream->CloseConnection();
139 }
140 if (m_pDepthImageStream)
141 {
142 m_pDepthImageStream->CloseConnection();
143 }
144
145 // Stop threaded code.
146 this->RequestStop();
147 this->Join();
148}
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()

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

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 store the frame in.
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-30

Implements ZEDCamera.

512{
513 // Assemble the FrameFetchContainer.
514 containers::FrameFetchContainer<cv::Mat> stContainer(cvFrame, m_ePropPixelFormat);
515
516 // Acquire lock on frame copy queue.
517 std::unique_lock<std::shared_mutex> lkScheduler(m_muPoolScheduleMutex);
518 // Append frame fetch container to the schedule queue.
519 m_qFrameCopySchedule.push(stContainer);
520 // Release lock on the frame schedule queue.
521 lkScheduler.unlock();
522
523 // Return the future from the promise stored in the container.
524 return stContainer.pCopiedFrameStatus->get_future();
525}
This struct is used to carry references to camera frames for scheduling and copying....
Definition FetchContainers.hpp:88

◆ RequestDepthCopy()

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

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.

543{
544 // Create instance variables.
545 PIXEL_FORMATS eFrameType;
546
547 // Check if the container should be set to retrieve an image or a measure.
548 bRetrieveMeasure ? eFrameType = PIXEL_FORMATS::eDepthMeasure : eFrameType = PIXEL_FORMATS::eDepthImage;
549 // Assemble container.
550 containers::FrameFetchContainer<cv::Mat> stContainer(cvDepth, eFrameType);
551
552 // Acquire lock on frame copy queue.
553 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
554 // Append frame fetch container to the schedule queue.
555 m_qFrameCopySchedule.push(stContainer);
556 // Release lock on the frame schedule queue.
557 lkSchedulers.unlock();
558
559 // Return the future from the promise stored in the container.
560 return stContainer.pCopiedFrameStatus->get_future();
561}

◆ RequestPointCloudCopy()

std::future< bool > SIMZEDCam::RequestPointCloudCopy ( cv::Mat cvPointCloud)
virtual

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.

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.

579{
580 // Assemble the FrameFetchContainer.
581 containers::FrameFetchContainer<cv::Mat> stContainer(cvPointCloud, PIXEL_FORMATS::eXYZ);
582
583 // Acquire lock on frame copy queue.
584 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
585 // Append frame fetch container to the schedule queue.
586 m_qFrameCopySchedule.push(stContainer);
587 // Release lock on the frame schedule queue.
588 lkSchedulers.unlock();
589
590 // Return the future from the promise stored in the container.
591 return stContainer.pCopiedFrameStatus->get_future();
592}

◆ RequestPositionalPoseCopy()

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

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

Parameters
stPose- A reference to the sl::GeoPose to store the GeoPose in.
Returns
std::future<bool> - A future that should be waited on before the passed in GeoPose is used.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-12-26

Implements ZEDCamera.

604{
605 // Check if positional tracking is enabled.
606 if (m_bCameraPositionalTrackingEnabled)
607 {
608 // Assemble the data container.
609 containers::DataFetchContainer<Pose> stContainer(stPose);
610
611 // Acquire lock on pose copy queue.
612 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
613 // Append pose fetch container to the schedule queue.
614 m_qPoseCopySchedule.push(stContainer);
615 // Release lock on the pose schedule queue.
616 lkSchedulers.unlock();
617
618 // Check if pose queue toggle has already been set.
619 if (!m_bPosesQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
620 {
621 // Signify that the pose queue is not empty.
622 m_bPosesQueued.store(true, ATOMIC_MEMORY_ORDER_METHOD);
623 }
624
625 // Return the future from the promise stored in the container.
626 return stContainer.pCopiedDataStatus->get_future();
627 }
628 else
629 {
630 // Submit logger message.
631 LOG_WARNING(logging::g_qSharedLogger, "Attempted to get ZED positional pose but positional tracking is not enabled or is still initializing!");
632
633 // Create dummy promise to return the future.
634 std::promise<bool> pmDummyPromise;
635 std::future<bool> fuDummyFuture = pmDummyPromise.get_future();
636 // Set future value.
637 pmDummyPromise.set_value(false);
638
639 // Return unsuccessful.
640 return fuDummyFuture;
641 }
642}
This struct is used to carry references to any datatype for scheduling and copying....
Definition FetchContainers.hpp:164

◆ RequestSensorsCopy()

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

Requests a copy of the sensors data from the camera.

Parameters
slSensorsData- A reference to the sl::SensorsData to store the sensors data in.
Returns
std::future<bool> - A future that should be waited on before the passed in sensors data is used.
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.

654{
655 // Assemble the DataFetchContainer.
656 containers::DataFetchContainer<sl::SensorsData> stContainer(slSensorsData);
657
658 // Acquire lock on data copy queue.
659 std::unique_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
660 // Append data fetch container to the schedule queue.
661 m_qSensorsCopySchedule.push(stContainer);
662 // Release lock on the data schedule queue.
663 lkSchedulers.unlock();
664
665 // Check if pose queue toggle has already been set.
666 if (!m_bSensorsQueued.load(ATOMIC_MEMORY_ORDER_METHOD))
667 {
668 // Signify that the pose queue is not empty.
669 m_bSensorsQueued.store(true, ATOMIC_MEMORY_ORDER_METHOD);
670 }
671
672 // Return the future from the promise stored in the container.
673 return stContainer.pCopiedDataStatus->get_future();
674}

◆ ResetPositionalTracking()

sl::ERROR_CODE SIMZEDCam::ResetPositionalTracking ( )
overridevirtual

This method is used to reset the positional tracking of the camera. Because this is a simulation camera, and then ZEDSDK is not available, this method will just reset the offsets to zero.

Returns
sl::ERROR_CODE - The error code returned by the ZED SDK. In this case, it will always be SUCCESS.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-12-26

Implements ZEDCamera.

687{
688 // Reset offsets back to zero.
689 m_dPoseOffsetX = 0.0;
690 m_dPoseOffsetY = 0.0;
691 m_dPoseOffsetZ = 0.0;
692 m_dPoseOffsetXO = 0.0;
693 m_dPoseOffsetYO = 0.0;
694 m_dPoseOffsetZO = 0.0;
695
696 return sl::ERROR_CODE::SUCCESS;
697}
Here is the caller graph for this function:

◆ RebootCamera()

sl::ERROR_CODE SIMZEDCam::RebootCamera ( )
overridevirtual

This method is used to reboot the camera. This method will stop the camera thread, join the camera thread, destroy the camera stream objects, reconstruct the camera stream objects, set the frame callbacks, and restart the camera thread. This simulates a camera reboot since the ZED SDK is not available.

Returns
sl::ERROR_CODE - The error code returned by the ZED SDK. In this case, it will always be SUCCESS. Even if the streams are not successfully reconnected, the camera will still be considered open.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om), Sam Hajdukiewicz (saman.nosp@m.thah.nosp@m.ajduk.nosp@m.iewi.nosp@m.cz@gm.nosp@m.ail..nosp@m.com)
Date
2024-12-26

Implements ZEDCamera.

712{
713 // Stop the camera thread.
714 this->RequestStop();
715 // Join the camera thread.
716 this->Join();
717
718 // Destroy the camera stream objects.
719 m_pRGBStream.reset();
720 m_pDepthImageStream.reset();
721 // Reconstruct camera stream objects. Append proper camera path arguments to each URL camera path.
722 m_pRGBStream = std::make_unique<WebRTC>(m_szCameraPath, m_szFullStreamName + "RGB");
723 m_pDepthImageStream = std::make_unique<WebRTC>(m_szCameraPath, m_szFullStreamName + "DepthImage");
724
725 // Set the frame callbacks.
726 this->SetCallbacks();
727
728 // Restart the camera thread.
729 this->Start();
730
731 return sl::ERROR_CODE::SUCCESS;
732}
void Start()
When this method is called, it starts a new thread that runs the code within the ThreadedContinuousCo...
Definition AutonomyThread.hpp:134
Here is the call graph for this function:
Here is the caller graph for this function:

◆ EnablePositionalTracking()

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

This method is used to enable positional tracking on the camera. Since this is a simulation camera, this method will just set the member variable and then use the NavBoard to simulate the camera's position.

Parameters
fExpectedCameraHeightFromFloorTolerance- The expected camera height from the floor tolerance.
Returns
sl::ERROR_CODE - The error code returned by the ZED SDK. In this case, it will always be SUCCESS.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-12-26

Implements ZEDCamera.

746{
747 // Unused parameter.
748 (void) fExpectedCameraHeightFromFloorTolerance;
749 // Update member variables.
750 m_bCameraPositionalTrackingEnabled = true;
751
752 return sl::ERROR_CODE::SUCCESS;
753}
Here is the caller graph for this function:

◆ DisablePositionalTracking()

void SIMZEDCam::DisablePositionalTracking ( )
overridevirtual

This method is used to disable positional tracking on the camera. Since this is a simulation camera, this method will just set the member variable.

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

Implements ZEDCamera.

764{
765 // Update member variables.
766 m_bCameraPositionalTrackingEnabled = false;
767}
Here is the caller graph for this function:

◆ SetPositionalPose()

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

This method is used to set the positional pose of the camera. Since this is a simulation camera, this method will just set the offset member variables.

Parameters
dX- The new X position of the camera in ZED_MEASURE_UNITS.
dY- The new Y position of the camera in ZED_MEASURE_UNITS.
dZ- The new Z position of the camera in ZED_MEASURE_UNITS.
dXO- The new tilt of the camera around the X axis in degrees.
dYO- The new tilt of the camera around the Y axis in degrees.
dZO- The new tilt of the camera around the Z axis in degrees.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-12-26

Implements ZEDCamera.

784{
785 // Acquire lock on the current rover pose mutex.
786 std::unique_lock<std::shared_mutex> lkPose(m_muCurrentRoverPoseMutex);
787
788 // Update offset member variables.
789 m_dPoseOffsetX = dX - m_stCurrentRoverPose.GetUTMCoordinate().dEasting;
790 m_dPoseOffsetY = dY - m_stCurrentRoverPose.GetUTMCoordinate().dAltitude;
791 m_dPoseOffsetZ = dZ - m_stCurrentRoverPose.GetUTMCoordinate().dNorthing;
792 m_dPoseOffsetXO = dXO;
793 m_dPoseOffsetYO = dYO - m_stCurrentRoverPose.GetCompassHeading();
794 m_dPoseOffsetZO = dZO;
795}
double GetCompassHeading() const
Accessor for the Compass Heading private member.
Definition GeospatialOperations.hpp:787
const geoops::UTMCoordinate & GetUTMCoordinate() const
Accessor for the geoops::UTMCoordinate member variable.
Definition GeospatialOperations.hpp:767
Here is the call graph for this function:

◆ GetCameraIsOpen()

bool SIMZEDCam::GetCameraIsOpen ( )
overridevirtual

Accessor for the camera open status.

Returns
true - The camera has been successfully opened.
false - The camera has not been successfully opened.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-09-30

Implements Camera< cv::Mat >.

807{
808 return m_pRGBStream->GetIsConnected() && m_pDepthImageStream->GetIsConnected() && this->GetThreadState() == AutonomyThreadState::eRunning;
809}
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 SIMZEDCam::GetUsingGPUMem ( ) const
overridevirtual

Returns if the camera is using GPU memory. This is a simulation camera, so this method will always return false.

Returns
true - We are using GPU memory.
false - We are not using GPU memory.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-12-26

Reimplemented from ZEDCamera.

822{
823 return false;
824}

◆ GetCameraModel()

std::string SIMZEDCam::GetCameraModel ( )
overridevirtual

Accessor for the name of this model of camera.

Returns
std::string - The model of the camera.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-12-26

Implements ZEDCamera.

835{
836 return "SIMZED2i";
837}

◆ GetPositionalTrackingEnabled()

bool SIMZEDCam::GetPositionalTrackingEnabled ( )
overridevirtual

Accessor for the if the camera's positional tracking is enabled. Since this is a simulation camera, this method will just return the member variable.

Returns
true - Positional tracking is enabled.
false - Positional tracking is disabled.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-12-26

Implements ZEDCamera.

850{
851 return m_bCameraPositionalTrackingEnabled && this->GetCameraIsOpen();
852}
bool GetCameraIsOpen() override
Accessor for the camera open status.
Definition SIMZEDCam.cpp:806
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ThreadedContinuousCode()

void SIMZEDCam::ThreadedContinuousCode ( )
overrideprivatevirtual

The code inside this private method runs in a separate thread, but still has access to this*. This method continuously get new frames from the OpenCV VideoCapture object and stores it in a member variable. 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-30

Implements AutonomyThread< void >.

297{
298 // Acquire a lock on the rover pose mutex.
299 std::unique_lock<std::shared_mutex> lkRoverPoseLock(m_muCurrentRoverPoseMutex);
300 // Check if the NavBoard pointer is valid.
301 if (globals::g_pNavigationBoard != nullptr)
302 {
303 // Get the current rover pose from the NavBoard.
304 m_stCurrentRoverPose = geoops::RoverPose(globals::g_pNavigationBoard->GetGPSData(), globals::g_pNavigationBoard->GetHeading());
305 }
306 // Release lock.
307 lkRoverPoseLock.unlock();
308
309 // Check if the depth image WebRTC connection is open.
310 if (m_pDepthImageStream != nullptr && m_pDepthImageStream->GetIsConnected())
311 {
312 // Acquire a lock on the WebRTC mutex.
313 std::shared_lock<std::shared_mutex> lkWebRTC2(m_muWebRTCDepthImageCopyMutex);
314 // Estimate the depth measure from the depth image.
315 this->EstimateDepthMeasure(m_cvDepthImage, m_cvDepthMeasure);
316 // Check if the depth image is empty.
317 if (m_cvDepthImage.empty())
318 {
319 // Release lock.
320 lkWebRTC2.unlock();
321 return;
322 }
323 // Release lock.
324 lkWebRTC2.unlock();
325
326 // Calculate the point cloud from the estimated depth measure.
327 this->CalculatePointCloud(m_cvDepthMeasure, m_cvPointCloud);
328 }
329
330 // Acquire a shared_lock on the frame copy queue.
331 std::shared_lock<std::shared_mutex> lkSchedulers(m_muPoolScheduleMutex);
332 // Check if the frame copy queue is empty.
333 if (!m_qFrameCopySchedule.empty() || !m_qPoseCopySchedule.empty() || !m_qSensorsCopySchedule.empty())
334 {
335 // Add the length of all queues together to determine the number of tasks to create.
336 size_t siTotalQueueLength = m_qFrameCopySchedule.size() + m_qPoseCopySchedule.size() + m_qSensorsCopySchedule.size();
337
338 // Acquire shared lock on the WebRTC mutex, so that the WebRTC connection doesn't try to write to the Mats while they are being copied in the thread pool.
339 std::shared_lock<std::shared_mutex> lkWebRTC(m_muWebRTCRGBImageCopyMutex);
340 std::shared_lock<std::shared_mutex> lkWebRTC2(m_muWebRTCDepthImageCopyMutex);
341
342 // Start the thread pool to store multiple copies of the sl::Mat into the given cv::Mats.
343 this->RunDetachedPool(siTotalQueueLength, m_nNumFrameRetrievalThreads);
344
345 // Get current time.
346 std::chrono::_V2::system_clock::duration tmCurrentTime = std::chrono::high_resolution_clock::now().time_since_epoch();
347 // Only reset once every couple seconds.
348 if (std::chrono::duration_cast<std::chrono::seconds>(tmCurrentTime).count() % 31 == 0 && !m_bQueueTogglesAlreadyReset)
349 {
350 // Reset queue counters.
351 m_bPosesQueued.store(false, ATOMIC_MEMORY_ORDER_METHOD);
352 m_bSensorsQueued.store(false, ATOMIC_MEMORY_ORDER_METHOD);
353
354 // Set reset toggle.
355 m_bQueueTogglesAlreadyReset = true;
356 }
357 // Crucial for toggle action. If time is not evenly devisable and toggles have previously been set, reset queue reset boolean.
358 else if (m_bQueueTogglesAlreadyReset)
359 {
360 // Reset reset toggle.
361 m_bQueueTogglesAlreadyReset = false;
362 }
363
364 // Wait for thread pool to finish.
365 this->JoinPool();
366
367 // Release lock on WebRTC mutex.
368 lkWebRTC.unlock();
369 lkWebRTC2.unlock();
370 }
371
372 // Release lock on frame copy queue.
373 lkSchedulers.unlock();
374}
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
void CalculatePointCloud(const cv::Mat &cvDepthMeasure, cv::Mat &cvPointCloud)
This method calculates a point cloud from the decoded depth measure use some simple trig and the came...
Definition SIMZEDCam.cpp:244
void EstimateDepthMeasure(const cv::Mat &cvDepthImage, cv::Mat &cvDepthMeasure)
This method estimates the depth measure from the depth image.
Definition SIMZEDCam.cpp:197
bool empty() const
This struct is used by the WaypointHandler to provide an easy way to store all pose data about the ro...
Definition GeospatialOperations.hpp:708
Here is the call graph for this function:

◆ PooledLinearCode()

void SIMZEDCam::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 vector queued up by the Grab methods.

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

Implements AutonomyThread< void >.

387{
389 // Frame queue.
391
392 // Acquire mutex for getting frames out of the queue.
393 std::unique_lock<std::shared_mutex> lkFrameQueue(m_muFrameCopyMutex);
394 // Check if the queue is empty.
395 if (!m_qFrameCopySchedule.empty())
396 {
397 // Get frame container out of queue.
398 containers::FrameFetchContainer<cv::Mat> stContainer = m_qFrameCopySchedule.front();
399 // Pop out of queue.
400 m_qFrameCopySchedule.pop();
401 // Release lock.
402 lkFrameQueue.unlock();
403
404 // Determine which frame should be copied.
405 switch (stContainer.eFrameType)
406 {
407 case PIXEL_FORMATS::eBGRA: *(stContainer.pFrame) = m_cvFrame.clone(); break;
408 case PIXEL_FORMATS::eDepthImage: *(stContainer.pFrame) = m_cvDepthImage.clone(); break;
409 case PIXEL_FORMATS::eDepthMeasure: *(stContainer.pFrame) = m_cvDepthMeasure.clone(); break;
410 case PIXEL_FORMATS::eXYZ: *(stContainer.pFrame) = m_cvPointCloud.clone(); break;
411 default: *(stContainer.pFrame) = m_cvFrame.clone(); break;
412 }
413
414 // Signal future that the frame has been successfully retrieved.
415 stContainer.pCopiedFrameStatus->set_value(true);
416 }
417
419 // Pose queue.
421 // Acquire mutex for getting data out of the pose queue.
422 std::unique_lock<std::shared_mutex> lkPoseQueue(m_muPoseCopyMutex);
423 // Check if the queue is empty.
424 if (!m_qPoseCopySchedule.empty())
425 {
426 // Get pose container out of queue.
427 containers::DataFetchContainer<Pose> stContainer = m_qPoseCopySchedule.front();
428 // Pop out of queue.
429 m_qPoseCopySchedule.pop();
430 // Release lock.
431 lkPoseQueue.unlock();
432
433 // Get angle realignments.
434 double dNewYO = numops::InputAngleModulus<double>(m_stCurrentRoverPose.GetCompassHeading() + m_dPoseOffsetYO, 0.0, 360.0);
435 // Repack values into pose.
436 Pose stPose(m_stCurrentRoverPose.GetUTMCoordinate().dEasting + m_dPoseOffsetX,
437 m_stCurrentRoverPose.GetUTMCoordinate().dAltitude + m_dPoseOffsetY,
438 m_stCurrentRoverPose.GetUTMCoordinate().dNorthing + m_dPoseOffsetZ,
439 m_dPoseOffsetXO,
440 dNewYO,
441 m_dPoseOffsetZO);
442
443 // 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.
444 // // Check ZED coordinate system.
445 // switch (m_slCameraParams.coordinate_system)
446 // {
447 // case sl::COORDINATE_SYSTEM::LEFT_HANDED_Y_UP:
448 // {
449 // // Realign based in the signedness of this coordinate system. Z is backwards.
450 // stPose.stTranslation.dZ *= -1;
451 // break;
452 // }
453 // default:
454 // {
455 // // No need to flip signs for other coordinate systems.
456 // break;
457 // }
458 // }
459
460 // Copy pose.
461 *(stContainer.pData) = stPose;
462
463 // Signal future that the data has been successfully retrieved.
464 stContainer.pCopiedDataStatus->set_value(true);
465 }
466 else
467 {
468 // Release lock.
469 lkPoseQueue.unlock();
470 }
471
473 // Sensors queue.
475 // Acquire mutex for getting data out of the sensors queue.
476 std::unique_lock<std::shared_mutex> lkSensorsQueue(m_muSensorsCopyMutex);
477 // Check if the queue is empty.
478 if (!m_qSensorsCopySchedule.empty())
479 {
480 // Get pose container out of queue.
481 containers::DataFetchContainer<sl::SensorsData> stContainer = m_qSensorsCopySchedule.front();
482 // Pop out of queue.
483 m_qSensorsCopySchedule.pop();
484 // Release lock.
485 lkSensorsQueue.unlock();
486
487 // Copy pose.
488 *(stContainer.pData) = m_stIMUData;
489
490 // Signal future that the data has been successfully retrieved.
491 stContainer.pCopiedDataStatus->set_value(true);
492 }
493 else
494 {
495 // Release lock.
496 lkSensorsQueue.unlock();
497 }
498}
CV_NODISCARD_STD Mat clone() const
Here is the call graph for this function:

◆ SetCallbacks()

void SIMZEDCam::SetCallbacks ( )
private

This method sets the callbacks for the WebRTC connections.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-12-26
158{
159 // Set the frame callbacks.
160 m_pRGBStream->SetOnFrameReceivedCallback(
161 [this](cv::Mat& cvFrame)
162 {
163 // Check if the frame is empty.
164 if (!cvFrame.empty())
165 {
166 // Acquire a lock on the webRTC copy mutex.
167 std::unique_lock<std::shared_mutex> lkWebRTC(m_muWebRTCRGBImageCopyMutex);
168 // Deep copy the frame.
169 m_cvFrame = cvFrame.clone();
170 }
171 });
172 m_pDepthImageStream->SetOnFrameReceivedCallback(
173 [this](cv::Mat& cvFrame)
174 {
175 // Check if the frame is empty.
176 if (!cvFrame.empty())
177 {
178 // Acquire a lock on the webRTC copy mutex.
179 std::unique_lock<std::shared_mutex> lkWebRTC(m_muWebRTCDepthImageCopyMutex);
180 // Deep copy the frame to the depth image buffer.
181 m_cvDepthImageBuffer = cvFrame.clone();
182 // Convert the depth image buffer to grayscale.
183 cv::cvtColor(m_cvDepthImageBuffer, m_cvDepthImage, cv::COLOR_BGR2GRAY);
184 }
185 });
186}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ EstimateDepthMeasure()

void SIMZEDCam::EstimateDepthMeasure ( const cv::Mat cvDepthImage,
cv::Mat cvDepthMeasure 
)
private

This method estimates the depth measure from the depth image.

Parameters
cvDepthImage- The depth image to estimate the depth measure from.
cvDepthMeasure- The estimated depth measure that will be written to.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-04-29
198{
199 // Declare instance variables.
200 const float fMaxDepth = 2001.0f; // Maximum depth in cm.
201
202 // Check if the depth image is empty.
203 if (cvDepthImage.empty())
204 {
205 // If the depth image is empty, fill the depth measure with zeros.
206 cvDepthMeasure = cv::Mat::zeros(cvDepthMeasure.size(), CV_32FC1);
207 return;
208 }
209
210// TEST: Even though this speeds up the code, it might be too much CPU work as the codebase grows. Use a GpuMat instead.
211#pragma omp parallel for collapse(2)
212
213 // Iterate over each pixel in the cvDepthImage image.
214 for (int nY = 0; nY < cvDepthImage.rows; ++nY)
215 {
216 for (int nX = 0; nX < cvDepthImage.cols; ++nX)
217 {
218 // For this, we are just using the depth image to estimate the depth measure. We will treat 255 as 0 cm and 0 as fMaxDepth - 1 cm.
219 // Get the depth value from the depth image.
220 uchar ucDepthValue = cvDepthImage.at<uchar>(nY, nX);
221
222 // Calculate the depth in cm.
223 float fDepth = (1.0f - (ucDepthValue / 255.0f)) * fMaxDepth;
224 // Check if nY and nX are within the bounds of the depth measure image.
225 if (nY < cvDepthMeasure.rows && nX < cvDepthMeasure.cols)
226 {
227 // Store the estimated depth in the new cv::Mat. Convert cm to m.
228 cvDepthMeasure.at<float>(nY, nX) = fDepth / 100.0f; // Convert cm to m.
229 }
230 }
231 }
232}
MatSize size
_Tp & at(int i0=0)
unsigned char uchar
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CalculatePointCloud()

void SIMZEDCam::CalculatePointCloud ( const cv::Mat cvDepthMeasure,
cv::Mat cvPointCloud 
)
private

This method calculates a point cloud from the decoded depth measure use some simple trig and the camera FOV.

Parameters
cvDepthMeasure- The decoded depth measure.
cvPointCloud- The point cloud that will be written to.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-01-04
245{
246 // Calculate focal lengths from FOV.
247 const double dRadPerDeg = M_PI / 180.0;
248 const double dFx = (cvDepthMeasure.cols / 2.0) / tan(m_dPropHorizontalFOV * dRadPerDeg / 2.0);
249 const double dFy = (cvDepthMeasure.rows / 2.0) / tan(m_dPropVerticalFOV * dRadPerDeg / 2.0);
250 // Image center.
251 const double dCx = cvDepthMeasure.cols / 2.0;
252 const double dCy = cvDepthMeasure.rows / 2.0;
253
254// TEST: Even though this speeds up the code, it might be too much CPU work as the codebase grows. Use a GpuMat instead.
255// This is a parallel for loop that calculates the point cloud from the decoded depth measure.
256#pragma omp parallel for collapse(2)
257
258 // Iterate over each pixel in the cvDepthMeasure image.
259 for (int nY = 0; nY < cvDepthMeasure.rows; ++nY)
260 {
261 for (int nX = 0; nX < cvDepthMeasure.cols; ++nX)
262 {
263 // Get depth value.
264 float fDepth = cvDepthMeasure.at<float>(nY, nX);
265
266 // Skip invalid depth values.
267 if (fDepth <= 0)
268 {
269 cvPointCloud.at<cv::Vec4f>(nY, nX) = cv::Vec4f(0, 0, 0, 0);
270 continue;
271 }
272
273 // Convert from pixel coordinates to 3D coordinates.
274 float fX = static_cast<float>((nX - dCx) * fDepth / dFx);
275 float fY = static_cast<float>((dCy - nY) * fDepth / dFy);
276 float fZ = fDepth;
277
278 // Store point. (XYZ + intensity, using Y channel for intensity)
279 cvPointCloud.at<cv::Vec4f>(nY, nX) = cv::Vec4f(fX, fY, fZ, 255);
280 }
281 }
282}
__device__ __forceinline__ float3 tan(const uchar3 &a)
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ ProcessIMUData

const std::function<void(const rovecomm::RoveCommPacket<double>&, const sockaddr_in&)> SIMZEDCam::ProcessIMUData
private

Callback function to process incoming IMU data from RoveComm for the SIM ZED Camera. Normally, this data would come from the physical ZED camera's IMU over USB,.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2025-11-19
98 {
99 // Not using this.
100 (void) stdAddr;
101
102 // Acquire a write lock on the sensors mutex.
103 std::unique_lock<std::shared_mutex> lkSensorsProcessLock(m_muSensorsCopyMutex);
104 // Update IMU data.
105 m_stIMUData.imu.linear_acceleration.x = static_cast<float>(stPacket.vData[0]);
106 m_stIMUData.imu.linear_acceleration.y = static_cast<float>(stPacket.vData[1]);
107 m_stIMUData.imu.linear_acceleration.z = static_cast<float>(stPacket.vData[2]);
108 m_stIMUData.imu.angular_velocity.x = static_cast<float>(stPacket.vData[3]);
109 m_stIMUData.imu.angular_velocity.y = static_cast<float>(stPacket.vData[4]);
110 m_stIMUData.imu.angular_velocity.z = static_cast<float>(stPacket.vData[5]);
111
112 // Manually calculate the Gyro pose using the Tait-Bryan angles (ZYX convention) and the quaternion representation.
113 // This is because the SIM does not provide orientation data from the IMU, only angular velocity.
114 double dQx = stPacket.vData[6];
115 double dQy = stPacket.vData[7];
116 double dQz = stPacket.vData[8];
117 double dQw = stPacket.vData[9];
118 double dRoll = std::atan2(2.0 * (dQw * dQx + dQy * dQz), 1.0 - 2.0 * (dQx * dQx + dQy * dQy));
119 double dPitch = std::asin(2.0 * (dQw * dQy - dQz * dQx));
120 double dYaw = std::atan2(2.0 * (dQw * dQz + dQx * dQy), 1.0 - 2.0 * (dQy * dQy + dQz * dQz));
121 // Pack the gyro values into a sl::Transform.
122 sl::float3 slEulerAngles(static_cast<float>(dRoll), static_cast<float>(dPitch), static_cast<float>(dYaw));
123 sl::Transform slIMUTransform;
124 slIMUTransform.setEulerAngles(slEulerAngles);
125 m_stIMUData.imu.pose = slIMUTransform;
126
127 // Unlock mutex.
128 lkSensorsProcessLock.unlock();
129
130 // Submit logger message.
131 LOG_DEBUG(logging::g_qSharedLogger,
132 "Incoming IMU data processed from RoveComm for SIM ZED Camera: (AccelX {}, AccelY {}, AccelZ {}, GyroX {}, GyroY {}, GyroZ {})",
133 stPacket.vData[0],
134 stPacket.vData[1],
135 stPacket.vData[2],
136 stPacket.vData[3],
137 stPacket.vData[4],
138 stPacket.vData[5]);
139 };

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