oh_my_loam/common/visualizer/lidar_visualizer.h

164 lines
4.4 KiB
C
Raw Normal View History

2020-10-12 21:09:32 +08:00
#pragma once
#include <atomic>
#include <deque>
#include <mutex>
#include <thread>
2020-10-13 01:07:59 +08:00
2021-01-05 14:33:42 +08:00
#include "common/macro/macros.h"
2021-01-04 21:26:09 +08:00
#include "lidar_visualizer_utils.h"
2020-10-12 21:09:32 +08:00
2021-01-04 21:26:09 +08:00
namespace common {
2020-10-12 21:09:32 +08:00
2021-01-04 21:26:09 +08:00
struct LidarVisFrame {
double timestamp = 0.0;
2021-01-14 00:34:13 +08:00
PointCloudConstPtr cloud = nullptr;
2020-10-12 21:09:32 +08:00
};
2021-01-04 21:26:09 +08:00
class LidarVisualizer {
2020-10-12 21:09:32 +08:00
public:
2021-01-04 21:26:09 +08:00
explicit LidarVisualizer(const std::string &name,
size_t max_history_size = 10)
2020-10-12 21:09:32 +08:00
: name_(name), max_history_size_(max_history_size) {
thread_.reset(new std::thread([&]() {
viewer_.reset(new PCLVisualizer(name_));
2021-01-04 21:26:09 +08:00
// Set background color: black
viewer_->setBackgroundColor(0, 0, 0);
// Set camera position
2020-10-12 21:09:32 +08:00
viewer_->setCameraPosition(0, 0, 200, 0, 0, 0, 1, 0, 0, 0);
viewer_->setSize(2500, 1500);
viewer_->addCoordinateSystem(1.0);
2021-01-04 21:26:09 +08:00
// Register keyboard callback
2020-10-12 21:09:32 +08:00
viewer_->registerKeyboardCallback(
[&](const pcl::visualization::KeyboardEvent &event) -> void {
KeyboardEventCallback(event);
});
Run();
}));
}
2021-01-04 21:26:09 +08:00
virtual ~LidarVisualizer() {
2020-10-12 21:09:32 +08:00
is_stopped_ = true;
viewer_->close();
if (thread_->joinable()) {
thread_->join();
}
}
2021-01-04 21:26:09 +08:00
void Render(const std::shared_ptr<LidarVisFrame> &frame) {
2020-10-12 21:09:32 +08:00
std::lock_guard<std::mutex> lock(mutex_);
while (history_frames_.size() > max_history_size_) {
history_frames_.pop_back();
}
history_frames_.emplace_front(frame);
curr_frame_iter_ = history_frames_.begin();
is_updated_ = true;
}
2021-01-22 16:33:55 +08:00
std::string name() const {
return name_;
}
2020-10-12 21:09:32 +08:00
protected:
void Run() {
while (!is_stopped_) {
if (is_updated_) {
RemoveRenderedObjects();
Draw();
is_updated_ = false;
}
viewer_->spinOnce(20); // ms
}
}
/**
2021-01-04 21:26:09 +08:00
* @brief Draw objects. This method should be overrided for customization
2020-10-12 21:09:32 +08:00
*/
2021-01-04 21:26:09 +08:00
virtual void Draw() {
auto frame = GetCurrentFrame<LidarVisFrame>();
2021-01-05 02:09:40 +08:00
DrawPointCloud<Point>(frame.cloud, WHITE, "point cloud");
2021-01-04 21:26:09 +08:00
}
2020-10-12 21:09:32 +08:00
/**
* @brief Keyboard event callback function, This method should be overrided
* for customization
*
* @param event Keyboard event
*/
virtual void KeyboardEventCallback(
const pcl::visualization::KeyboardEvent &event) {
if (event.getKeySym() == "p" && event.keyDown()) {
std::lock_guard<std::mutex> lock(mutex_);
++curr_frame_iter_;
if (curr_frame_iter_ == history_frames_.end()) {
--curr_frame_iter_;
}
is_updated_ = true;
} else if (event.getKeySym() == "n" && event.keyDown()) {
std::lock_guard<std::mutex> lock(mutex_);
if (curr_frame_iter_ != history_frames_.begin()) {
--curr_frame_iter_;
}
is_updated_ = true;
} else if (event.getKeySym() == "r" && event.keyDown()) {
viewer_->setCameraPosition(0, 0, 200, 0, 0, 0, 1, 0, 0, 0);
viewer_->setSize(2500, 1500);
is_updated_ = true;
}
}
void RemoveRenderedObjects() {
viewer_->removeAllPointClouds();
2020-10-12 21:09:32 +08:00
viewer_->removeAllShapes();
}
2020-10-27 20:13:19 +08:00
template <typename FrameT>
2020-10-12 21:09:32 +08:00
FrameT GetCurrentFrame() const {
std::lock_guard<std::mutex> lock(mutex_);
2020-10-27 20:13:19 +08:00
return *static_cast<FrameT *>((*curr_frame_iter_).get());
2020-10-12 21:09:32 +08:00
}
2020-12-31 20:59:08 +08:00
template <typename PointType>
void DrawPointCloud(
const typename pcl::PointCloud<PointType>::ConstPtr &cloud,
const Color &color, const std::string &id, int point_size = 3) {
AddPointCloud<PointType>(cloud, color, id, viewer_.get(), point_size);
}
template <typename PointType>
void DrawPointCloud(
const typename pcl::PointCloud<PointType>::ConstPtr &cloud,
const std::string &field, const std::string &id, int point_size = 3) {
AddPointCloud<PointType>(cloud, field, id, viewer_.get(), point_size);
}
2020-10-12 21:09:32 +08:00
// visualizer name
std::string name_;
size_t max_history_size_;
// atomic bool variable
std::atomic_bool is_stopped_{false};
// mutex for visualizer_frame.
mutable std::mutex mutex_;
// bool flag indicates whether the Visualizer frame is updated.
std::atomic_bool is_updated_{false};
// The visualizer frame list
2021-01-04 21:26:09 +08:00
std::deque<std::shared_ptr<LidarVisFrame>> history_frames_;
2020-10-12 21:09:32 +08:00
// The current displayed frame iter.
2021-01-04 21:26:09 +08:00
typename std::deque<std::shared_ptr<LidarVisFrame>>::iterator
curr_frame_iter_;
2020-10-12 21:09:32 +08:00
// thread for visualization
std::unique_ptr<std::thread> thread_ = nullptr;
// viewer
std::unique_ptr<PCLVisualizer> viewer_ = nullptr;
2021-01-05 14:33:42 +08:00
DISALLOW_COPY_AND_ASSIGN(LidarVisualizer);
2020-10-12 21:09:32 +08:00
};
2021-01-04 21:26:09 +08:00
} // namespace common