GrabBag/Device/RsLidarDevice/_Inc/RsLidarDevice.h
2026-05-17 18:59:44 +08:00

125 lines
4.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef CRSLIDARDEVICE_H
#define CRSLIDARDEVICE_H
#include "IRsLidarDevice.h"
// SDK 内部以 uint8_t* 调用 recvfrom(),但 C++ 中 char*/unsigned char*/signed char*
// 是三种独立类型MSVC 拒绝 uint8_t*(=unsigned char*) → char* 的隐式转换。
// 此重载在 SDK 头文件之前定义,利用重载决议的精确匹配规则拦截调用并内部转型。
#ifdef _WIN32
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
inline int recvfrom(SOCKET s, unsigned char* buf, int len, int flags, sockaddr* from, int* fromlen)
{
return ::recvfrom(s, reinterpret_cast<char*>(buf), len, flags, from, fromlen);
}
#endif
// SDK 依赖 std::array / int16_t / uint16_t但其内部缺少对应的 #include
// 在 Linux 上通过 libstdc++ 间接包含可用MSVC STL 不会间接拉入,需在此处显式引入。
#include <array>
#include <cstdint>
// SDK 头文件全部放在私有层,不污染公共接口
#include <rs_driver/api/lidar_driver.hpp>
#include <rs_driver/msg/point_cloud_msg.hpp>
#include <rs_driver/msg/packet.hpp>
#include <rs_driver/driver/driver_param.hpp>
#include <rs_driver/common/error_code.hpp>
#include <rs_driver/utility/sync_queue.hpp>
#include <thread>
#include <atomic>
#include <mutex>
#include <array>
#include <chrono>
using namespace robosense::lidar;
class CRsLidarDevice : public IRsLidarDevice
{
public:
CRsLidarDevice();
~CRsLidarDevice();
int InitDevice() override;
int OpenDevice(const RsLidarConfig& config) override;
int CloseDevice() override;
bool IsOpened() const override;
int Start() override;
int Stop() override;
bool IsRunning() const override;
int SetPointCloudCallback(PointCloudCallback callback) override;
int SetRawCloudCallback(RawCloudCallback callback) override;
int SetPacketCallback(PacketCallback callback) override;
int SetExceptionCallback(ExceptionCallback callback) override;
std::string GetVersion() override;
uint64_t GetDroppedFrameCount() const override;
size_t GetStuffedQueueDepth() const override;
uint64_t GetExceptionCount(int errCode) const override;
RsCallbackStats GetCallbackLatencyStats() const override;
size_t GetStuffedQueuePeak() const override;
private:
// SDK 内部类型别名
using SdkCloudMsg = PointCloudT<PointXYZI>;
using SdkCloudPtr = std::shared_ptr<SdkCloudMsg>;
void processCloudThread();
/// 输出 5s 窗口诊断日志并重置窗口字段;仅当距 lastLogTime ≥5s 时实际输出
void emitDiagnosticLogIfDue(std::chrono::steady_clock::time_point& lastLogTime);
SdkCloudPtr getFreeCloud();
void putStuffedCloud(SdkCloudPtr msg);
/// 将 SDK Packet 转为 RsPacketInfo 后转发给用户
void onPacket(const Packet& pkt);
/// 将 SDK Error 转为 RsExceptionInfo 后转发给用户
void onException(const Error& code);
/// RsLidarConfig → RSDriverParam
static RSDriverParam toDriverParam(const RsLidarConfig& config);
bool m_bOpened = false;
std::atomic<bool> m_bRunning{false};
std::atomic<bool> m_bStopProcess{false};
PointCloudCallback m_pointCloudCallback;
RawCloudCallback m_rawCloudCallback;
PacketCallback m_packetCallback;
ExceptionCallback m_exceptionCallback;
std::mutex m_callbackMutex;
std::unique_ptr<LidarDriver<SdkCloudMsg>> m_pDriver;
std::thread m_processThread;
SyncQueue<SdkCloudPtr, 4096> m_freeQueue;
SyncQueue<SdkCloudPtr, 4096> m_stuffedQueue;
RSDriverParam m_param;
// 丢帧监控
std::atomic<uint64_t> m_droppedFrameCount{0};
std::atomic<uint64_t> m_totalPushCount{0};
// 诊断统计(每 5s 滚动窗口)
// bucket: 0=MSOPTIMEOUT(0x40) 1=PKTBUFOVERFLOW(0x48) 2=CLOUDOVERFLOW(0x49) 3=WRONGMSOPLEN(0x42) 4=other
static constexpr size_t EXC_BUCKET_COUNT = 5;
std::array<std::atomic<uint64_t>, EXC_BUCKET_COUNT> m_exceptionCounts{};
std::atomic<uint64_t> m_cbMaxUs{0};
std::atomic<uint64_t> m_cbAccumUs{0};
std::atomic<uint64_t> m_cbCount{0};
std::atomic<size_t> m_qPeak{0};
/// 将 SDK ErrCode 映射到统计桶下标,未知返回 4 (other)
static size_t errCodeToBucket(int errCode);
};
#endif // CRSLIDARDEVICE_H