diff --git a/README.md b/README.md
index 5f1767b..665a3b3 100644
--- a/README.md
+++ b/README.md
@@ -9,16 +9,23 @@
#### 安装教程
-1. xxxx
-2. xxxx
+1. chmod +x build.sh
+2. ./build.sh
3. xxxx
#### 使用说明
+<<<<<<< Updated upstream
在最外层目录 catkin_make
可能需要 source ./devel/setup.bash
1. roslaunch librviz_tutorial laser.launch
2. xxxx
+=======
+在工作目录下(src上一层)
+记得source(可能需要)
+1. source ./devel/setup.bash
+2. roslaunch point_visual laser.launch
+>>>>>>> Stashed changes
3. xxxx
#### 参与贡献
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..5a8e36b
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# 创建工作目录
+mkdir ~/PointVisual
+
+cd ..
+#将当前src移动到PointVisual
+cp -r src ~/PointVisual
+
+# 切换到工作目录
+cd ~/PointVisual
+
+# 在工作目录make
+catkin_make
+
+if [ $? -eq 0 ]; then
+
+# 执行source命令
+ source ./devel/setup.bash
+
+# 运行其他命令
+# roslaunch point_visual laser.launch
+ roscore &
+ sleep 2
+ rosrun point_visual myviz
+else
+ exit 1
+fi
diff --git a/librviz_tutorial/launch/laser.launch b/librviz_tutorial/launch/laser.launch
deleted file mode 100644
index 0a19978..0000000
--- a/librviz_tutorial/launch/laser.launch
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/librviz_tutorial/src/myviz.cpp b/librviz_tutorial/src/myviz.cpp
deleted file mode 100755
index 547cc8a..0000000
--- a/librviz_tutorial/src/myviz.cpp
+++ /dev/null
@@ -1,1105 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-#include "rviz/properties/property_tree_widget.h"
-#include "rviz/selection/selection_manager.h"
-#include "rviz/panel.h"
-
-#include "rviz/visualization_manager.h"
-#include"rviz/tool_manager.h"
-#include "rviz/render_panel.h"
-#include "rviz/display.h"
-
-#include "myviz.h"
-#include "../tools/color.h"
-#include "qthread.h"
-// BEGIN_TUTORIAL
-// Constructor for MyViz. This does most of the work of the class.
-MyViz::MyViz( QWidget* parent)
- : QWidget( parent )
-{
-
- nh=ros::NodeHandle("~");
- sub=nh.subscribe("/test",1000,&MyViz::subCallback,this);
- pub=nh.advertise("/test_pub",1000);
- pub_thread=std::thread(&MyViz::pubThread,this);
-
- // 全局变量存放处
- // 颜色名称,可添加,待设置rgb类型设置颜色
- color_name = {
- "white","red","green","black","blue","yellow",
- "pink","purple","skyblue","lightgreen","orange",
- };
- // 颜色路径名
- color_icon_filename = QString("../Rviz/librviz_ws/src/librviz_tutorial/sources/images/%1.png");
- speed_name = {"2.0","1.5","1.25","1.0","0.75","0.5",};
- duration = 0;
- isclicked = true;
- ispauseclick = true;
- sliderreleased = false;
- playagain = false;
- isthreadplaying = false;
- abs = false;
- stored = false;
-
- dlg = new LoginDialog(this);
- landed = 0;
- cur_fixed_frame = "world";
-
- // 网格结构
- QGridLayout* controls_layout = new QGridLayout();
- int ctl_index = 0;
-
- // 登录按钮
- QPushButton* login_button = new QPushButton("登录");
- QPushButton* quit_login_button = new QPushButton("退出");
-
- //select按钮
- QPushButton* selection_button = new QPushButton("选择坐标点");
- QPushButton* move_camera_button = new QPushButton("移动");
-
- controls_layout->addWidget( login_button, ctl_index, 0);
- controls_layout->addWidget( quit_login_button, ctl_index++, 1);
-
-
- // offline 布局
- // QPushButton setting!////////////////////////////////////////////////////////////////////////////////////////////////
- QPushButton* play = new QPushButton("播放", this);
- QPushButton* pause = new QPushButton("暂停", this);
- QPushButton* but_save = new QPushButton("保存一帧", this);// buttonn: save one frame
- QPushButton* but_saveMul = new QPushButton("保存多帧", this);// button: save multiple frames
- QPushButton* but_file = new QPushButton("打开文件", this);// button: select file
-
- // QLabel setting!/////////////////////////////////////////////////////////////////////////////////////////////////////
- QLabel* label_speed = new QLabel("播放速度:");//speed combobox
- QLabel* label_split = new QLabel("");//speed combobox
-
- // QSlider setting!////////////////////////////////////////////////////////////////////////////////////////////////////
- progress = new QSlider(Qt::Horizontal);
- // QComboBox setting!//////////////////////////////////////////////////////////////////////////////////////////////////
- QComboBox * speed_combobox = new QComboBox();
- //enable button////////////////////////////////////////////////////////////////////////////////////////////////////////
- play->setEnabled(true);
- pause->setEnabled(true);
- but_save->setEnabled(true);
- but_saveMul->setEnabled(true);
- but_file->setEnabled(false);
-
- // setting button size!////////////////////////////////////////////////////////////////////////////////////////////////
- play->setFixedSize(120, 30);
- pause->setFixedSize(120, 30);
- but_save->setFixedSize(120, 30);
- but_saveMul->setFixedSize(120, 30);
- but_file->setFixedSize(120, 30);
-
- for(int i = 0; i < speed_name.size(); i++)
- speed_combobox->addItem(speed_name[i] + "x");
- speed_combobox->setCurrentIndex(3);
-
- controls_layout->addWidget( label_split, ctl_index++, 0 );
- controls_layout->addWidget( but_file, ctl_index, 0 );
- controls_layout->addWidget( but_save, ctl_index++, 1 );
- controls_layout->addWidget( but_saveMul, ctl_index++, 0 );
-
- controls_layout->addWidget( move_camera_button, ctl_index, 0);
- controls_layout->addWidget( selection_button, ctl_index++ ,1);
-
- controls_layout->addWidget(label_speed,ctl_index,0);
- controls_layout->addWidget(speed_combobox,ctl_index++,1);
-
- controls_layout->addWidget( play, ctl_index, 0 );
- controls_layout->addWidget( pause, ctl_index++, 1 );
- controls_layout->addWidget(progress,ctl_index++,0, 1, 2); // addwidget(widget,row,col,m,n);//m是占几行,n是占几列,
-
- controls_layout->setSpacing(5);
-
- // 是否选择显示坐标轴
- QLabel* label_axes = new QLabel("参考坐标系:");
- QCheckBox *axes_checkbox = new QCheckBox("", this);
- // QComboBox * axesBox = new QComboBox();
- // axesBox->addItem("不显示");
- // axesBox->addItem("显示");
-
- // 选择圆圈范围
- QLabel* label_circle = new QLabel("参考圆(m): ");
- QLineEdit* circleLineEdit = new QLineEdit();
- circleLineEdit->setPlaceholderText("请输入数字");
- circleLineEdit->setFixedWidth(120);
-
- controls_layout->addWidget(label_axes, ctl_index,0);
- controls_layout->addWidget(axes_checkbox, ctl_index++,1);
- controls_layout->addWidget(label_circle, ctl_index,0);
- controls_layout->addWidget(circleLineEdit, ctl_index++,1);
-
- // 第二个layout
- //QGridLayout* display_layout = new QGridLayout();
- //int display_index = 0;
-
- // Tree 全局变量存放地方
- Tree_Display(controls_layout, ctl_index++);
-
-
- // 待解锁子组件设置父组件,方便寻找,登陆后解锁可编辑属性
- login_button->setObjectName("login_button");
- login_button->setParent(this);
- quit_login_button->setObjectName("quit_login_button");
- quit_login_button->setParent(this);
- quit_login_button->setEnabled(false);
-
-
- but_file->setObjectName("open_file");
- but_file->setParent(this);
- progress->setObjectName("bag_progress");
- progress->setParent(this);
- progress->setEnabled(false);
-
- // controls_layout->setRowStretch(3, 0);
- // Make signal/slot connections. 进行信号/插槽连接
-
- // 增加登录按钮
- connect(login_button, SIGNAL(clicked()), this, SLOT(login_button_clicked()));
- // 增加退出按钮
- connect(quit_login_button, SIGNAL(clicked()), this, SLOT(quit_login_button_clicked()));
-
- // 增加切换select
- connect(selection_button, SIGNAL(clicked()), this, SLOT( slot_select()));
- connect(move_camera_button, SIGNAL(clicked()), this, SLOT( slot_move_camera()));
-
- // 增加坐标变换
- // connect(axesBox, SIGNAL(currentIndexChanged(int)), this, SLOT(AxesDisplayChanged(int)));
- connect(axes_checkbox, SIGNAL(stateChanged(int)), this, SLOT(AxesDisplayChanged(int)));
- // 增加圆圈变换
- connect(circleLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(CircleDisplayChanged(const QString&)));
- //off
- connect(progress,&QSlider::valueChanged,this,[=](){// 变动会触发
- if(!ismoved){
- ischanged = true;// “戳”这一个动作会使ischange变成true
- // qDebug()<<"CLICK"<setSliderPosition(0);
- std::thread rosBagPlay(&MyViz::openFile, this);// 新开线程执行操作
- rosBagPlay.detach();
-
- }
- }
-
- });
- connect(pause, &QPushButton::clicked, this, [&]() {
- if(isthreadplaying){
- if(ispauseclick)
- {
- ispauseclick = false;
- }
- else
- {
- ispauseclick = true;
- }
- }
- });
-
- // Construct and lay out render panel.
- render_panel_ = new rviz::RenderPanel(); // RVIZ在QT上显示的类
- QHBoxLayout* main_layout = new QHBoxLayout; // 主要layout QV垂直,QH水平
-
- // Next we initialize the main RViz classes.
- //
- // The VisualizationManager is the container for Display objects,
- // holds the main Ogre scene, holds the ViewController, etc. It is
- // very central and we will probably need one in every usage of
- // librviz.
- manager_ = new rviz::VisualizationManager( render_panel_ ); // 是实现rviz功能的类
- // 初始化camera 这行代码实现放大 缩小 平移等操作
- render_panel_->initialize( manager_->getSceneManager(), manager_ );
- manager_->setFixedFrame("laser");
- // 初始化tool_manager_
- tool_manager_ = manager_->getToolManager();
-
- // 在初始化之后再进行更改操作
- manager_->initialize();
- manager_->startUpdate();
-
- manager_->setFixedFrame(cur_fixed_frame);
- // qDebug()<< cur_fixed_frame;
-
- // 创建select panel
- QLabel *select_label = new QLabel("坐标点显示:");
- tree_widget_ = new rviz::PropertyTreeWidget();
- tree_widget_->setModel(manager_->getSelectionManager()->getPropertyModel());
- ctl_index++;
- controls_layout->addWidget(select_label, ctl_index++, 0);
- // controls_layout->addWidget(tree_widget_, ctl_index++, 0);
- controls_layout->addWidget(tree_widget_, ctl_index++, 0, 1, 2);
-
- // 设置网格某一行伸缩比例,放最后一行
- // controls_layout->setRowStretch(--ctl_index, 6);
-
- // Create a Grid display.
- grid_ = manager_->createDisplay( "rviz/Grid", "adjustable grid", true );
- ROS_ASSERT( grid_ != NULL );
-
- // cloud = manager_->createDisplay( "rviz/PointCloud2", "point cloud", true );
- // ROS_ASSERT( cloud != NULL );
-
- laser_ = manager_->createDisplay( "rviz/LaserScan", "Qlaser", true );
- ROS_ASSERT( laser_ );
- // 新增雷达
- laser_->subProp("Topic")->setValue("/scan");
- laser_->subProp("Size (Pixels)")->setValue("2");
- laser_->subProp("Color Transformer")->setValue("FlatColor");
- laser_->subProp("Color")->setValue(color_name[1]);
- // cloud->subProp("Topic")->setValue("/pose_graph/octree");
- // cloud->subProp("Style")->setValue("Points");
- // cloud->subProp("Size (Pixels)")->setValue("2");
- // cloud->subProp("Color Transformer")->setValue("Intensity");
- // cloud->subProp("Invert Rainbow")->setValue("true");
- // cloud->subProp("Decay Time")->setValue("1");
- // Configure the GridDisplay the way we like it.
- grid_->subProp( "Line Style" )->setValue( "Billboards" );
- grid_->subProp( "Color" )->setValue( QColor( Qt::white ) );
-
- // 新增坐标系
- axes_display= manager_->createDisplay("rviz/Axes", "Axes", false);
- ROS_ASSERT( axes_display != NULL );
- axes_display->subProp("Length")->setValue(0.2); // 设置透明度
- axes_display->subProp("Radius")->setValue(0.05); // 设置坐标系的缩放大小
- // 新增Marker_ 显示圆圈
- marker_ = manager_->createDisplay("rviz/Marker", "Marker", false);
- ROS_ASSERT( marker_ != NULL );
- marker_->subProp("Topic")->setValue("visualization_marker");
-
- // Set the top-level layout for this MyViz widget.
- main_layout->addLayout( controls_layout );
- //main_layout->addLayout( controls_layout );
- main_layout->addWidget( render_panel_,2); // 存放rviz的位置, stretch 拉伸系数
- setLayout( main_layout );
-
-}
-
-void MyViz::Tree_Display(QGridLayout* controls_layout, int index){
- QTreeWidget *menu = new QTreeWidget();
- // menu->setColumnCount(2);
- // 列头自适应大小
- menu->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
-
- menu->setHeaderLabels(QStringList()<<"key"<<"value");
- menu->setHeaderHidden(true);
- // menu->setColumnCount(2);
-
- // 设置不同层次菜单的缩进
- // menu->setIndentation(10);
- // global-一层树
- QTreeWidgetItem *global= new QTreeWidgetItem(menu, QStringList("全局变量"));
- menu->addTopLevelItem(global);
- global->setExpanded(true);
-
- // fix frame
- QTreeWidgetItem *fixed_frame = new QTreeWidgetItem(global, QStringList("固定参考系"));
-
- QLineEdit* fixed_frame_text = new QLineEdit();
- fixed_frame_text->setText("world");
- fixed_frame_text->setStyleSheet("background:transparent;border-width:0;border-style:inset");
- // 初始化固定坐标系
- cur_fixed_frame = fixed_frame_text->text();
- // 设置事件
- connect(fixed_frame_text,SIGNAL(textChanged(const QString&)),this,SLOT(setFixedFrame(const QString&)));
- // 将其他控件(非TreeWidgetItem)放入treeItem中
- menu->setItemWidget(fixed_frame, 1, fixed_frame_text); // 将container 放到 Item ,数字为列数
-
- QTreeWidgetItem *bg_color = new QTreeWidgetItem(global, QStringList("背景颜色"));
- QLineEdit* bg_color_text = new QLineEdit();
- bg_color_text->setText("48;48;48");
- bg_color_text->setStyleSheet("border-width:0;border-style:outset");
- connect(bg_color_text,SIGNAL(textChanged(const QString&)),this,SLOT(setBackgroundColor(const QString&)));
- menu->setItemWidget(bg_color, 1, bg_color_text); // 将container 放到 Item ,数字为列数
-
- // global->addChild(fixed_frame);
- // global->setTextAlignment(1, 2); // (列数,对齐方式)
- // grid - 一层树
- QTreeWidgetItem * grid = new QTreeWidgetItem(menu, QStringList("栅格"));
- // 二层
- QTreeWidgetItem *grid_color = new QTreeWidgetItem(grid, QStringList("颜色"));
- QComboBox * grid_color_cbox = new QComboBox();
- for(int i =0 ; i < color_name.size(); ++i){
- QString color_path = color_icon_filename.arg(color_name[i]);
- QIcon color_icon(color_path);
- grid_color_cbox->addItem(color_icon, color_name[i]);
- }
- connect(grid_color_cbox, SIGNAL(currentIndexChanged(int)), this, SLOT(GridColorChanged(int)));
- menu->setItemWidget(grid_color, 1, grid_color_cbox);
-
- // grid cell size
- QTreeWidgetItem *grid_cell = new QTreeWidgetItem(grid, QStringList("网格大小"));
- QSlider* cell_size_slider = new QSlider( Qt::Horizontal );
- cell_size_slider->setMinimum( 1 );
- cell_size_slider->setMaximum( 100 );
- connect( cell_size_slider, SIGNAL( valueChanged( int )), this, SLOT( setCellSize( int )));
- // cell_size_slider->setValue( 1 );
- menu->setItemWidget(grid_cell, 1, cell_size_slider);
-
- // grid Line Thickness
- QTreeWidgetItem *grid_thickness = new QTreeWidgetItem(grid, QStringList("线条粗细"));
- QSlider* thickness_slider = new QSlider( Qt::Horizontal );
- thickness_slider->setMinimum( 1 );
- thickness_slider->setMaximum( 100 );
- connect( thickness_slider, SIGNAL( valueChanged( int )), this, SLOT( setThickness( int )));
- // thickness_slider->setSliderPosition(1);
- menu->setItemWidget(grid_thickness, 1, thickness_slider);
-
- // laser - 一层树
- QTreeWidgetItem * laser = new QTreeWidgetItem(menu, QStringList("雷达"));
- // 二层
- QTreeWidgetItem *laser_topic = new QTreeWidgetItem(laser, QStringList("话题"));
- // Topic_Laser 输入雷达
- QLineEdit* laser_topic_text = new QLineEdit();
-
- // 方便寻找,登陆后解锁
- laser_topic_text->setObjectName("laser_topic");
- laser_topic_text->setParent(this);
- laser_topic_text->setEnabled(false);
- // 增加雷达话题
- connect(laser_topic_text, SIGNAL(textChanged(const QString &)), this, SLOT(setLaserTopic(const QString &)));
- menu->setItemWidget(laser_topic, 1, laser_topic_text);
-
- // Laser size
- QTreeWidgetItem *laser_size = new QTreeWidgetItem(laser, QStringList("大小"));
- QSpinBox* laser_size_text=new QSpinBox();
- connect(laser_size_text,SIGNAL(valueChanged(int)),this,SLOT(setLaserSize(int)));
- menu->setItemWidget(laser_size, 1, laser_size_text);
-
- // Laser color
- QTreeWidgetItem *laser_color = new QTreeWidgetItem(laser, QStringList("颜色"));
- QComboBox * laser_color_comboBox = new QComboBox();
- for(int i =0 ; i < color_name.size(); ++i){
- QString color_path = color_icon_filename.arg(color_name[i]);
- QIcon color_icon(color_path);
- laser_color_comboBox->addItem(color_icon, color_name[i]);
- }
- // 设置初始化雷达颜色为红色
- laser_color_comboBox->setCurrentIndex(1);
-
- // 增加颜色变换
- connect(laser_color_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(LaserColorChanged(int)));
- menu->setItemWidget(laser_color, 1, laser_color_comboBox);
-
- //controls_layout->addWidget(menu, index, 0 );
- controls_layout->addWidget(menu, index, 0, 1, 2);
-}
-
-
-void MyViz::quit_login_button_clicked(){
- landed = 0;
- // 退出设置登录按钮可用
- QWidget * login_button = this->findChild("login_button");
- if (login_button) {
- login_button->setEnabled(true);
- }else{
- qDebug() << "login_button组件未找到" ;
- }
- // 退出设置退出按钮不可用
- QWidget * quit_button = this->findChild("quit_login_button");
- if (quit_button) {
- quit_button->setEnabled(false);
- }else{
- qDebug() << "quit_login_button组件未找到" ;
- }
- // 退出设置其他组件不可用
- if(dlg != NULL){
- for (int i=0; i< dlg->setting_name.size(); i++){
- QWidget *foundChild = this->findChild(dlg->setting_name[i]);
- if (foundChild) {
- // 找到了指定的子组件 在这里可以对子组件进行操作
- foundChild->setEnabled(false);
- }else{
- qDebug()<<"第" << i+1 <<"组件未找到" ;
- }
- }
- }
-}
-
-void MyViz::login_button_clicked(){
- dlg->setWindowTitle(tr("登录"));
- // dlg->setFixedSize(400, 300);
- // dlg->open();// 非模态级别对话框
- if(dlg->exec() == QDialog::Accepted){
- // 登录成功后
- landed = 1;
- qDebug() << "login accepted";
- // 登录设置其他组件和退出可用
- QWidget * quit_button = this->findChild("quit_login_button");
- if (quit_button) {
- quit_button->setEnabled(true);
- }else{
- qDebug() << "quit_login_button组件未找到" ;
- }
- // 登录设置登录不可用
- QWidget * login_button = this->findChild("login_button");
- if (login_button) {
- login_button->setEnabled(false);
- }else{
- qDebug()<<"login_button组件未找到" ;
- }
- }else{
- // 登录失败
- qDebug() << "login refused";
- }
-}
-
-void MyViz::PlayCircle(double index){
- int argc =0;
- char** argv;
- ros::init(argc, argv, "basic_shapes");
- ros::NodeHandle n;
- ros::Rate r(1);
- ros::Publisher marker_pub = n.advertise("visualization_marker", 1);
- uint32_t shape = visualization_msgs::Marker::LINE_STRIP;
-
- if (ros::ok())
- {
- visualization_msgs::Marker marker;
- // Set the frame ID and timestamp. See the TF tutorials for information on these.
- marker.header.frame_id = cur_fixed_frame.toStdString();
- // marker.header.frame_id = "laser";
- marker.header.stamp = ros::Time::now();
-
- // Set the namespace and id for this marker. This serves to create a unique ID
- // Any marker sent with the same namespace and id will overwrite the old one
- marker.ns = "basic_shapes";
- marker.id = 0;
-
- // Set the marker type. Initially this is CUBE, and cycles between that and SPHERE, ARROW, and CYLINDER
- marker.type = shape;
-
- // Set the marker action. Options are ADD, DELETE, and new in ROS Indigo: 3 (DELETEALL)
- marker.action = visualization_msgs::Marker::ADD;
-
- // Set the pose of the marker. This is a full 6DOF pose relative to the frame/time specified in the header
- marker.pose.position.x = 0;
- marker.pose.position.y = 0;
- marker.pose.position.z = 0;
- marker.pose.orientation.x = 0.0;
- marker.pose.orientation.y = 0.0;
- marker.pose.orientation.z = 0.0;
- marker.pose.orientation.w = 1.0;
-
- // Set the scale of the marker -- 1x1x1 here means 1m on a side
- // 设置线段的宽度
- marker.scale.x = 0.02;
- marker.scale.y = 1.0;
- marker.scale.z = 1.0;
-
- // Set the color -- be sure to set alpha to something non-zero!
- marker.color.r = 0.0f;
- marker.color.g = 1.0f;
- marker.color.b = 0.0f;
- marker.color.a = 1.0;
- // points
- // 绘制同心圆
- // double r_c= std::stod(argv[1]);
- double radius = index;
- int num_points = 360;
- // Create the vertices for the points and lines 画圆
- for (uint32_t i = 0; i < num_points; ++i)
- {
- // float y = sin(f + i / 100.0f * 2 * M_PI);
- // float z = cos(f + i / 100.0f * 2 * M_PI);
- double angle = 2 * M_PI * i / num_points;
- geometry_msgs::Point point;
- point.x = radius * cos(angle);
- point.y = radius * sin(angle);
- point.z = 0.0;
- marker.points.push_back(point);
- }
- marker.lifetime = ros::Duration();
-
- // Publish the marker
- while (marker_pub.getNumSubscribers() < 1)
- {
- if (!ros::ok())
- {
- std::cout<< "publish return 0" << std::endl;
- }
- ROS_WARN_ONCE("Please create a subscriber to the marker");
- // sleep(1);
- }
- marker_pub.publish(marker);
-
- r.sleep();
- }
-
-}
-
-void MyViz::CircleDisplayChanged(const QString& text){
- double index = text.toDouble();
- if(index <= 0){
- marker_->setValue(false);
- }else
- {
- marker_->setValue(true);
- std::thread ThreadCircle(&MyViz::PlayCircle, this, index);// 新开线程执行操作
- ThreadCircle.detach();// 执行完成后自动回收资源
- }
-}
-
-void MyViz::AxesDisplayChanged(int stage)
-{
- // 0未被选中,1被部分选中,2 被选中
- switch (stage)
- {
- case 0: // 未被选中
- if (axes_display != NULL)
- axes_display->setValue(false);
- break;
-
- case 2: // 被选择
- if (axes_display != NULL)
- axes_display->setValue(true);
- break;
- }
-}
-
-void MyViz::slot_move_camera(){
- rviz::Tool* current_tool_= tool_manager_->getDefaultTool();
- tool_manager_->setCurrentTool(current_tool_);
- manager_->startUpdate();
-}
-
-
-void MyViz::slot_select(){
- // 获得工具类
- // tool_manager_ = manager_->getToolManager();
- rviz::Tool* current_tool_ = tool_manager_->addTool("rviz/Select");
- tool_manager_->setCurrentTool(current_tool_);
- manager_->startUpdate();
-}
-
-void MyViz::setBackgroundColor(const QString& color_string){
- if(manager_!=NULL){
- const QString t = color_string;
- QColor new_color = parseColor(t);
- if(new_color.isValid()){
- // rviz源码中修改背景颜色的方式
- render_panel_->setBackgroundColor(qtToOgre(new_color));
- manager_->queueRender();
- }
- else
- {
- ROS_INFO_STREAM("Color invalid !!!");
- }
- }else{
- ROS_INFO_STREAM("manager_ failed !!!");
- }
-}
-
-
-void MyViz::LaserColorChanged(int index){
- if(laser_!=NULL) laser_->subProp("Color")->setValue(color_name[index]);
-
-}
-
-void MyViz::GridColorChanged(int index){
- if(grid_!=NULL) grid_->subProp("Color")->setValue(color_name[index]);
-}
-
-// Destructor.
-MyViz::~MyViz()
-{
- delete manager_;
-}
-
-// This function is a Qt slot connected to a QSlider's valueChanged()
-// signal. It sets the line thickness of the grid by changing the
-// grid's "Line Width" property.
-void MyViz::setThickness( int thickness_percent )
-{
- if( grid_ != NULL )
- {
- grid_->subProp( "Line Style" )->subProp( "Line Width" )->setValue( thickness_percent / 100.0f );
- }
-}
-
-// This function is a Qt slot connected to a QSlider's valueChanged()
-// signal. It sets the cell size of the grid by changing the grid's
-// "Cell Size" Property.
-void MyViz::setCellSize( int cell_size_percent )
-{
- if( grid_ != NULL )
- {
- grid_->subProp( "Cell Size" )->setValue( cell_size_percent / 10.0f );
- }
-}
-
-void MyViz::setCloudTopic(const QString &newTopic){
- if(cloud!=NULL){
- cloud->subProp( "Topic" )->setValue(newTopic);
- //ROS_INFO_STREAM("cloud topic changed to => "<subProp( "Topic" )->setValue(newTopic);
- ROS_INFO_STREAM("laser topic changed to => "<setEnabled(true);
- // laser->subProp( "Color" )->setValue( QColor( Qt::yellow ) );
- // manager_->setFixedFrame("laser");
- manager_->startUpdate();
-}
-
-void MyViz::setFixedFrame(const QString & fix_frame){
- manager_->setFixedFrame(fix_frame);
- cur_fixed_frame = fix_frame;
- manager_->startUpdate();
-}
-
-void MyViz::setCloudSize(int cloudsize){
- if(cloud!=NULL){
- cloud->subProp("Size (Pixels)")->setValue(cloudsize);
- }
-}
-
-void MyViz::setLaserSize(int lasersize){
- if(laser_!=NULL){
- laser_->subProp("Size (Pixels)")->setValue(lasersize);
- }
-}
-
-void MyViz::subCallback(const std_msgs::String& msg){
- ROS_INFO_STREAM("receive message!");
-}
-
-void MyViz::pubThread(){
- while(ros::ok()){
- ROS_INFO_STREAM_ONCE("here is in publish process!");
- }
-}
-
-
-void MyViz::openFile()
-{
- ros::Rate r(10.0);
- rosbag::Bag bag,newBag;
- std::string pcdFilePathStr = filePath.toStdString();
- int frameEnd;
- int frameStart;
- bool saveFlag = false;
- if(stored)
- {
- char** argv;// 字符串内容(输入)
- int argc=0;// 字符串个数(输入)
- countbag = 0;
- ros::init(argc, argv, "laser_scan_publisher");// "laser"???????????重新启动一下roscore可以解决
- // qDebug()<<"11111";
-
- ros::NodeHandle n;
- scan_pub = n.advertise("scan", 5);// "topic"
- // sleep time
-
- bag.open(pcdFilePathStr, rosbag::bagmode::Read);
-
- rosbag::View view1(bag, rosbag::TopicQuery("/scan"));
- view = &view1;
- std::cout<size()<begin(); it != view->end(); ++it)// 用于预先存储bag包的信息
- {
- auto m = *it;
- sensor_msgs::LaserScan::ConstPtr input = m.instantiate();
- indx.push_back(input);
- }
- stored = false;
- indxsize = indx.size();
- bag.close();
- qDebug()<=indxsize)
- {
- scan_pub.publish(*indx[indxsize-1]);
- end = true;// 停在当前位置
- countbag = 0;// 从头开始
- qDebug()<<"publish end";
- }
- // progressmove = false;
-
- if(is_rateChanged){
- qDebug() << QString::number(speed_rate);
- r = ros::Rate(speed_rate);
- r.reset();
- is_rateChanged = false;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- if(is_save){
- if(newBag.isOpen())
- newBag.close();
- std::string temFileStr = pcdFilePathStr;
- temFileStr.resize(pcdFilePathStr.length() - 4);
- std::string saveFilePathStr = temFileStr + "frame" \
- + std::to_string(countbag) + ".bag";
- std::cout << saveFilePathStr;
- std::ifstream file(saveFilePathStr.c_str());
- if (!file.good()) {
- // std::ofstream outputFile(saveFilePathStr); //create a file
- // outputFile.close();
-
- QFile newFile(QString::fromStdString(saveFilePathStr));
-
- newBag.open(saveFilePathStr, rosbag::bagmode::Write);
- // for(int i=0;i<10;i++){
- newBag.write("/scan", ros::Time::now(), indx[countbag]);
- // }
- newBag.close();
- }else{
- // file exist
- }
-
- is_save = false;
- r.sleep();
- countbag++;
- continue;
- }
- if(is_saveMul || is_saveMulFinish){
- if(ispauseclick && is_saveMul)
- {
- is_saveMul = false;
- QMessageBox msgBox;
- msgBox.setWindowTitle("Tips");
- msgBox.setText("Pause First Please!");
- msgBox.resize(2000, 1000);
- msgBox.exec();
- continue;
- }
-
- if(is_saveMulFinish){
- frameEnd = countbag;
- std::string temFileStr = pcdFilePathStr;
- temFileStr.resize(pcdFilePathStr.length() - 4);
- std::string saveFilePathStr = temFileStr + "frame" \
- + std::to_string(frameStart) + "to" + std::to_string(frameEnd) + ".bag";
- std::cout << saveFilePathStr;
- std::ifstream file(saveFilePathStr.c_str());
- if (!file.good()) {
-
-
- newBag.open(saveFilePathStr, rosbag::bagmode::Write);
-
-
- for(int i = frameStart; i < frameEnd; i++){
-
- newBag.write("/scan", ros::Time::now(), indx[i]);
-
-
- }
- is_saveMulFinish = false;
- is_saveMul = false;
- saveFlag = false;
- newBag.close();
- }else{
-
- }
- }
- else{
- qDebug()<setSliderPosition(ceil(countbag/indxsize*100));
- qDebug()<value()/100)*indxsize;
- double valuedouble = progress->value();
- countbag = round((valuedouble/100)*indxsize);
- if(countbag >= indxsize)// 直接重新开始for循环
- {
- countbag = indxsize-1;
- progress->setSliderPosition(100);
- ispauseclick = false;
- }
- ismoved = false;
- }
- else if(ischanged)// 手戳动时改变进度条
- {
- end = false;
- int value = (progress->value()/100)*indxsize;
- double valuedouble = progress->value();
- countbag = round((valuedouble/100)*indxsize);
- if(countbag >= indxsize)// 直接重新开始for循环
- {
- countbag = indxsize-1;
- progress->setSliderPosition(100);
- ispauseclick = false;
- }
- scan_pub.publish(*indx[countbag]);
- countbag++;
- ischanged = false;
- r.sleep();
- continue;
- // ismoved = false;
- }
- if(!ispauseclick || end)
- {
- qDebug()<<"pause";
- if(countbagsliderPosition()<=100 && countbagvalue/indxsize*100<=100)
- {
- qDebug()<<"pause";
- progress->setSliderPosition(ceil(countbagvalue/indxsize*100));
- qDebug()<setSliderPosition(0);
- isthreadplaying = false;
- playagain = false;
- filePath = QFileDialog::getOpenFileName(nullptr, "select file", "/home", "bag(*.bag);;所有文件 (*)");
- qDebug()<< filePath;
- if(filePath.isEmpty()){
- QMessageBox msgBox;
- msgBox.setWindowTitle("Tips");
- msgBox.setText("No file is selected");
- msgBox.resize(2000, 1000);
- // 设置样式表,包括透明度设置
- msgBox.setStyleSheet("QMessageBox {"
- "background-color: rgba(255, 255, 255, 0.9);" // 设置背景颜色和透明度
- "border: 2px solid rgba(0, 0, 0, 0.9);" // 设置边框颜色和透明度
- "}"
- "QLabel {"
- "color: rgba(0, 0, 0, 0.9);" // 设置文本颜色和透明度
- "font-size: 16px;"
- "}");
- QTimer selectTimer;
- selectTimer.setSingleShot(true); // 设置定时器只触发一次
- selectTimer.start(2000); // 3秒后触发定时器,单位是毫秒
-
- //连接定时器的超时信号到关闭消息框的槽函数
- QObject::connect(&selectTimer, &QTimer::timeout, [&]() {
- msgBox.done(QMessageBox::Ok); // 关闭消息框
- });
- msgBox.exec();
- }else{
-
- QMessageBox msgBox;
- msgBox.setWindowTitle("Tips");
- msgBox.setText("File selected");
- msgBox.resize(2000, 1000);
- // 设置样式表,包括透明度设置
- msgBox.setStyleSheet("QMessageBox {"
- "background-color: rgba(255, 255, 255, 0.9);" // 设置背景颜色和透明度
- "border: 2px solid rgba(0, 0, 0, 0.9);" // 设置边框颜色和透明度
- "}"
- "QLabel {"
- "color: rgba(0, 0, 0, 0.9);" // 设置文本颜色和透明度
- "font-size: 16px;"
- "}");
- QTimer selectTimer;
- selectTimer.setSingleShot(true); // 设置定时器只触发一次
- selectTimer.start(2000); // 3秒后触发定时器,单位是毫秒
-
- //连接定时器的超时信号到关闭消息框的槽函数
- QObject::connect(&selectTimer, &QTimer::timeout, [&]() {
- msgBox.done(QMessageBox::Ok); // 关闭消息框
- });
- msgBox.exec();
- isthreadplaying = true;
- }
-}
-
-
-void MyViz::SpeedChanged(int index){
- // if(isthreadplaying)
- bool ok;
- double number = speed_name[index].toDouble(&ok);
- if(ok){
- speed_rate = 10.0 * number;
- qDebug() << "*************func test" << QString::number(speed_rate);
- is_rateChanged = true;
- }
-
- else{
- qDebug() << "failed";
- }
-}
\ No newline at end of file
diff --git a/librviz_tutorial/CHANGELOG.rst b/point_visual/CHANGELOG.rst
similarity index 100%
rename from librviz_tutorial/CHANGELOG.rst
rename to point_visual/CHANGELOG.rst
diff --git a/librviz_tutorial/CMakeLists.txt b/point_visual/CMakeLists.txt
similarity index 83%
rename from librviz_tutorial/CMakeLists.txt
rename to point_visual/CMakeLists.txt
index 5d360fe..d3a9c55 100644
--- a/librviz_tutorial/CMakeLists.txt
+++ b/point_visual/CMakeLists.txt
@@ -4,7 +4,7 @@
##
## First start with some standard catkin stuff.
cmake_minimum_required(VERSION 3.0.2)
-project(librviz_tutorial)
+project(point_visual)
set(SDK_PATH "./sdk/")
@@ -17,7 +17,15 @@ FILE(GLOB SDK_SRC
find_package(catkin REQUIRED COMPONENTS
rviz roscpp std_msgs
rosconsole sensor_msgs # node.cpp
-rosbag
+rosbag
+pcl_ros
+)
+
+find_package(PCL REQUIRED)
+include_directories(
+ include
+ ${catkin_INCLUDE_DIRS}
+ /usr/include/pcl-1.8
)
@@ -68,8 +76,8 @@ set(SRC_FILES
add_executable(myviz ${SRC_FILES} )
-add_executable(rplidarNode src/node.cpp ${SDK_SRC}) # 创建启动laser
-target_link_libraries(rplidarNode ${catkin_LIBRARIES})
+# add_executable(rplidarNode src/node.cpp ${SDK_SRC}) # 创建启动laser
+# target_link_libraries(rplidarNode ${catkin_LIBRARIES})
target_link_libraries(myviz -lcrypto)
@@ -85,11 +93,11 @@ target_link_libraries(myviz ${QT_LIBRARIES} ${catkin_LIBRARIES})
## Install
install(TARGETS myviz DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
-install(TARGETS rplidarNode
- ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
- LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
- RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
-)
+# install(TARGETS rplidarNode
+# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
+# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
+# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
+# )
install(DIRECTORY launch sdk
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
diff --git a/point_visual/launch/laser.launch b/point_visual/launch/laser.launch
new file mode 100644
index 0000000..425c158
--- /dev/null
+++ b/point_visual/launch/laser.launch
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/librviz_tutorial/launch/rplidar.launch b/point_visual/launch/rplidar.launch
similarity index 81%
rename from librviz_tutorial/launch/rplidar.launch
rename to point_visual/launch/rplidar.launch
index 0b2c7e2..1c88615 100644
--- a/librviz_tutorial/launch/rplidar.launch
+++ b/point_visual/launch/rplidar.launch
@@ -1,5 +1,5 @@
-
+
diff --git a/librviz_tutorial/package.xml b/point_visual/package.xml
similarity index 96%
rename from librviz_tutorial/package.xml
rename to point_visual/package.xml
index b6183b9..a1961ef 100644
--- a/librviz_tutorial/package.xml
+++ b/point_visual/package.xml
@@ -1,5 +1,5 @@
- librviz_tutorial
+ point_visual
0.11.0
Tutorial showing how to compile your own C++ program with RViz displays and features.
diff --git a/librviz_tutorial/rosdoc.yaml b/point_visual/rosdoc.yaml
similarity index 100%
rename from librviz_tutorial/rosdoc.yaml
rename to point_visual/rosdoc.yaml
diff --git a/librviz_tutorial/sdk/README.txt b/point_visual/sdk/README.txt
similarity index 100%
rename from librviz_tutorial/sdk/README.txt
rename to point_visual/sdk/README.txt
diff --git a/librviz_tutorial/sdk/include/rplidar.h b/point_visual/sdk/include/rplidar.h
similarity index 100%
rename from librviz_tutorial/sdk/include/rplidar.h
rename to point_visual/sdk/include/rplidar.h
diff --git a/librviz_tutorial/sdk/include/rplidar_cmd.h b/point_visual/sdk/include/rplidar_cmd.h
similarity index 100%
rename from librviz_tutorial/sdk/include/rplidar_cmd.h
rename to point_visual/sdk/include/rplidar_cmd.h
diff --git a/librviz_tutorial/sdk/include/rplidar_driver.h b/point_visual/sdk/include/rplidar_driver.h
similarity index 100%
rename from librviz_tutorial/sdk/include/rplidar_driver.h
rename to point_visual/sdk/include/rplidar_driver.h
diff --git a/librviz_tutorial/sdk/include/rplidar_protocol.h b/point_visual/sdk/include/rplidar_protocol.h
similarity index 100%
rename from librviz_tutorial/sdk/include/rplidar_protocol.h
rename to point_visual/sdk/include/rplidar_protocol.h
diff --git a/librviz_tutorial/sdk/include/rptypes.h b/point_visual/sdk/include/rptypes.h
similarity index 100%
rename from librviz_tutorial/sdk/include/rptypes.h
rename to point_visual/sdk/include/rptypes.h
diff --git a/librviz_tutorial/sdk/src/arch/linux/arch_linux.h b/point_visual/sdk/src/arch/linux/arch_linux.h
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/linux/arch_linux.h
rename to point_visual/sdk/src/arch/linux/arch_linux.h
diff --git a/librviz_tutorial/sdk/src/arch/linux/net_serial.cpp b/point_visual/sdk/src/arch/linux/net_serial.cpp
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/linux/net_serial.cpp
rename to point_visual/sdk/src/arch/linux/net_serial.cpp
diff --git a/librviz_tutorial/sdk/src/arch/linux/net_serial.h b/point_visual/sdk/src/arch/linux/net_serial.h
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/linux/net_serial.h
rename to point_visual/sdk/src/arch/linux/net_serial.h
diff --git a/librviz_tutorial/sdk/src/arch/linux/net_socket.cpp b/point_visual/sdk/src/arch/linux/net_socket.cpp
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/linux/net_socket.cpp
rename to point_visual/sdk/src/arch/linux/net_socket.cpp
diff --git a/librviz_tutorial/sdk/src/arch/linux/thread.hpp b/point_visual/sdk/src/arch/linux/thread.hpp
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/linux/thread.hpp
rename to point_visual/sdk/src/arch/linux/thread.hpp
diff --git a/librviz_tutorial/sdk/src/arch/linux/timer.cpp b/point_visual/sdk/src/arch/linux/timer.cpp
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/linux/timer.cpp
rename to point_visual/sdk/src/arch/linux/timer.cpp
diff --git a/librviz_tutorial/sdk/src/arch/linux/timer.h b/point_visual/sdk/src/arch/linux/timer.h
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/linux/timer.h
rename to point_visual/sdk/src/arch/linux/timer.h
diff --git a/librviz_tutorial/sdk/src/arch/macOS/arch_macOS.h b/point_visual/sdk/src/arch/macOS/arch_macOS.h
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/macOS/arch_macOS.h
rename to point_visual/sdk/src/arch/macOS/arch_macOS.h
diff --git a/librviz_tutorial/sdk/src/arch/macOS/net_serial.cpp b/point_visual/sdk/src/arch/macOS/net_serial.cpp
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/macOS/net_serial.cpp
rename to point_visual/sdk/src/arch/macOS/net_serial.cpp
diff --git a/librviz_tutorial/sdk/src/arch/macOS/net_serial.h b/point_visual/sdk/src/arch/macOS/net_serial.h
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/macOS/net_serial.h
rename to point_visual/sdk/src/arch/macOS/net_serial.h
diff --git a/librviz_tutorial/sdk/src/arch/macOS/net_socket.cpp b/point_visual/sdk/src/arch/macOS/net_socket.cpp
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/macOS/net_socket.cpp
rename to point_visual/sdk/src/arch/macOS/net_socket.cpp
diff --git a/librviz_tutorial/sdk/src/arch/macOS/thread.hpp b/point_visual/sdk/src/arch/macOS/thread.hpp
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/macOS/thread.hpp
rename to point_visual/sdk/src/arch/macOS/thread.hpp
diff --git a/librviz_tutorial/sdk/src/arch/macOS/timer.cpp b/point_visual/sdk/src/arch/macOS/timer.cpp
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/macOS/timer.cpp
rename to point_visual/sdk/src/arch/macOS/timer.cpp
diff --git a/librviz_tutorial/sdk/src/arch/macOS/timer.h b/point_visual/sdk/src/arch/macOS/timer.h
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/macOS/timer.h
rename to point_visual/sdk/src/arch/macOS/timer.h
diff --git a/librviz_tutorial/sdk/src/arch/win32/arch_win32.h b/point_visual/sdk/src/arch/win32/arch_win32.h
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/win32/arch_win32.h
rename to point_visual/sdk/src/arch/win32/arch_win32.h
diff --git a/librviz_tutorial/sdk/src/arch/win32/net_serial.cpp b/point_visual/sdk/src/arch/win32/net_serial.cpp
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/win32/net_serial.cpp
rename to point_visual/sdk/src/arch/win32/net_serial.cpp
diff --git a/librviz_tutorial/sdk/src/arch/win32/net_serial.h b/point_visual/sdk/src/arch/win32/net_serial.h
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/win32/net_serial.h
rename to point_visual/sdk/src/arch/win32/net_serial.h
diff --git a/librviz_tutorial/sdk/src/arch/win32/net_socket.cpp b/point_visual/sdk/src/arch/win32/net_socket.cpp
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/win32/net_socket.cpp
rename to point_visual/sdk/src/arch/win32/net_socket.cpp
diff --git a/librviz_tutorial/sdk/src/arch/win32/timer.cpp b/point_visual/sdk/src/arch/win32/timer.cpp
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/win32/timer.cpp
rename to point_visual/sdk/src/arch/win32/timer.cpp
diff --git a/librviz_tutorial/sdk/src/arch/win32/timer.h b/point_visual/sdk/src/arch/win32/timer.h
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/win32/timer.h
rename to point_visual/sdk/src/arch/win32/timer.h
diff --git a/librviz_tutorial/sdk/src/arch/win32/winthread.hpp b/point_visual/sdk/src/arch/win32/winthread.hpp
similarity index 100%
rename from librviz_tutorial/sdk/src/arch/win32/winthread.hpp
rename to point_visual/sdk/src/arch/win32/winthread.hpp
diff --git a/librviz_tutorial/sdk/src/hal/abs_rxtx.h b/point_visual/sdk/src/hal/abs_rxtx.h
similarity index 100%
rename from librviz_tutorial/sdk/src/hal/abs_rxtx.h
rename to point_visual/sdk/src/hal/abs_rxtx.h
diff --git a/librviz_tutorial/sdk/src/hal/assert.h b/point_visual/sdk/src/hal/assert.h
similarity index 100%
rename from librviz_tutorial/sdk/src/hal/assert.h
rename to point_visual/sdk/src/hal/assert.h
diff --git a/librviz_tutorial/sdk/src/hal/byteops.h b/point_visual/sdk/src/hal/byteops.h
similarity index 100%
rename from librviz_tutorial/sdk/src/hal/byteops.h
rename to point_visual/sdk/src/hal/byteops.h
diff --git a/librviz_tutorial/sdk/src/hal/event.h b/point_visual/sdk/src/hal/event.h
similarity index 100%
rename from librviz_tutorial/sdk/src/hal/event.h
rename to point_visual/sdk/src/hal/event.h
diff --git a/librviz_tutorial/sdk/src/hal/locker.h b/point_visual/sdk/src/hal/locker.h
similarity index 100%
rename from librviz_tutorial/sdk/src/hal/locker.h
rename to point_visual/sdk/src/hal/locker.h
diff --git a/librviz_tutorial/sdk/src/hal/socket.h b/point_visual/sdk/src/hal/socket.h
similarity index 100%
rename from librviz_tutorial/sdk/src/hal/socket.h
rename to point_visual/sdk/src/hal/socket.h
diff --git a/librviz_tutorial/sdk/src/hal/thread.cpp b/point_visual/sdk/src/hal/thread.cpp
similarity index 100%
rename from librviz_tutorial/sdk/src/hal/thread.cpp
rename to point_visual/sdk/src/hal/thread.cpp
diff --git a/librviz_tutorial/sdk/src/hal/thread.h b/point_visual/sdk/src/hal/thread.h
similarity index 100%
rename from librviz_tutorial/sdk/src/hal/thread.h
rename to point_visual/sdk/src/hal/thread.h
diff --git a/librviz_tutorial/sdk/src/hal/types.h b/point_visual/sdk/src/hal/types.h
similarity index 100%
rename from librviz_tutorial/sdk/src/hal/types.h
rename to point_visual/sdk/src/hal/types.h
diff --git a/librviz_tutorial/sdk/src/hal/util.h b/point_visual/sdk/src/hal/util.h
similarity index 100%
rename from librviz_tutorial/sdk/src/hal/util.h
rename to point_visual/sdk/src/hal/util.h
diff --git a/librviz_tutorial/sdk/src/rplidar_driver.cpp b/point_visual/sdk/src/rplidar_driver.cpp
similarity index 100%
rename from librviz_tutorial/sdk/src/rplidar_driver.cpp
rename to point_visual/sdk/src/rplidar_driver.cpp
diff --git a/librviz_tutorial/sdk/src/rplidar_driver_TCP.h b/point_visual/sdk/src/rplidar_driver_TCP.h
similarity index 100%
rename from librviz_tutorial/sdk/src/rplidar_driver_TCP.h
rename to point_visual/sdk/src/rplidar_driver_TCP.h
diff --git a/librviz_tutorial/sdk/src/rplidar_driver_impl.h b/point_visual/sdk/src/rplidar_driver_impl.h
similarity index 100%
rename from librviz_tutorial/sdk/src/rplidar_driver_impl.h
rename to point_visual/sdk/src/rplidar_driver_impl.h
diff --git a/librviz_tutorial/sdk/src/rplidar_driver_serial.h b/point_visual/sdk/src/rplidar_driver_serial.h
similarity index 100%
rename from librviz_tutorial/sdk/src/rplidar_driver_serial.h
rename to point_visual/sdk/src/rplidar_driver_serial.h
diff --git a/librviz_tutorial/sdk/src/sdkcommon.h b/point_visual/sdk/src/sdkcommon.h
similarity index 100%
rename from librviz_tutorial/sdk/src/sdkcommon.h
rename to point_visual/sdk/src/sdkcommon.h
diff --git a/point_visual/sources/images/button/approach.png b/point_visual/sources/images/button/approach.png
new file mode 100644
index 0000000..910bda2
Binary files /dev/null and b/point_visual/sources/images/button/approach.png differ
diff --git a/point_visual/sources/images/button/back.png b/point_visual/sources/images/button/back.png
new file mode 100644
index 0000000..9e89b4f
Binary files /dev/null and b/point_visual/sources/images/button/back.png differ
diff --git a/point_visual/sources/images/button/pause.png b/point_visual/sources/images/button/pause.png
new file mode 100644
index 0000000..a18c404
Binary files /dev/null and b/point_visual/sources/images/button/pause.png differ
diff --git a/point_visual/sources/images/button/play.png b/point_visual/sources/images/button/play.png
new file mode 100644
index 0000000..1e3cd8d
Binary files /dev/null and b/point_visual/sources/images/button/play.png differ
diff --git a/librviz_tutorial/sources/images/black.png b/point_visual/sources/images/color/black.png
similarity index 100%
rename from librviz_tutorial/sources/images/black.png
rename to point_visual/sources/images/color/black.png
diff --git a/librviz_tutorial/sources/images/blue.png b/point_visual/sources/images/color/blue.png
similarity index 100%
rename from librviz_tutorial/sources/images/blue.png
rename to point_visual/sources/images/color/blue.png
diff --git a/librviz_tutorial/sources/images/green.png b/point_visual/sources/images/color/green.png
similarity index 100%
rename from librviz_tutorial/sources/images/green.png
rename to point_visual/sources/images/color/green.png
diff --git a/librviz_tutorial/sources/images/lightgreen.png b/point_visual/sources/images/color/lightgreen.png
similarity index 100%
rename from librviz_tutorial/sources/images/lightgreen.png
rename to point_visual/sources/images/color/lightgreen.png
diff --git a/librviz_tutorial/sources/images/orange.png b/point_visual/sources/images/color/orange.png
similarity index 100%
rename from librviz_tutorial/sources/images/orange.png
rename to point_visual/sources/images/color/orange.png
diff --git a/librviz_tutorial/sources/images/pink.png b/point_visual/sources/images/color/pink.png
similarity index 100%
rename from librviz_tutorial/sources/images/pink.png
rename to point_visual/sources/images/color/pink.png
diff --git a/librviz_tutorial/sources/images/purple.png b/point_visual/sources/images/color/purple.png
similarity index 100%
rename from librviz_tutorial/sources/images/purple.png
rename to point_visual/sources/images/color/purple.png
diff --git a/librviz_tutorial/sources/images/red.png b/point_visual/sources/images/color/red.png
similarity index 100%
rename from librviz_tutorial/sources/images/red.png
rename to point_visual/sources/images/color/red.png
diff --git a/librviz_tutorial/sources/images/skyblue.png b/point_visual/sources/images/color/skyblue.png
similarity index 100%
rename from librviz_tutorial/sources/images/skyblue.png
rename to point_visual/sources/images/color/skyblue.png
diff --git a/librviz_tutorial/sources/images/white.png b/point_visual/sources/images/color/white.png
similarity index 100%
rename from librviz_tutorial/sources/images/white.png
rename to point_visual/sources/images/color/white.png
diff --git a/librviz_tutorial/sources/images/yellow.png b/point_visual/sources/images/color/yellow.png
similarity index 100%
rename from librviz_tutorial/sources/images/yellow.png
rename to point_visual/sources/images/color/yellow.png
diff --git a/librviz_tutorial/sources/user/input.txt b/point_visual/sources/user/input.txt
similarity index 100%
rename from librviz_tutorial/sources/user/input.txt
rename to point_visual/sources/user/input.txt
diff --git a/librviz_tutorial/sources/user/user.txt b/point_visual/sources/user/user.txt
similarity index 100%
rename from librviz_tutorial/sources/user/user.txt
rename to point_visual/sources/user/user.txt
diff --git a/librviz_tutorial/src/doc/conf.py b/point_visual/src/doc/conf.py
similarity index 100%
rename from librviz_tutorial/src/doc/conf.py
rename to point_visual/src/doc/conf.py
diff --git a/librviz_tutorial/src/doc/index.rst b/point_visual/src/doc/index.rst
similarity index 100%
rename from librviz_tutorial/src/doc/index.rst
rename to point_visual/src/doc/index.rst
diff --git a/librviz_tutorial/src/doc/myviz.png b/point_visual/src/doc/myviz.png
similarity index 100%
rename from librviz_tutorial/src/doc/myviz.png
rename to point_visual/src/doc/myviz.png
diff --git a/librviz_tutorial/src/doc/tutorialformatter.py b/point_visual/src/doc/tutorialformatter.py
similarity index 100%
rename from librviz_tutorial/src/doc/tutorialformatter.py
rename to point_visual/src/doc/tutorialformatter.py
diff --git a/librviz_tutorial/src/loginDialog.cpp b/point_visual/src/loginDialog.cpp
similarity index 71%
rename from librviz_tutorial/src/loginDialog.cpp
rename to point_visual/src/loginDialog.cpp
index 43264e4..1e50af6 100644
--- a/librviz_tutorial/src/loginDialog.cpp
+++ b/point_visual/src/loginDialog.cpp
@@ -9,8 +9,10 @@
LoginDialog::LoginDialog(QWidget *parent):QDialog(parent)
{
+
+ this->setFixedSize(380, 300);
userLabel = new QLabel(this);
- userLabel->move(80, 80);
+ userLabel->move(70, 80);
userLabel->setText(tr("用户名"));
userEditLine = new QLineEdit(this);
@@ -18,7 +20,7 @@ LoginDialog::LoginDialog(QWidget *parent):QDialog(parent)
userEditLine->setPlaceholderText(tr("请输入用户名"));
pwdLabel = new QLabel(this);
- pwdLabel->move(80, 130);
+ pwdLabel->move(70, 130);
pwdLabel->setText(tr("密码"));
pwdEditLine = new QLineEdit(this);
@@ -33,23 +35,24 @@ LoginDialog::LoginDialog(QWidget *parent):QDialog(parent)
exitBtn = new QPushButton(this);
exitBtn->move(220, 200);
exitBtn->setText(tr("退出"));
-
+
connect(loginBtn, &QPushButton::clicked, this, &LoginDialog::login);
connect(exitBtn, &QPushButton::clicked, this, &LoginDialog::close);
// 待解锁的组件名称
- setting_name = {"laser_topic", "open_file", "bag_progress"};
+ setting_name = {"cloud_topic", "laser_topic", "open_file", "bag_progress", "fixd_frame_topic"};
+ // 账号路径
+ user_file_name = "../PointVisual/src/point_visual/sources/user/user.txt";
- // to do read from file
+ // 创建用户表存下
createUser();
// userPasswords["root"] = hashPassword("root123");
// userPasswords["wbw"] = hashPassword("123");
}
-
void LoginDialog::createUser(){
- std::ifstream inputFile("../Rviz/librviz_ws/src/librviz_tutorial/sources/user/user.txt");
+ std::ifstream inputFile(user_file_name);
// 第一次读写user.txt将user加密后,建立userPasswords
if(inputFile.is_open()){
std::string line;
@@ -57,7 +60,7 @@ void LoginDialog::createUser(){
std::istringstream iss(line);
std::string username, pwd;
if(iss>> username && iss>> pwd){
- if(pwd.size() < 8){
+ if(pwd.size() <= 8){
// 根据长度判断是否已经被加密
pwd = hashPassword(pwd);
}
@@ -74,7 +77,7 @@ void LoginDialog::createUser(){
// 加密后的账户密码写入user.txt
void LoginDialog::writeHash(const std::map user){
- std::ofstream file("../Rviz/librviz_ws/src/librviz_tutorial/sources/user/user.txt");
+ std::ofstream file(user_file_name);
if(file.is_open()){
for(auto iter = user.begin(); iter != user.end() ; iter++){
@@ -124,15 +127,16 @@ std::string LoginDialog::hashPassword(const std::string& password) {
// 判断用户账号返回不同code
int LoginDialog::checkUser(const QString username, const QString pwd){
auto iter = userPasswords.find(username);
- if (iter != userPasswords.end()) {
- if(iter->second == hashPassword(pwd)){
- // 用户密码都对
- return 2;
- }else{
- // 用户对,密码不对
- return 1;
- }
- } else {
+ if(iter != userPasswords.end()){
+ if(pwd.size() > 8) { return 1; }
+ if(iter->second == hashPassword(pwd)){
+ // 用户密码都对
+ return 2;
+ }else{
+ // 用户对,密码不对
+ return 1;
+ }
+ }else {
// 用户不对
return 0;
}
@@ -168,35 +172,6 @@ void LoginDialog::login()
userEditLine->clear();
pwdEditLine->clear();
userEditLine->setFocus();
- // //判断用户名和密码是否正确 todo 函数判断
- // if (userEditLine->text().trimmed() == tr("tom") &&
- // pwdEditLine->text() == tr("123456"))
- // {
- // for(int i=0 ; ifindChild(setting_name[i]);
- // if (foundChild) {
- // qDebug()<<"111" ;
- // // 找到了指定的子组件 在这里可以对子组件进行操作
- // foundChild->setEnabled(true);
- // }else{
- // qDebug()<<"第" << i+1 <<"组件未找到" ;
- // }
- // }
- // QMessageBox::information(this, tr("登录成功"), tr("已解锁"), QMessageBox::Yes);
- // // landed = 1;
- // accept();
- // }
- // else
- // {
- // QMessageBox::warning(this, tr("登录失败"), tr("用户名或者密码错误"), QMessageBox::Yes);
- // }
- // userEditLine->clear();
- // pwdEditLine->clear();
- // userEditLine->setFocus();
-
-
- // QMessageBox::information(this, tr("提示"), tr("已经登陆,请勿重新登录"), QMessageBox::Yes);
-
}
diff --git a/librviz_tutorial/src/loginDialog.h b/point_visual/src/loginDialog.h
similarity index 97%
rename from librviz_tutorial/src/loginDialog.h
rename to point_visual/src/loginDialog.h
index aed63ae..fa60a2a 100644
--- a/librviz_tutorial/src/loginDialog.h
+++ b/point_visual/src/loginDialog.h
@@ -46,6 +46,7 @@ private:
// std::vector setting_name;
// 用户表
std::map userPasswords;
+ std::string user_file_name;
};
diff --git a/librviz_tutorial/src/main.cpp b/point_visual/src/main.cpp
similarity index 100%
rename from librviz_tutorial/src/main.cpp
rename to point_visual/src/main.cpp
diff --git a/point_visual/src/myviz.cpp b/point_visual/src/myviz.cpp
new file mode 100644
index 0000000..2e8ef19
--- /dev/null
+++ b/point_visual/src/myviz.cpp
@@ -0,0 +1,2038 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "rviz/properties/property_tree_widget.h"
+#include "rviz/selection/selection_manager.h"
+// #include "rviz/views_panel.h"
+#include "rviz/panel.h"
+#include "rviz/view_controller.h"
+#include "rviz/view_manager.h"
+#include "rviz/view_controller.h"
+
+#include "rviz/visualization_manager.h"
+#include"rviz/tool_manager.h"
+#include "rviz/render_panel.h"
+#include "rviz/display.h"
+
+#include "myviz.h"
+#include "../tools/color.h"
+#include "qthread.h"
+// BEGIN_TUTORIAL
+// Constructor for MyViz. This does most of the work of the class.
+MyViz::MyViz( QWidget* parent)
+ : QWidget( parent )
+{
+
+ nh=ros::NodeHandle("~");
+ sub=nh.subscribe("/test",1000,&MyViz::subCallback,this);
+ pub=nh.advertise("/test_pub",1000);
+ pub_thread=std::thread(&MyViz::pubThread,this);
+
+ // 全局变量存放处
+ // 颜色名称,可添加,待设置rgb类型设置颜色
+ circle_index = 0;
+ color_name = {
+ "white","red","green","black","blue","yellow",
+ "pink","purple","skyblue","lightgreen","orange",
+ };
+ // 颜色路径名
+ color_icon_filename = QString("../PointVisual/src/point_visual/sources/images/color/%1.png");
+ button_icon_filename = QString("../PointVisual/src/point_visual/sources/images/button/%1.png");
+ speed_name = {"2.0","1.5","1.25","1.0","0.75","0.5",};
+ // circle_radius = {};
+ ispauseclick = true;
+ sliderreleased = false;
+ playagain = false;
+ isthreadplaying = false;
+ stored = false;
+
+ dlg = new LoginDialog(this);
+ landed = 0;
+ cur_fixed_frame = "world";
+
+ // 网格结构
+ QGridLayout* controls_layout = new QGridLayout();
+ int ctl_index = 0;
+
+ // 登录按钮
+ QPushButton* login_button = new QPushButton("登录");
+ QPushButton* quit_login_button = new QPushButton("退出");
+
+ //select按钮
+ QPushButton* selection_button = new QPushButton("选择坐标点");
+ QPushButton* move_camera_button = new QPushButton("移动视角");
+
+ controls_layout->addWidget( login_button, ctl_index, 0);
+ controls_layout->addWidget( quit_login_button, ctl_index++, 1);
+
+ // offline 布局
+ // QPushButton setting!////////////////////////////////////////////////////////////////////////////////////////////////
+ QIcon pause_png(button_icon_filename.arg("pause"));
+ QIcon gogo_png(button_icon_filename.arg("approach"));
+ QIcon back_png(button_icon_filename.arg("back"));
+ QIcon play_png(button_icon_filename.arg("play"));
+
+ play = new QPushButton(play_png, "", this);
+
+ QPushButton* but_save = new QPushButton("保存一帧", this);// buttonn: save one frame
+ QPushButton* but_saveMul = new QPushButton("保存多帧", this);// button: save multiple frames
+ QPushButton* but_file = new QPushButton("打开文件", this);// button: select file
+
+ QPushButton* but_nextFrame = new QPushButton(gogo_png,"", this);// button: next frame*********************************************************************************************************************
+ QPushButton* but_previousFrame = new QPushButton(back_png,"", this);// button: previous frame*********************************************************************************************************************
+
+ // QLabel setting!/////////////////////////////////////////////////////////////////////////////////////////////////////
+ QLabel* label_speed = new QLabel("播放速度:");//speed combobox
+ QLabel* label_split = new QLabel("");//speed combobox
+
+ // QSlider setting!////////////////////////////////////////////////////////////////////////////////////////////////////
+ progress = new QSlider(Qt::Horizontal);
+ // QComboBox setting!//////////////////////////////////////////////////////////////////////////////////////////////////
+ QComboBox * speed_combobox = new QComboBox();
+
+ QPushButton* but_trans = new QPushButton("格式转换", this);// buttonn: save one frame
+
+ //enable button////////////////////////////////////////////////////////////////////////////////////////////////////////
+ play->setEnabled(true);
+ but_save->setEnabled(true);
+ but_saveMul->setEnabled(true);
+ but_file->setEnabled(false);
+
+ // setting button size!////////////////////////////////////////////////////////////////////////////////////////////////
+ play->setFixedSize(130, 30);
+ but_save->setFixedSize(130, 30);
+ but_saveMul->setFixedSize(130, 30);
+ but_file->setFixedSize(130, 30);
+
+ but_nextFrame->setFixedSize(130, 30);
+ but_previousFrame->setFixedSize(130, 30);
+
+ for(int i = 0; i < speed_name.size(); i++)
+ speed_combobox->addItem(speed_name[i] + "x");
+ speed_combobox->setCurrentIndex(3);
+
+ controls_layout->addWidget( label_split, ctl_index++, 0 );
+ controls_layout->addWidget( but_file, ctl_index, 0 );
+ controls_layout->addWidget(but_trans, ctl_index++,1);
+
+ controls_layout->addWidget( but_save, ctl_index, 0 );
+ controls_layout->addWidget( but_saveMul, ctl_index++, 1 );
+ controls_layout->addWidget( move_camera_button, ctl_index, 0);
+ controls_layout->addWidget( selection_button, ctl_index++ ,1);
+
+ controls_layout->addWidget(label_speed,ctl_index,0);
+ controls_layout->addWidget(speed_combobox,ctl_index++,1);
+
+ controls_layout->addWidget( play, ctl_index++, 0 );
+
+ controls_layout->addWidget( but_previousFrame, ctl_index, 0 );
+ controls_layout->addWidget( but_nextFrame, ctl_index++, 1 );
+ controls_layout->addWidget(progress,ctl_index++,0, 1, 2); // addwidget(widget,row,col,m,n);//m是占几行,n是占几列,
+
+ controls_layout->setSpacing(5);
+
+ // 是否选择显示坐标轴
+ QLabel* label_axes = new QLabel("参考坐标系:");
+ QCheckBox *axes_checkbox = new QCheckBox("", this);
+ axes_checkbox->setStyleSheet("QCheckBox::indicator { width: 20px; height: 20px; }");
+ // QComboBox * axesBox = new QComboBox();
+ // axesBox->addItem("不显示");
+ // axesBox->addItem("显示");
+
+ // 选择圆圈范围
+ QLabel* label_circle = new QLabel("距离参考圈(m): ");
+ QLineEdit* circleLineEdit = new QLineEdit();
+ circleLineEdit->setPlaceholderText("请输入数字");
+ circleLineEdit->setFixedSize(130,30);
+ // 设置父组件
+ circleLineEdit->setObjectName("circle_edit");
+ circleLineEdit->setParent(this);
+ // 增加圆圈增加,删除按钮
+ QPushButton* but_addCircle = new QPushButton("添加参考圈");
+ QPushButton* but_deleteCircle = new QPushButton("删除参考圈");
+
+ // 以红色坐标轴指向自己为正视图
+ QPushButton* but_view0 = new QPushButton("正视图");
+ QPushButton* but_view_left = new QPushButton("左视图");
+ QPushButton* but_view_right = new QPushButton("右视图");
+ QPushButton* but_view_top = new QPushButton("俯视图");
+
+
+ controls_layout->addWidget(but_addCircle, ctl_index, 0);
+ controls_layout->addWidget(but_deleteCircle, ctl_index++, 1);
+
+ controls_layout->addWidget(label_circle, ctl_index,0);
+ controls_layout->addWidget(circleLineEdit, ctl_index++,1);
+
+ controls_layout->addWidget(label_axes, ctl_index,0);
+ controls_layout->addWidget(axes_checkbox, ctl_index++,1);
+
+
+ controls_layout->addWidget(but_view0, ctl_index, 0);
+ controls_layout->addWidget(but_view_top, ctl_index++, 1);
+ controls_layout->addWidget(but_view_left, ctl_index, 0);
+ controls_layout->addWidget(but_view_right, ctl_index++, 1);
+
+ // Tree 全局变量存放地方
+ Tree_Display(controls_layout, ctl_index++);
+
+ // 待解锁子组件设置父组件,方便寻找,登陆后解锁可编辑属性
+ login_button->setObjectName("login_button");
+ login_button->setParent(this);
+ quit_login_button->setObjectName("quit_login_button");
+ quit_login_button->setParent(this);
+ quit_login_button->setEnabled(false);
+
+ but_file->setObjectName("open_file");
+ but_file->setParent(this);
+ progress->setObjectName("bag_progress");
+ progress->setParent(this);
+ progress->setEnabled(false);
+
+ // controls_layout->setRowStretch(3, 0);
+ // Make signal/slot connections. 进行信号/插槽连接
+
+ // 增加登录按钮
+ connect(login_button, SIGNAL(clicked()), this, SLOT(login_button_clicked()));
+ // 增加退出按钮
+ connect(quit_login_button, SIGNAL(clicked()), this, SLOT(quit_login_button_clicked()));
+
+ // 增加切换select
+ connect(selection_button, SIGNAL(clicked()), this, SLOT( slot_select()));
+ connect(move_camera_button, SIGNAL(clicked()), this, SLOT( slot_move_camera()));
+
+ // 增加坐标变换
+ // connect(axesBox, SIGNAL(currentIndexChanged(int)), this, SLOT(AxesDisplayChanged(int)));
+ connect(axes_checkbox, SIGNAL(stateChanged(int)), this, SLOT(AxesDisplayChanged(int)));
+ // 增加圆圈变换-弃用
+ // connect(circleLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(CircleDisplayChanged(const QString&)));
+ // 增加圆圈
+ connect(but_addCircle, SIGNAL(clicked()), this, SLOT(CircleDisplayAdded()));
+ // 删除圆圈
+ connect(but_deleteCircle, SIGNAL(clicked()), this, SLOT(CircleDisplayDeleted()));
+ // 增加视角回正
+ connect(but_view0, SIGNAL(clicked()), this, SLOT(ViewZero()));
+ // 增加视角左转
+ connect(but_view_left, SIGNAL(clicked()), this, SLOT(ViewLeft()));
+ // 增加视角右转
+ connect(but_view_right, SIGNAL(clicked()), this, SLOT(ViewRight()));
+ // 增加视角俯视
+ connect(but_view_top, SIGNAL(clicked()), this, SLOT(ViewTop()));
+
+ //off
+ connect(but_nextFrame, &QPushButton::clicked, this, [&]() {
+ if(!ispauseclick){
+ is_next = true;
+ }else{
+ QMessageBox::information(this, "tips", "No file is played");
+ }
+ });
+ connect(but_previousFrame, &QPushButton::clicked, this, [&]() {
+ if(!ispauseclick){
+ is_previous = true;
+ }else{
+ QMessageBox::information(this, "tips", "No file is played");
+ }
+ });
+
+ connect(progress,&QSlider::valueChanged,this,[=](){// 变动会触发
+ if(!ismoved){
+ ischanged = true;// “戳”这一个动作会使ischange变成true
+ }
+ });
+ connect(progress,&QSlider::sliderMoved,this,[=](){// 变动会触发
+ sliderreleased = true;
+ ismoved = true;
+ });
+ connect(progress,&QSlider::sliderPressed,this,[=](){// 拖动时打开暂停
+ ispauseclick = false;
+ // play->setText("Play");
+ play->setIcon(QIcon(play_png));
+ });
+ connect(progress,&QSlider::sliderReleased,this,[=](){// 释放时关闭暂停
+ // sliderreleased = true;
+ ispauseclick = false;
+ ismoved = false;
+ // play->setText("Play");
+ play->setIcon(QIcon(play_png));
+ });
+
+ connect(but_save, &QPushButton::clicked, this, [&]() {
+ if(isthreadplaying){
+ ispauseclick = false;
+ SavefileName = QFileDialog::getSaveFileName(nullptr, "Save File", "/home","files(*)");
+ is_save = true;
+ }
+ // QMessageBox::information(this, "tips", "Save Complete!");}
+ else
+ ;
+ // QMessageBox::information(this, "tips", "No file is played");
+ });
+ connect(but_saveMul, &QPushButton::clicked, this, [&]() {
+ if(isthreadplaying){
+ if(is_saveMul){
+ is_saveMul = false;
+ is_saveMulFinish = true;
+ QMessageBox::information(this, "tips", "Save Mul Complete!");
+ }
+ else{
+ SaveMulfileName = QFileDialog::getSaveFileName(nullptr, "Save File", "/home","files(*)");
+ is_saveMul = true;
+ std::string nametype = find(SaveMulfileName.toStdString());
+ if(!ispauseclick && !is_saveMulFinish && is_saveMul && nametype=="bag")
+ {
+ QMessageBox::information(this, "tips", "Move Slider to Choose End!");
+ }
+ }
+ }else{
+ QMessageBox::information(this, "tips", "No file is played");
+ }
+ });
+ connect(but_file, &QPushButton::clicked, this, &MyViz::selectFile);
+
+ connect(speed_combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(SpeedChanged(int)));//speed change
+ connect(play, &QPushButton::clicked,this,[=]() {// *********************************************************************************************************************
+ // 只有当线程启动时才能按暂停键
+ if(filePath.isEmpty())
+ {
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("Please Choose a File!");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ }
+ else{
+
+
+ if(threadout && !playagain){
+ threadout = false;
+ playagain = true;
+ ispauseclick = true;
+ isthreadplaying = true;
+ stored = true;
+ // play->setText("Pause");
+ play->setIcon(pause_png);
+ std::string choice = find(filePath.toStdString());
+ int filename;
+ if(choice == "bag")
+ {
+ filename = 0;
+ if(Topic.isEmpty())
+ {
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("Please set topic!");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ filename = -1;
+ isthreadplaying = false;
+ playagain = false;
+ threadout = true;
+ ispauseclick = false;
+ stored = false;
+ }
+ }
+ if(choice == "pcd"){filename = 1;}
+ if(choice == "ply"){filename = 2;}
+ if(choice == "bin"){filename = 3;}
+
+ switch(filename)
+ {
+ case 0:
+ {std::thread rosBagPlay(&MyViz::openFile, this);
+ rosBagPlay.detach();
+ break;}
+ case 1:
+ {std::thread rosBagPlay(&MyViz::pcdFile, this);
+ rosBagPlay.detach();
+ break;}
+ case 2:
+ {std::thread rosBagPlay(&MyViz::plyFile, this);
+ rosBagPlay.detach();
+ break;}
+ case 3:
+ {std::thread rosBagPlay(&MyViz::bin, this);
+ rosBagPlay.detach();
+ break;}
+ }
+ }
+ else if(isthreadplaying && playagain && ispauseclick){ // pause
+ ispauseclick = false;
+ play->setIcon(play_png);
+ }else if(isthreadplaying && playagain && ! ispauseclick){ // not pause
+ ispauseclick = true;;
+ play->setIcon(pause_png);
+ }
+
+
+ }
+
+ });
+ // connect(bg_topic_text,SIGNAL(textChanged(const QString&)),this,SLOT(setTopic(const QString&)));
+
+ connect(but_trans, &QPushButton::clicked, this, &MyViz::TransformeType);
+
+ // Construct and lay out render panel.
+ render_panel_ = new rviz::RenderPanel(); // RVIZ在QT上显示的类
+ QHBoxLayout* main_layout = new QHBoxLayout; // 主要layout QV垂直,QH水平
+
+ // Next we initialize the main RViz classes.
+ //
+ // The VisualizationManager is the container for Display objects,
+ // holds the main Ogre scene, holds the ViewController, etc. It is
+ // very central and we will probably need one in every usage of
+ // librviz.
+ manager_ = new rviz::VisualizationManager( render_panel_ ); // 是实现rviz功能的类
+ // 初始化camera 这行代码实现放大 缩小 平移等操作
+ render_panel_->initialize( manager_->getSceneManager(), manager_ );
+ manager_->setFixedFrame("laser");
+ // 初始化tool_manager_
+ tool_manager_ = manager_->getToolManager();
+
+ // 在初始化之后再进行更改操作
+ manager_->initialize();
+ manager_->startUpdate();
+
+ manager_->setFixedFrame(cur_fixed_frame);
+
+ // 创建select panel
+ QLabel *select_label = new QLabel("坐标点显示:");
+ select_tree_widget_ = new rviz::PropertyTreeWidget();
+ select_tree_widget_->setModel(manager_->getSelectionManager()->getPropertyModel());
+ ctl_index++;
+ controls_layout->addWidget(select_label, ctl_index++, 0);
+ controls_layout->addWidget(select_tree_widget_, ctl_index++, 0, 1, 2);
+
+ // view_tree_widget_ = new rviz::PropertyTreeWidget();
+ // 视角类ViewManager
+ view_man_ = manager_->getViewManager();
+ viewController = view_man_ ->getCurrent();
+ ROS_ASSERT( viewController != NULL );
+ // view_tree_widget_->setModel(view_man_ -> getPropertyModel());
+ // controls_layout->addWidget(view_tree_widget_, ctl_index++, 0, 1, 2);
+
+ // 设置网格某一行伸缩比例,放最后一行
+ // controls_layout->setRowStretch(--ctl_index, 6);
+
+ // Create a Grid display.
+ grid_ = manager_->createDisplay( "rviz/Grid", "adjustable grid", true );
+ ROS_ASSERT( grid_ != NULL );
+ grid_->subProp( "Line Style" )->setValue( "Billboards" );
+ grid_->subProp( "Color" )->setValue( QColor( Qt::white ) );
+
+ // 新增点云
+ cloud = manager_->createDisplay( "rviz/PointCloud2", "point cloud", true );
+ ROS_ASSERT( cloud != NULL );
+ cloud->subProp("Size (m)")->setValue("0.005");
+ cloud->subProp("Color Transformer")->setValue("FlatColor");
+ cloud->subProp("Style")->setValue("Flat Squares");
+ // cloud->subProp("Topic")->setValue("/pose_graph/octree");
+ // cloud->subProp("Invert Rainbow")->setValue("true");
+ // cloud->subProp("Decay Time")->setValue("1");
+ // Configure the GridDisplay the way we like it.
+
+ laser_ = manager_->createDisplay( "rviz/LaserScan", "Qlaser", true );
+ ROS_ASSERT( laser_ );
+ // 新增雷达
+ laser_->subProp("Topic")->setValue("/scan");
+ laser_->subProp("Size (m)")->setValue("0.015");
+ laser_->subProp("Color Transformer")->setValue("FlatColor");
+ laser_->subProp("Color")->setValue(color_name[1]);
+
+ // 新增坐标系
+ axes_display= manager_->createDisplay("rviz/Axes", "Axes", false);
+ ROS_ASSERT( axes_display != NULL );
+ axes_display->subProp("Length")->setValue(0.2); // 设置透明度
+ axes_display->subProp("Radius")->setValue(0.05); // 设置坐标系的缩放大小
+ // 新增Marker_ 显示圆圈
+ marker_ = manager_->createDisplay("rviz/Marker", "Marker", false);
+ ROS_ASSERT( marker_ != NULL );
+ marker_->subProp("Topic")->setValue("visualization_marker");
+
+ // Set the top-level layout for this MyViz widget.
+ main_layout->addLayout( controls_layout );
+ // main_layout->addLayout( controls_layout );
+ // main_layout->addWidget( view_tree_widget_);
+ main_layout->addWidget( render_panel_,2); // 存放rviz的位置, stretch 拉伸系数
+ setLayout( main_layout );
+
+}
+
+void MyViz::Tree_Display(QGridLayout* controls_layout, int index){
+ QTreeWidget *menu = new QTreeWidget();
+ // menu->setColumnCount(2);
+ // 列头自适应大小
+ menu->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ menu->setHeaderLabels(QStringList()<<"key"<<"value");
+ menu->setHeaderHidden(true);
+
+ // 设置不同层次菜单的缩进
+ // menu->setIndentation(10);
+ // global-一层树
+ QTreeWidgetItem *global= new QTreeWidgetItem(menu, QStringList("全局变量"));
+ menu->addTopLevelItem(global);
+ global->setExpanded(true);
+
+ // fix frame
+ QTreeWidgetItem *fixed_frame = new QTreeWidgetItem(global, QStringList("固定参考系"));
+ QLineEdit* fixed_frame_text = new QLineEdit();
+ fixed_frame_text->setText("world");
+ // 方便寻找,登陆后解锁
+ fixed_frame_text->setObjectName("fixd_frame_topic");
+ fixed_frame_text->setParent(this);
+ fixed_frame_text->setEnabled(false);
+ // fixed_frame_text->setStyleSheet("background:transparent;border-width:0;border-style:inset");
+ // 初始化固定坐标系
+ cur_fixed_frame = fixed_frame_text->text();
+ // 设置事件
+ connect(fixed_frame_text,SIGNAL(textChanged(const QString&)),this,SLOT(setFixedFrame(const QString&)));
+ // 将其他控件(非TreeWidgetItem)放入treeItem中
+ menu->setItemWidget(fixed_frame, 1, fixed_frame_text); // 将container 放到 Item ,数字为列数
+
+ QTreeWidgetItem *bg_color = new QTreeWidgetItem(global, QStringList("背景颜色 "));
+ QLineEdit* bg_color_text = new QLineEdit();
+ bg_color_text->setText("50;50;50");
+ // bg_color_text->setFixedWidth(130);
+ // bg_color_text->setStyleSheet("border-width:0;border-style:outset");
+ connect(bg_color_text,SIGNAL(textChanged(const QString&)),this,SLOT(setBackgroundColor(const QString&)));
+ menu->setItemWidget(bg_color, 1, bg_color_text); // 将container 放到 Item ,数字为列数
+
+ // global->addChild(fixed_frame);
+ // global->setTextAlignment(1, 2); // (列数,对齐方式)
+ // grid - 一层树
+ QTreeWidgetItem * grid = new QTreeWidgetItem(menu, QStringList("栅格"));
+ // 二层
+ QTreeWidgetItem *grid_color = new QTreeWidgetItem(grid, QStringList("颜色"));
+ QComboBox * grid_color_cbox = new QComboBox();
+ for(int i =0 ; i < color_name.size(); ++i){
+ QString color_path = color_icon_filename.arg(color_name[i]);
+ QIcon color_icon(color_path);
+ grid_color_cbox->addItem(color_icon, color_name[i]);
+ }
+ connect(grid_color_cbox, SIGNAL(currentIndexChanged(int)), this, SLOT(GridColorChanged(int)));
+ menu->setItemWidget(grid_color, 1, grid_color_cbox);
+
+ // grid cell size
+ QTreeWidgetItem *grid_cell = new QTreeWidgetItem(grid, QStringList("网格大小"));
+ QSlider* cell_size_slider = new QSlider( Qt::Horizontal );
+ cell_size_slider->setMinimum( 1 );
+ cell_size_slider->setMaximum( 100 );
+ cell_size_slider->setValue(10);
+ connect( cell_size_slider, SIGNAL( valueChanged( int )), this, SLOT( setCellSize( int )));
+ menu->setItemWidget(grid_cell, 1, cell_size_slider);
+
+ // grid Line Thickness
+ QTreeWidgetItem *grid_thickness = new QTreeWidgetItem(grid, QStringList("线条粗细"));
+ QSlider* thickness_slider = new QSlider( Qt::Horizontal );
+ thickness_slider->setMinimum( 1 );
+ thickness_slider->setMaximum( 100 );
+ thickness_slider->setValue(5);
+ connect( thickness_slider, SIGNAL( valueChanged( int )), this, SLOT( setThickness( int )));
+
+ menu->setItemWidget(grid_thickness, 1, thickness_slider);
+
+ // laser - 一层树
+ QTreeWidgetItem * laser = new QTreeWidgetItem(menu, QStringList("雷达"));
+ // 二层
+ QTreeWidgetItem *laser_topic = new QTreeWidgetItem(laser, QStringList("话题"));
+ // Topic_Laser 输入雷达
+ QLineEdit* laser_topic_text = new QLineEdit();
+
+ // 方便寻找,登陆后解锁
+ laser_topic_text->setObjectName("laser_topic");
+ laser_topic_text->setParent(this);
+ laser_topic_text->setEnabled(false);
+ // 增加雷达话题
+ connect(laser_topic_text, SIGNAL(textChanged(const QString &)), this, SLOT(setLaserTopic(const QString &)));
+ menu->setItemWidget(laser_topic, 1, laser_topic_text);
+
+ // Laser size
+ QTreeWidgetItem *laser_size = new QTreeWidgetItem(laser, QStringList("大小(m)"));
+ QLineEdit* laser_size_text=new QLineEdit();
+ laser_size_text->setText("0.015");
+ connect(laser_size_text,SIGNAL(textChanged(const QString &)),this,SLOT(setLaserSize(const QString &)));
+ menu->setItemWidget(laser_size, 1, laser_size_text);
+
+ // Laser Alpha
+ QTreeWidgetItem *laser_alpha = new QTreeWidgetItem(laser, QStringList("透明度"));
+ QLineEdit* laser_alpha_text=new QLineEdit();
+ laser_alpha_text->setText("1");
+ connect(laser_alpha_text,SIGNAL(textChanged(const QString &)),this,SLOT(setLaserAlpha(const QString &)));
+ menu->setItemWidget(laser_alpha, 1, laser_alpha_text);
+
+ // Laser color
+ QTreeWidgetItem *laser_color = new QTreeWidgetItem(laser, QStringList("颜色"));
+ QComboBox * laser_color_comboBox = new QComboBox();
+ for(int i =0 ; i < color_name.size(); ++i){
+ QString color_path = color_icon_filename.arg(color_name[i]);
+ QIcon color_icon(color_path);
+ laser_color_comboBox->addItem(color_icon, color_name[i]);
+ }
+ // 设置初始化雷达颜色为红色
+ laser_color_comboBox->setCurrentIndex(1);
+ // 增加颜色变换
+ connect(laser_color_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(LaserColorChanged(int)));
+ menu->setItemWidget(laser_color, 1, laser_color_comboBox);
+
+ // cloud - 一层树
+ QTreeWidgetItem * cloud = new QTreeWidgetItem(menu, QStringList("点云"));
+ // 二层
+ QTreeWidgetItem *cloud_topic = new QTreeWidgetItem(cloud, QStringList("话题"));
+ // Colud_Topic 输入雷达
+ QLineEdit* cloud_topic_text = new QLineEdit();
+ cloud_topic_text->setObjectName("cloud_topic");
+ cloud_topic_text->setParent(this);
+ cloud_topic_text->setEnabled(false);
+ connect(cloud_topic_text, SIGNAL(textChanged(const QString &)), this, SLOT(setCloudTopic(const QString &)));
+ menu->setItemWidget(cloud_topic, 1, cloud_topic_text);
+
+ // Cloud Size
+ QTreeWidgetItem *cloud_size = new QTreeWidgetItem(cloud, QStringList("大小(m)"));
+ QLineEdit* cloud_size_text=new QLineEdit();
+ cloud_size_text->setText("0.005");
+ connect(cloud_size_text,SIGNAL(textChanged(const QString &)),this,SLOT(setCloudSize(const QString &)));
+ menu->setItemWidget(cloud_size, 1, cloud_size_text);
+
+ // Cloud Alpha
+ QTreeWidgetItem *cloud_alpha = new QTreeWidgetItem(cloud, QStringList("透明度"));
+ QLineEdit* cloud_alpha_text=new QLineEdit();
+ cloud_alpha_text->setText("1");
+ connect(cloud_alpha_text,SIGNAL(textChanged(const QString &)),this,SLOT(setCloudAlpha(const QString &)));
+ menu->setItemWidget(cloud_alpha, 1, cloud_alpha_text);
+
+ // cloud color
+ QTreeWidgetItem *cloud_color = new QTreeWidgetItem(cloud, QStringList("颜色"));
+ QComboBox * cloud_color_comboBox = new QComboBox();
+ for(int i =0 ; i < color_name.size(); ++i){
+ QString color_path = color_icon_filename.arg(color_name[i]);
+ QIcon color_icon(color_path);
+ cloud_color_comboBox->addItem(color_icon, color_name[i]);
+ }
+ // 设置初始化颜色
+ cloud_color_comboBox->setCurrentIndex(0);
+
+ connect(cloud_color_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(CloudColorChanged(int)));
+ menu->setItemWidget(cloud_color, 1, cloud_color_comboBox);
+
+ //controls_layout->addWidget(menu, index, 0 );
+ controls_layout->addWidget(menu, index, 0, 1, 2);
+}
+
+void MyViz::ViewTop(){
+ viewController->reset();
+ viewController->subProp("Yaw")->setValue(0);
+ viewController->subProp("Pitch")->setValue(1.5698);
+}
+
+void MyViz::ViewLeft(){
+ viewController->reset();
+ viewController->subProp("Yaw")->setValue(1.570796*3);
+ viewController->subProp("Pitch")->setValue(0);
+}
+
+void MyViz::ViewRight(){
+ viewController->reset();
+ // 0.785398是以红色为正的右边45度
+ viewController->subProp("Yaw")->setValue(1.570796);
+ viewController->subProp("Pitch")->setValue(0);
+}
+
+void MyViz::ViewZero(){
+ if (viewController)
+ {
+ viewController->reset();
+ viewController->subProp("Yaw")->setValue(0);
+ viewController->subProp("Pitch")->setValue(0);
+ }
+}
+
+void MyViz::quit_login_button_clicked(){
+ landed = 0;
+ // 退出设置登录按钮可用
+ QWidget * login_button = this->findChild("login_button");
+ if (login_button) {
+ login_button->setEnabled(true);
+ }else{
+ qDebug() << "login_button组件未找到" ;
+ }
+ // 退出设置退出按钮不可用
+ QWidget * quit_button = this->findChild("quit_login_button");
+ if (quit_button) {
+ quit_button->setEnabled(false);
+ }else{
+ qDebug() << "quit_login_button组件未找到" ;
+ }
+ // 退出设置其他组件不可用
+ if(dlg != NULL){
+ for (int i=0; i< dlg->setting_name.size(); i++){
+ QWidget *foundChild = this->findChild(dlg->setting_name[i]);
+ if (foundChild) {
+ // 找到了指定的子组件 在这里可以对子组件进行操作
+ foundChild->setEnabled(false);
+ }else{
+ qDebug()<<"第" << i+1 <<"组件未找到" ;
+ }
+ }
+ }
+}
+
+void MyViz::login_button_clicked(){
+ dlg->setWindowTitle(tr("登录"));
+ // dlg->open();// 非模态级别对话框
+ if(dlg->exec() == QDialog::Accepted){
+ // 登录成功后
+ landed = 1;
+ qDebug() << "login accepted";
+ // 登录设置其他组件和退出可用
+ QWidget * quit_button = this->findChild("quit_login_button");
+ if (quit_button) {
+ quit_button->setEnabled(true);
+ }else{
+ qDebug() << "quit_login_button组件未找到" ;
+ }
+ // 登录设置登录不可用
+ QWidget * login_button = this->findChild("login_button");
+ if (login_button) {
+ login_button->setEnabled(false);
+ }else{
+ qDebug()<<"login_button组件未找到" ;
+ }
+ }else{
+ // 登录失败
+ qDebug() << "login refused";
+ }
+}
+
+void MyViz::PlayCircles(){
+ int argc =0;
+ char** argv;
+ ros::init(argc, argv, "basic_shapes");
+ ros::NodeHandle n;
+ ros::Rate r(100);
+ ros::Publisher marker_pub = n.advertise("visualization_marker", 10);
+ uint32_t shape = visualization_msgs::Marker::LINE_STRIP;
+ double radius = 0; // 圆的半径
+
+ if(ros::ok())
+ {
+ for(auto it = circle_radius.begin(); it != circle_radius.end(); ++it){
+ // qDebug() << it->first <<"r_test_playcicle";
+ visualization_msgs::Marker marker;
+ // Set the frame ID and timestamp. See the TF tutorials for information on these.
+ marker.header.frame_id = cur_fixed_frame.toStdString();
+ // marker.header.frame_id = "laser";
+ marker.header.stamp = ros::Time::now();
+
+ // Set the namespace and id for this marker. This serves to create a unique ID
+ // Any marker sent with the same namespace and id will overwrite the old one
+ marker.ns = "basic_shapes";
+ marker.id = it->second;
+ // Set the marker type. Initially this is CUBE, and cycles between that and SPHERE, ARROW, and CYLINDER
+ marker.type = shape;
+
+ // Set the marker action. Options are ADD, DELETE, and new in ROS Indigo: 3 (DELETEALL)
+ marker.action = visualization_msgs::Marker::ADD;
+
+ // Set the pose of the marker. This is a full 6DOF pose relative to the frame/time specified in the header
+ marker.pose.position.x = 0;
+ marker.pose.position.y = 0;
+ marker.pose.position.z = 0;
+ marker.pose.orientation.x = 0.0;
+ marker.pose.orientation.y = 0.0;
+ marker.pose.orientation.z = 0.0;
+ marker.pose.orientation.w = 1.0;
+
+ // Set the scale of the marker -- 1x1x1 here means 1m on a side
+ // 设置线段的宽度
+ marker.scale.x = 0.02;
+ marker.scale.y = 1.0;
+ marker.scale.z = 1.0;
+
+ // Set the color -- be sure to set alpha to something non-zero!
+ marker.color.r = 0.0f;
+ marker.color.g = 1.0f;
+ marker.color.b = 0.0f;
+ marker.color.a = 1.0;
+ // points
+ // 绘制同心圆
+ // double r_c= std::stod(argv[1]);
+ int num_points = 360;
+
+ // Create the vertices for the points and lines 画圆
+ radius = it->first;
+ for (uint32_t i = 0; i < num_points; ++i)
+ {
+ double angle = 2 * M_PI * i / num_points;
+ geometry_msgs::Point point;
+ point.x = radius * cos(angle);
+ point.y = radius * sin(angle);
+ point.z = 0.0;
+ marker.points.push_back(point);
+ }
+ marker.lifetime = ros::Duration();
+
+ // Publish the marker 等待订阅者订阅
+ while (marker_pub.getNumSubscribers() < 1) // 测试rviz点击就更新了,全部更新
+ {
+ if (!ros::ok())
+ {
+ std::cout<< "publish return 0" << std::endl;
+ }
+ ROS_WARN_ONCE("Please create a subscriber to the marker");
+ // sleep(1);
+ }
+
+ marker_pub.publish(marker);
+ r.sleep();
+ }
+ }
+}
+
+// 删除圆圈槽函数
+void MyViz::CircleDisplayDeleted(){
+ if(circle_radius.empty()){
+ // 如果为空,置index为0,也可以不置
+ circle_index = 0;
+ }
+ QLineEdit * circle_edit = this->findChild("circle_edit");
+ if (circle_edit && !circle_radius.empty()) {
+ QString text = circle_edit->text();
+ double r = text.toDouble();
+ // 从map中找到半径元素
+ auto it = circle_radius.find(r);
+ // 找到半径
+ if( it != circle_radius.end()){
+ // 更新界面
+ marker_->reset();
+ // 先删除再发布
+ circle_radius.erase(it);
+ std::thread ThreadCircleDelete(&MyViz::PlayCircles, this);
+ ThreadCircleDelete.detach();
+ // qDebug() << "删除成功" << it->first ;
+ }
+ }else{
+ // to do
+ // qDebug() << "circle_edit组件未找到 或 circle_radius为空" ;
+ }
+}
+
+// 增加圆圈槽函数
+void MyViz::CircleDisplayAdded(){
+ marker_->setValue(true);
+ QLineEdit * circle_edit = this->findChild("circle_edit");
+ if (circle_edit) {
+ // 获取要删除的半径
+ QString text = circle_edit->text();
+ double r = text.toDouble();
+ if( r == 0 ){
+ // qDebug() << "输入半径为0";
+ // marker_->setValue(false);
+ // to do
+ }else{
+ // marker_->setValue(true);
+ // 判断半径重复
+ if(circle_radius.find(r) == circle_radius.end()){
+ // 未找到相同的半径,则添加
+ circle_radius[r] = circle_index;
+ circle_index++;
+ }else{
+ qDebug() << "相同元素" << r <<"已添加";
+ }
+ marker_->reset();
+ std::thread ThreadCircle(&MyViz::PlayCircles, this);
+ ThreadCircle.detach();// 执行完成后自动回收资源
+ }
+ }else{
+ qDebug() << "circle_edit组件未找到" ;
+ }
+}
+
+// 参考系变化槽函数
+void MyViz::AxesDisplayChanged(int stage)
+{
+ // 0未被选中,1被部分选中,2 被选中
+ switch (stage)
+ {
+ case 0: // 未被选中
+ if (axes_display != NULL)
+ axes_display->setValue(false);
+ break;
+
+ case 2: // 被选择
+ if (axes_display != NULL)
+ axes_display->setValue(true);
+ break;
+ }
+}
+
+void MyViz::slot_move_camera(){
+ rviz::Tool* current_tool_= tool_manager_->getDefaultTool();
+ tool_manager_->setCurrentTool(current_tool_);
+ manager_->startUpdate();
+}
+
+
+void MyViz::slot_select(){
+ // 获得工具类
+ // tool_manager_ = manager_->getToolManager();
+ rviz::Tool* current_tool_ = tool_manager_->addTool("rviz/Select");
+ tool_manager_->setCurrentTool(current_tool_);
+ manager_->startUpdate();
+}
+
+void MyViz::setBackgroundColor(const QString& color_string){
+ if(manager_!=NULL){
+ const QString t = color_string;
+ QColor new_color = parseColor(t);
+ if(new_color.isValid()){
+ // rviz源码中修改背景颜色的方式
+ render_panel_->setBackgroundColor(qtToOgre(new_color));
+ manager_->queueRender();
+ }
+ else
+ {
+ ROS_INFO_STREAM("Color invalid !!!");
+ }
+ }else{
+ ROS_INFO_STREAM("manager_ failed !!!");
+ }
+}
+
+
+void MyViz::LaserColorChanged(int index){
+ if(laser_!=NULL) laser_->subProp("Color")->setValue(color_name[index]);
+
+}
+
+void MyViz::CloudColorChanged(int index){
+ if(cloud!=NULL) cloud->subProp("Color")->setValue(color_name[index]);
+
+}
+void MyViz::GridColorChanged(int index){
+ if(grid_!=NULL) grid_->subProp("Color")->setValue(color_name[index]);
+}
+
+// Destructor.
+MyViz::~MyViz()
+{
+ delete manager_;
+}
+
+void MyViz::setThickness( int thickness_percent )
+{
+ if( grid_ != NULL )
+ {
+ grid_->subProp( "Line Style" )->subProp( "Line Width" )->setValue( thickness_percent / 100.0f );
+ }
+}
+
+void MyViz::setCellSize( int cell_size_percent )
+{
+ if( grid_ != NULL )
+ {
+ grid_->subProp( "Cell Size" )->setValue( cell_size_percent / 10.0f );
+ }
+}
+
+void MyViz::setCloudTopic(const QString &newTopic){
+ if(cloud!=NULL){
+ Topic = newTopic;
+ cloud->subProp( "Topic" )->setValue(newTopic);
+ ROS_INFO_STREAM("cloud topic changed to => "<startUpdate();
+}
+
+void MyViz::setCloudSize(const QString & size){
+ if(cloud!=NULL){
+ cloud->subProp("Size (m)")->setValue(size);
+ }
+}
+
+void MyViz::setCloudAlpha(const QString& cloudAlpha){
+ if(cloud!=NULL){
+ cloud->subProp("Alpha")->setValue(cloudAlpha);
+ }
+}
+void MyViz::setLaserAlpha(const QString& laserAlpha){
+ if(laser_!=NULL){
+ laser_->subProp("Alpha")->setValue(laserAlpha);
+ }
+}
+void MyViz::setLaserTopic(const QString &newTopic){
+ if(laser_!=NULL){
+ Topic = newTopic;
+ laser_->subProp( "Topic" )->setValue(newTopic);
+ ROS_INFO_STREAM("laser topic changed to => "<setEnabled(true);
+ // laser->subProp( "Color" )->setValue( QColor( Qt::yellow ) );
+ // manager_->setFixedFrame("laser");
+ manager_->startUpdate();
+}
+
+void MyViz::setFixedFrame(const QString & fix_frame){
+ manager_->setFixedFrame(fix_frame);
+ cur_fixed_frame = fix_frame;
+ manager_->startUpdate();
+}
+
+void MyViz::setLaserSize(const QString& laserSize){
+ if(laser_!=NULL){
+ laser_->subProp("Size (m)")->setValue(laserSize);
+ }
+}
+
+void MyViz::subCallback(const std_msgs::String& msg){
+ ROS_INFO_STREAM("receive message!");
+}
+
+void MyViz::pubThread(){
+ while(ros::ok()){
+ ROS_INFO_STREAM_ONCE("here is in publish process!");
+ }
+}
+
+void MyViz::openFile()
+{
+ ros::Rate r(10.0);
+ rosbag::Bag bag,newBag;
+ std::string pcdFilePathStr = filePath.toStdString();
+ int frameEnd;
+ int frameStart;
+ bool saveFlag = false;
+ if(stored)
+ {
+ char** argv;// 字符串内容(输入)
+ int argc=0;// 字符串个数(输入)
+ countbag = 0;
+ ros::init(argc, argv, "laser_scan_publisher");// "laser"???????????重新启动一下roscore可以解决
+
+ ros::NodeHandle n;
+ scan_pub = n.advertise(Topic.toStdString(), 5);// "topic"
+ scan_pubpcd = n.advertise(Topic.toStdString(), 5);
+ // sleep time
+
+ bag.open(pcdFilePathStr, rosbag::bagmode::Read);
+
+ rosbag::View view1(bag, rosbag::TopicQuery("/" + Topic.toStdString()));
+ view = &view1;
+ std::cout<size()<begin(); it != view->end(); ++it)// 用于预先存储bag包的信息
+ {
+ auto m = *it;
+ sensor_msgs::LaserScan::ConstPtr input = m.instantiate();
+ if(input==nullptr){break;}
+ indx.push_back(input);
+ }
+ rosbag::View view2(bag, rosbag::TopicQuery("/" + Topic.toStdString()));
+ view_ = &view2;
+ if(view2.size()==0)
+ {
+ isthreadplaying = false;
+ playagain = false;
+ threadout = true;
+ ispauseclick = false;
+ stored = false;
+ QMessageBox::information(this, "warning", "Error Topic!");
+ return;
+ }
+ if(indx.size()==0){
+ for (rosbag::View::iterator it = view_->begin(); it != view_->end(); ++it)// 用于预先存储bag包的信息
+ {
+ auto m = *it;
+ sensor_msgs::PointCloud2::ConstPtr input = m.instantiate();
+ if(input != nullptr){
+ indxpcd.push_back(input);}
+ }
+ pointcloud2 = true;
+ }
+ stored = false;
+ indxsize = indx.size();
+ indxpcdsize = indxpcd.size();
+ bag.close();
+ }
+
+ if(!pointcloud2){
+ while (isthreadplaying)// 用于播放存储的bag包的信息
+ {
+ if(threadout)
+ {
+ break;
+ }
+ double countbagvalue = countbag;
+ if(countbag>=indxsize)
+ {
+ scan_pub.publish(*indx[indxsize-1]);
+ end = true;// 停在当前位置
+ countbag = 0;// 从头开始
+ }
+ // progressmove = false;
+
+ if(is_rateChanged){
+ r = ros::Rate(speed_rate);
+ r.reset();
+ is_rateChanged = false;
+ }
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ if(is_save){
+ if(newBag.isOpen())
+ newBag.close();
+ std::string saveFilePathStr = SavefileName.toStdString();
+
+ qDebug() << SavefileName;
+ if(SavefileName.isEmpty()){
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("Save failure, No file is selected");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ is_save = false;
+ continue;
+ }
+ std::string NameType = find(saveFilePathStr);
+ if(NameType == "bag"){
+ std::ifstream file(saveFilePathStr.c_str());
+ if (!file.good()) {
+ QFile newFile(QString::fromStdString(saveFilePathStr));
+ newBag.open(saveFilePathStr, rosbag::bagmode::Write);
+ newBag.write("/scan", ros::Time::now(), indx[countbag]);
+ newBag.close();
+ }else{
+ // file exist
+ }
+ }
+ // else if(NameType == "pcd"){
+ // pcl::PointCloud pcl_cloud;
+ // // pcl::fromROSMsg(*indx[countbag], pcl_cloud);
+ // populatePointCloudFromLaserScan(*indx[countbag], pcl_cloud);
+ // // 保存点云数据到PCD文件
+ // pcl::io::savePCDFileASCII(saveFilePathStr, pcl_cloud);
+ // }
+ // }else if(NameType == "ply"){
+ // pcl::PointCloud pcl_cloud;
+ // pcl::fromROSMsg(*indx[countbag], pcl_cloud);
+
+ // // 保存点云数据到PLY文件
+ // pcl::io::savePLYFileASCII(saveFilePathStr, pcl_cloud);
+ // }else if(NameType == "bin"){
+ // pcl::PointCloud pcl_cloud;
+ // pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
+
+ // pcl::fromROSMsg(*indx[countbag], *cloud);
+ // std::ofstream bin_file(saveFilePathStr.c_str(),std::ios::out|std::ios::binary|std::ios::app);
+ // if(!bin_file.good()) std::cout<<"Couldn't open "<points.size (); ++i)
+ // {
+ // bin_file.write(reinterpret_cast(&cloud->points[i].x), sizeof(float));
+ // bin_file.write(reinterpret_cast(&cloud->points[i].y), sizeof(float));
+ // bin_file.write(reinterpret_cast(&cloud->points[i].z), sizeof(float));
+ // }
+
+ // bin_file.close();
+ // }
+ else{
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("file type error");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ is_save = false;
+ }
+ is_save = false;
+ r.sleep();
+ countbag++;
+ continue;
+ }
+ if(is_saveMul || is_saveMulFinish){
+ if(ispauseclick && is_saveMul)
+ {
+ is_saveMul = false;
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("Pause First Please!");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ continue;
+ }
+ // QMessageBox::information(this, "tips", "Move Slider to Choose End!");
+ if(is_saveMulFinish){
+ frameEnd = countbag;
+
+ if(frameStart > frameEnd){
+ int tem = frameEnd;
+ frameEnd = frameStart;
+ frameStart = tem;
+ }
+ std::ifstream file(SaveMulfileName.toStdString().c_str());
+ if (!file.good()) {
+ newBag.open(SaveMulfileName.toStdString(), rosbag::bagmode::Write);
+ for(int i = frameStart; i < frameEnd; i++){
+ newBag.write("/scan", ros::Time::now(), indx[i]);
+ }
+ is_saveMulFinish = false;
+ is_saveMul = false;
+ saveFlag = false;
+ newBag.close();
+ }else{
+
+ }
+
+ }
+ else{
+ if(!saveFlag){
+ std::string NameType = find(SaveMulfileName.toStdString());
+ if(SaveMulfileName.isEmpty())
+ {
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("Save failure, No file is selected, Please seve again!");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ is_saveMul = false;
+ continue;
+ }else if(NameType != "bag"){
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("file type error");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ is_saveMul = false;
+ continue;
+ }
+ frameStart = countbag;
+ saveFlag = true;
+ }else{
+ ;
+ }
+ }
+ if(ismoved)
+ {
+ double valuedouble = progress->value();
+ countbag = round((valuedouble/100)*indxsize);
+ scan_pub.publish(*indx[countbag]);
+ progress->setSliderPosition((countbag/indxsize*100));
+ ismoved = false;
+ }
+ else{
+ scan_pub.publish(*indx[countbag]);
+ progress->setSliderPosition((countbag/indxsize*100));
+ r.sleep();
+ ischanged = false;}
+ //Reached the end of the file, but did not stop the multiple frame saving operation
+ if(countbag == indxsize){
+ // newBag.close();
+ frameEnd = indxsize;
+ is_saveMulFinish = true;
+
+ // countbag = 0;
+
+ // ispauseclick = false;
+ }
+
+ continue;}
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ if(ismoved)// 手拖动时改变进度条
+ {
+ end = false;
+ int value = (progress->value()/100)*indxsize;
+ double valuedouble = progress->value();
+ countbag = round((valuedouble/100)*indxsize);
+ if(countbag >= indxsize)// 直接重新开始for循环
+ {
+ countbag = indxsize-1;
+ progress->setSliderPosition(100);
+ ispauseclick = false;
+ }
+ ismoved = false;
+ }
+ else if(ischanged)// 手戳动时改变进度条
+ {
+ end = false;
+ int value = (progress->value()/100)*indxsize;
+ double valuedouble = progress->value();
+ countbag = round((valuedouble/100)*indxsize);
+ if(countbag >= indxsize)// 直接重新开始for循环
+ {
+ countbag = indxsize-1;
+ progress->setSliderPosition(100);
+ ispauseclick = false;
+ }
+ scan_pub.publish(*indx[countbag]);
+ countbag++;
+ ischanged = false;
+ r.sleep();
+ continue;
+ // ismoved = false;
+ }
+ if(!ispauseclick || end)
+ {
+ if(is_next){
+ if(countbag == indxsize)
+ countbag = 0;
+ else
+ countbag++;
+ scan_pub.publish(*indx[countbag]);
+ progress->setSliderPosition(ceil(countbag/indxsize*100));
+ r.sleep();
+ ischanged = false;
+ is_next = false;
+ // continue;
+ }
+ if(is_previous){
+ if(countbag > 0)
+ countbag--;
+ scan_pub.publish(*indx[countbag]);
+ progress->setSliderPosition(ceil(countbag/indxsize*100));
+ r.sleep();
+ ischanged = false;
+ is_previous = false;
+ // continue;
+ }
+ if(countbagsliderPosition()<=100 && countbagvalue/indxsize*100<=100)
+ {
+ progress->setSliderPosition(ceil(countbagvalue/indxsize*100));
+ }
+ countbag++;
+ ischanged = false;
+ r.sleep();
+ }
+ }
+ }
+ else if(pointcloud2){
+ while (isthreadplaying){// 用于播放存储的bag包的信息
+ if(threadout)
+ break;
+ double countbagvalue = countbag;
+ if(countbag>=indxpcdsize)
+ {
+ scan_pubpcd.publish(*indxpcd[indxpcdsize-1]);
+ end = true;// 停在当前位置
+ countbag = 0;// 从头开始
+ }
+ // progressmove = false;
+
+ if(is_rateChanged){
+ r = ros::Rate(speed_rate);
+ r.reset();
+ is_rateChanged = false;
+ }
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ if(is_save){
+ if(newBag.isOpen())
+ newBag.close();
+ std::string saveFilePathStr = SavefileName.toStdString();
+
+ qDebug() << SavefileName;
+ if(SavefileName.isEmpty()){
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("Save failure, No file is selected");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ is_save = false;
+ continue;
+ }
+ std::string NameType = find(saveFilePathStr);
+ if(NameType == "bag"){
+ std::ifstream file(saveFilePathStr.c_str());
+ if (!file.good()) {
+ // std::ofstream outputFile(saveFilePathStr); //create a file
+ // outputFile.close();
+
+ QFile newFile(QString::fromStdString(saveFilePathStr));
+
+ newBag.open(saveFilePathStr, rosbag::bagmode::Write);
+ newBag.write("/scan", ros::Time::now(), indxpcd[countbag]);
+
+ newBag.close();
+ }else{
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("Save failure");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ continue;
+ }
+ }else if(NameType == "pcd"){
+ pcl::PointCloud pcl_cloud;
+ pcl::fromROSMsg(*indxpcd[countbag], pcl_cloud);
+
+ // 保存点云数据到PCD文件
+ pcl::io::savePCDFileASCII(saveFilePathStr, pcl_cloud);
+ }else if (NameType == "ply"){
+ pcl::PointCloud pcl_cloud;
+ pcl::fromROSMsg(*indxpcd[countbag], pcl_cloud);
+
+ // 保存点云数据到PCD文件
+ pcl::io::savePLYFileASCII(saveFilePathStr, pcl_cloud);
+ }else if(NameType == "bin"){
+ pcl::PointCloud pcl_cloud;
+ pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
+
+ pcl::fromROSMsg(*indxpcd[countbag], *cloud);
+ std::ofstream bin_file(saveFilePathStr.c_str(),std::ios::out|std::ios::binary|std::ios::app);
+ if(!bin_file.good()) std::cout<<"Couldn't open "<points.size (); ++i)
+ {
+ bin_file.write(reinterpret_cast(&cloud->points[i].x), sizeof(float));
+ bin_file.write(reinterpret_cast(&cloud->points[i].y), sizeof(float));
+ bin_file.write(reinterpret_cast(&cloud->points[i].z), sizeof(float));
+ }
+
+ bin_file.close();
+ }else{
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("file type error");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ continue;
+ }
+ // std::ifstream file(saveFilePathStr.c_str());
+
+
+ is_save = false;
+ r.sleep();
+ // countbag++;
+ continue;
+ }
+ if(is_saveMul || is_saveMulFinish){
+ if(ispauseclick && is_saveMul)
+ {
+ is_saveMul = false;
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("Pause First Please!");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ continue;
+ }
+ // QMessageBox::information(this, "tips", "Move Slider to Choose End!");
+ if(is_saveMulFinish){
+ frameEnd = countbag;
+ // std::string temFileStr = pcdFilePathStr;
+ // temFileStr.resize(pcdFilePathStr.length() - 4);
+ if(frameStart > frameEnd){
+ int tem = frameEnd;
+ frameEnd = frameStart;
+ frameStart = tem;
+ }
+ std::ifstream file(SaveMulfileName.toStdString().c_str());
+ if (!file.good()) {
+ newBag.open(SaveMulfileName.toStdString(), rosbag::bagmode::Write);
+
+ for(int i = frameStart; i < frameEnd; i++)
+ newBag.write("/scan", ros::Time::now(), indxpcd[i]);
+
+ is_saveMulFinish = false;
+ is_saveMul = false;
+ saveFlag = false;
+ newBag.close();
+ }else{
+
+ }
+ }
+ else{
+ if(!saveFlag){
+ std::string filetype = find(SaveMulfileName.toStdString());
+ if(SaveMulfileName.isEmpty()){
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("Save failure, No file is selected, Please seve again!");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ is_saveMul = false;
+ continue;
+ }else if(filetype != "bag"){
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("file type error");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ is_saveMul = false;
+ continue;
+ }
+ frameStart = countbag;
+ saveFlag = true;
+ }else{
+ ;
+ }
+ }
+ if(ismoved){
+ double valuedouble = progress->value();
+ countbag = round((valuedouble/100)*indxpcdsize);
+ scan_pubpcd.publish(*indxpcd[countbag]);
+ progress->setSliderPosition((countbag/indxpcdsize*100));
+ ismoved = false;
+ }
+ else{
+ scan_pubpcd.publish(*indxpcd[countbag]);
+ progress->setSliderPosition((countbag/indxpcdsize*100));
+ r.sleep();
+ ischanged = false;
+ }
+ //Reached the end of the file, but did not stop the multiple frame saving operation
+ if(countbag == indxpcdsize){
+ // newBag.close();
+ frameEnd = indxpcdsize;
+ is_saveMulFinish = true;
+
+ // countbag = 0;
+
+ // ispauseclick = false;
+ }
+
+ continue;
+ }
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ if(ismoved)// 手拖动时改变进度条
+ {
+ end = false;
+ int value = (progress->value()/100)*indxpcdsize;
+ double valuedouble = progress->value();
+ countbag = round((valuedouble/100)*indxpcdsize);
+ if(countbag >= indxpcdsize)// 直接重新开始for循环
+ {
+ countbag = indxpcdsize-1;
+ progress->setSliderPosition(100);
+ ispauseclick = false;
+ }
+ ismoved = false;
+ }
+ else if(ischanged)// 手戳动时改变进度条
+ {
+ end = false;
+ int value = (progress->value()/100)*indxpcdsize;
+ double valuedouble = progress->value();
+ countbag = round((valuedouble/100)*indxpcdsize);
+ if(countbag >= indxpcdsize)// 直接重新开始for循环
+ {
+ countbag = indxpcdsize-1;
+ progress->setSliderPosition(100);
+ ispauseclick = false;
+ }
+ scan_pubpcd.publish(*indxpcd[countbag]);
+ countbag++;
+ ischanged = false;
+ r.sleep();
+ continue;
+ // ismoved = false;
+ }
+ if(!ispauseclick || end)
+ {
+ if(is_next){
+ if(countbag == indxpcdsize)
+ countbag = 0;
+ else
+ countbag++;
+ scan_pubpcd.publish(*indxpcd[countbag]);
+ progress->setSliderPosition(ceil(countbag/indxpcdsize*100));
+ r.sleep();
+ ischanged = false;
+ is_next = false;
+ // continue;
+ }
+ if(is_previous){
+ if(countbag > 0)
+ countbag--;
+ scan_pubpcd.publish(*indxpcd[countbag]);
+ progress->setSliderPosition(ceil(countbag/indxpcdsize*100));
+ r.sleep();
+ ischanged = false;
+ is_previous = false;
+ // continue;
+ }
+ if(countbagsliderPosition()<=100 && countbagvalue/indxpcdsize*100<=100)
+ {
+ progress->setSliderPosition(ceil(countbagvalue/indxpcdsize*100));
+ }
+ countbag++;
+ ischanged = false;
+ r.sleep();
+ }
+ }
+ }
+}
+
+double MyViz::extractDuration(const QByteArray& output) {
+ QString outputString = QString::fromLocal8Bit(output);
+ QString delimiter = "duration:";
+ outputString = outputString.section(delimiter, 1, 1);
+ delimiter ="\n";
+ outputString = outputString.section(delimiter, 0,0);
+ outputString.remove(" ");
+ outputString.remove("s") ;
+ double number = outputString.toDouble();
+
+ return number;
+}
+
+
+void MyViz::selectFile(){// *********************************************************************************************************************
+ QIcon play_png(button_icon_filename.arg("play"));
+ //QIcon play_png("/home/laijunwen/show/src/point-cloud-visualization/librviz_tutorial/sources/images/play.png");
+ play->setIcon(play_png);
+ threadout = true;
+ if(threadout)// 清空播放容器
+ {
+ stored = true;
+ indx.clear();
+ }
+ progress->setSliderPosition(0);
+ isthreadplaying = false;
+ playagain = false;
+ QString tempath;
+ tempath = QFileDialog::getOpenFileName(nullptr, "select file", "/home", "bag(*.bag);;所有文件 (*)");
+ if(tempath.isEmpty()){
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("No file is selected");
+ msgBox.resize(2000, 1000);
+ // 设置样式表,包括透明度设置
+ msgBox.setStyleSheet("QMessageBox {"
+ "background-color: rgba(255, 255, 255, 0.9);" // 设置背景颜色和透明度
+ "border: 2px solid rgba(0, 0, 0, 0.9);" // 设置边框颜色和透明度
+ "}"
+ "QLabel {"
+ "color: rgba(0, 0, 0, 0.9);" // 设置文本颜色和透明度
+ "font-size: 16px;"
+ "}");
+ QTimer selectTimer;
+ selectTimer.setSingleShot(true); // 设置定时器只触发一次
+ selectTimer.start(2000); // 3秒后触发定时器,单位是毫秒
+
+ //连接定时器的超时信号到关闭消息框的槽函数
+ QObject::connect(&selectTimer, &QTimer::timeout, [&]() {
+ msgBox.done(QMessageBox::Ok); // 关闭消息框
+ });
+ msgBox.exec();
+ }else{
+ filePath = tempath;
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("File selected");
+ msgBox.resize(2000, 1000);
+ // 设置样式表,包括透明度设置
+ msgBox.setStyleSheet("QMessageBox {"
+ "background-color: rgba(255, 255, 255, 0.9);" // 设置背景颜色和透明度
+ "border: 2px solid rgba(0, 0, 0, 0.9);" // 设置边框颜色和透明度
+ "}"
+ "QLabel {"
+ "color: rgba(0, 0, 0, 0.9);" // 设置文本颜色和透明度
+ "font-size: 16px;"
+ "}");
+ QTimer selectTimer;
+ selectTimer.setSingleShot(true); // 设置定时器只触发一次
+ selectTimer.start(2000); // 3秒后触发定时器,单位是毫秒
+
+ //连接定时器的超时信号到关闭消息框的槽函数
+ QObject::connect(&selectTimer, &QTimer::timeout, [&]() {
+ msgBox.done(QMessageBox::Ok); // 关闭消息框
+ });
+ msgBox.exec();
+ isthreadplaying = true;
+ }
+}
+
+
+void MyViz::SpeedChanged(int index){
+ // if(isthreadplaying)
+ bool ok;
+ double number = speed_name[index].toDouble(&ok);
+ if(ok){
+ speed_rate = 10.0 * number;
+ is_rateChanged = true;
+ }
+ else{
+ qDebug() << "speed change failed";
+ }
+}
+
+
+void MyViz::pcdFile()// *********************************************************************************************************************
+{
+ char** argv;// 字符串内容(输入)
+ int argc=0;// 字符串个数(输入)
+ ros::init (argc, argv, "UandBdetect");
+ ros::NodeHandle nh;
+ ros::Publisher pcl_pub = nh.advertise ("pcd_output", 1);
+ pcl::PointCloud cloud;
+ sensor_msgs::PointCloud2 output;
+ std::string pcdFilePathStr = filePath.toStdString();
+ pcl::io::loadPCDFile (pcdFilePathStr, cloud); //修改自己pcd文件所在路径
+ //Convert the cloud to ROS message
+ pcl::toROSMsg(cloud, output);
+ output.header.frame_id = "world";//this has been done in order to be able to visualize our PointCloud2 message on the RViz visualizer
+
+ ros::Rate loop_rate(1);
+
+ pcl_pub.publish(output);
+ ros::spinOnce();
+ loop_rate.sleep();
+}
+
+
+std::string MyViz::find(const std::string Path)
+{
+ size_t lastDotPos = Path.find_last_of('.');
+ std::string fileExtension;
+ if (lastDotPos != std::string::npos)
+ // 提取后缀
+ fileExtension = Path.substr(lastDotPos + 1);
+ return fileExtension;
+}
+
+
+//*********************************************************************************************************************
+void MyViz::plyFile()
+{
+ char** argv;// 字符串内容(输入)
+ int argc=0;// 字符串个数(输入)
+ ros::init (argc, argv, "UandBdetect");
+ ros::NodeHandle nh;
+ ros::Publisher pcl_pub = nh.advertise ("ply_output", 1);
+ pcl::PointCloud cloud;
+ sensor_msgs::PointCloud2 output;
+ std::string pcdFilePathStr = filePath.toStdString();
+ pcl::io::loadPLYFile (pcdFilePathStr, cloud); //修改自己pcd文件所在路径
+ //Convert the cloud to ROS message
+ pcl::toROSMsg(cloud, output);
+ output.header.frame_id = "world";//this has been done in order to be able to visualize our PointCloud2 message on the RViz visualizer
+ //!!!这一步需要注意,是后面rviz的 fixed_frame !!!敲黑板,画重点。
+ ros::Rate loop_rate(1);
+ // while (ros::ok())
+ // {
+ pcl_pub.publish(output);
+ ros::spinOnce();
+ loop_rate.sleep();
+ // }
+}
+
+void MyViz::bin()
+{
+ std::string binFilePathStr = filePath.toStdString();
+ std::ifstream inFile(binFilePathStr, std::ios::binary);
+ if (!inFile.is_open())
+ {
+ std::cerr << "Failed to open input binary file." << std::endl;
+
+ }
+ pcl::PointCloud::Ptr cloud1(new pcl::PointCloud);
+ while (!inFile.eof())
+ {
+ pcl::PointXYZ point;
+ inFile.read(reinterpret_cast(&point.x), sizeof(float));
+ inFile.read(reinterpret_cast(&point.y), sizeof(float));
+ inFile.read(reinterpret_cast(&point.z), sizeof(float));
+
+ if (inFile.eof())
+ break;
+
+ cloud1->push_back(point);
+ }
+
+ inFile.close();
+ binFilePathStr = binFilePathStr.substr(0,binFilePathStr.size()-4);
+ char** argv;// 字符串内容(输入)
+ int argc=0;// 字符串个数(输入)
+ ros::init (argc, argv, "UandBdetect");
+ ros::NodeHandle nh;
+ ros::Publisher pcl_pub = nh.advertise ("bin_output", 1);
+ pcl::PointCloud cloud;
+ sensor_msgs::PointCloud2 output;
+ binFilePathStr = binFilePathStr+".pcd";
+ pcl::toROSMsg(*cloud1, output);
+ output.header.frame_id = "world";//this has been done in order to be able to visualize our PointCloud2 message on the RViz visualizer
+ ros::Rate loop_rate(1);
+ pcl_pub.publish(output);
+ ros::spinOnce();
+ loop_rate.sleep();
+
+}
+
+void MyViz::pcd2bin (std::string &in_file, std::string& out_file){
+ //Create a PointCloud value
+ pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
+
+ //Open the PCD file
+ if (pcl::io::loadPCDFile (in_file, *cloud) == -1)
+ {
+ PCL_ERROR ("Couldn't read in_file\n");
+ }
+ //Create & write .bin file
+ std::ofstream bin_file(out_file.c_str(),std::ios::out|std::ios::binary|std::ios::app);
+ if(!bin_file.good()) std::cout<<"Couldn't open "<points.size (); ++i)
+ {
+ bin_file.write(reinterpret_cast(&cloud->points[i].x), sizeof(float));
+ bin_file.write(reinterpret_cast(&cloud->points[i].y), sizeof(float));
+ bin_file.write(reinterpret_cast(&cloud->points[i].z), sizeof(float));
+ }
+
+ bin_file.close();
+}
+
+void MyViz::pcd2ply(std::string &in_file, std::string& out_file){
+ pcl::PointCloud cloud;
+
+ pcl::io::loadPCDFile (in_file, cloud); //修改自己pcd文件所在路径
+ // pcl::PLYWriter writer;
+ // writer.write(out_file, cloud);
+
+ pcl::io::savePLYFileASCII(out_file, cloud);
+}
+
+void MyViz::ply2pcd(std::string &in_file, std::string& out_file){
+ pcl::PointCloud cloud;
+
+ pcl::io::loadPLYFile (in_file, cloud); //修改自己ply文件所在路径
+
+ pcl::io::savePCDFileASCII(out_file, cloud);
+}
+
+void MyViz::ply2bin(std::string &in_file, std::string& out_file){
+ pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
+ if (pcl::io::loadPLYFile (in_file, *cloud) == -1)
+ {
+ PCL_ERROR ("Couldn't read in_file\n");
+ }
+ //Create & write .bin file
+ std::ofstream bin_file(out_file.c_str(),std::ios::out|std::ios::binary|std::ios::app);
+ if(!bin_file.good()) std::cout<<"Couldn't open "<points.size (); ++i)
+ {
+ bin_file.write(reinterpret_cast(&cloud->points[i].x), sizeof(float));
+ bin_file.write(reinterpret_cast(&cloud->points[i].y), sizeof(float));
+ bin_file.write(reinterpret_cast(&cloud->points[i].z), sizeof(float));
+ }
+
+ bin_file.close();
+}
+
+void MyViz::bin2pcd(std::string &in_file, std::string& out_file){
+ std::fstream input(in_file.c_str(), std::ios::in | std::ios::binary);
+ if(!input.good()){
+ std::cerr << "Couldn't read in_file: " << in_file << endl;
+ }
+
+ pcl::PointCloud::Ptr points (new pcl::PointCloud);
+
+ int i;
+ for (i=0; input.good() && !input.eof(); i++) {
+ pcl::PointXYZI point;
+ input.read((char *) &point.x, 3*sizeof(float));
+ input.read((char *) &point.intensity, sizeof(float));
+ points->push_back(point);
+ }
+ input.close();
+
+ pcl::io::savePCDFileASCII(out_file, *points);
+}
+
+void MyViz::bin2ply(std::string &in_file, std::string& out_file){
+ std::fstream input(in_file.c_str(), std::ios::in | std::ios::binary);
+ if(!input.good()){
+ std::cerr << "Couldn't read in_file: " << in_file << endl;
+ }
+
+ pcl::PointCloud::Ptr points (new pcl::PointCloud);
+
+ int i;
+ for (i=0; input.good() && !input.eof(); i++) {
+ pcl::PointXYZI point;
+ input.read((char *) &point.x, 3*sizeof(float));
+ input.read((char *) &point.intensity, sizeof(float));
+ points->push_back(point);
+ }
+ input.close();
+
+ pcl::io::savePLYFileASCII(out_file, *points);
+ // pcl::PLYWriter writer;
+ // writer.write(out_file, *points);
+}
+
+void MyViz::TransformeType(){
+ if(filePath.isEmpty()){
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("Not select File");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ return;
+ }
+ std::string na = find(filePath.toStdString());
+ if(na == "bag")
+ {
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("bag file can't transform from here!!");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ return;
+ }
+ QString SavefileName = QFileDialog::getSaveFileName(nullptr, "Save File", "/home","files(*)");
+ qDebug() << SavefileName;
+ if(SavefileName.isEmpty()){
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("Not select File");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ return;
+ }
+
+ std::string SaveFileNameStr = SavefileName.toStdString();
+ std::string aftertypeName = find(SaveFileNameStr);
+ std::string beforetypeName = find(filePath.toStdString());
+
+ if(beforetypeName == "pcd"){
+ if(aftertypeName == "pcd"){
+ pcl::PointCloud::Ptr cloud (new pcl::PointCloud);
+ //Open the PCD file
+ if (pcl::io::loadPCDFile (filePath.toStdString(), *cloud) == -1)
+ PCL_ERROR ("Couldn't read in_file\n");
+ if(pcl::io::savePCDFileASCII(SaveFileNameStr, *cloud) != -1)
+ std::cout<<" --- save " << SaveFileNameStr << std::endl;
+ }else if(aftertypeName == "ply"){
+ std::string temstr = filePath.toStdString();
+ pcd2ply(temstr, SaveFileNameStr);
+ }else if(aftertypeName == "bin"){
+ std::string temstr = filePath.toStdString();
+ pcd2bin(temstr, SaveFileNameStr);
+ }
+
+ }else if(beforetypeName == "ply"){
+ if(aftertypeName == "pcd"){
+ std::string temstr = filePath.toStdString();
+ ply2pcd(temstr, SaveFileNameStr);
+ }
+ else if(aftertypeName == "ply"){
+ pcl::PointCloud cloud;
+
+ std::string plyFilePathStr = filePath.toStdString();
+ pcl::io::loadPLYFile (plyFilePathStr, cloud); //修改自己ply文件所在路径
+ // pcl::PLYWriter writer;
+ // writer.write(SaveFileNameStr, cloud);
+ if(pcl::io::savePLYFileASCII(SaveFileNameStr, cloud) != -1)
+ std::cout<<" --- save " << SaveFileNameStr << std::endl;
+ }else if(aftertypeName == "bin"){
+ std::string temstr = filePath.toStdString();
+ ply2bin(temstr, SaveFileNameStr);
+ }
+ }else if(beforetypeName == "bin"){
+ if(aftertypeName == "pcd"){
+ std::string temstr = filePath.toStdString();
+ bin2pcd(temstr, SaveFileNameStr);
+ }
+ else if(aftertypeName == "ply"){
+ std::string temstr = filePath.toStdString();
+ bin2ply(temstr, SaveFileNameStr);
+ }
+ // else if(aftertypeName == "bin"){
+ // std::string binFilePathStr = filePath.toStdString();
+ // std::ifstream inFile(binFilePathStr, std::ios::binary);
+ // if (!inFile.is_open())
+ // std::cerr << "Failed to open input binary file." << std::endl;
+ // pcl::PointCloud::Ptr cloud(new pcl::PointCloud);
+ // while (!inFile.eof()){
+ // pcl::PointXYZ point;
+ // inFile.read(reinterpret_cast(&point.x), sizeof(float));
+ // inFile.read(reinterpret_cast(&point.y), sizeof(float));
+ // inFile.read(reinterpret_cast(&point.z), sizeof(float));
+
+ // if (inFile.eof())
+ // break;
+ // cloud->push_back(point);
+ // }
+ // inFile.close();
+ // std:: ofstream bin_file(filePath.toStdString().c_str(),std::ios::out|std::ios::binary|std::ios::app);
+ // if(!bin_file.good()) std::cout<<"Couldn't open "<points.size (); ++i){
+ // bin_file.write((char*)&cloud->points[i].x,3*sizeof(float));
+ // bin_file.write((char*)&cloud->points[i].intensity,sizeof(float));
+ // }
+ // bin_file.close();
+ // }
+ }else{
+ QMessageBox msgBox;
+ msgBox.setWindowTitle("Tips");
+ msgBox.setText("File type error");
+ msgBox.resize(2000, 1000);
+ msgBox.exec();
+ }
+}
+
diff --git a/librviz_tutorial/src/myviz.h b/point_visual/src/myviz.h
similarity index 66%
rename from librviz_tutorial/src/myviz.h
rename to point_visual/src/myviz.h
index 9de4261..9160e0b 100644
--- a/librviz_tutorial/src/myviz.h
+++ b/point_visual/src/myviz.h
@@ -32,20 +32,22 @@
#include
-#include
+#include
#include
-#include
-#include"std_msgs/String.h"
-#include
+#include
+#include "std_msgs/String.h"
+#include
#include
-#include
+#include
#include
#include
#include
-#include
+#include
#include
#include
+#include
+
#include
#include"loginDialog.h"
@@ -56,8 +58,8 @@ class RenderPanel;
class VisualizationManager;
class ToolManager;
class PropertyTreeWidget;
-class ToolManager;
-class PropertyTreeWidget;
+class ViewManager;
+class ViewController;
}
// BEGIN_TUTORIAL
@@ -70,64 +72,93 @@ public:
virtual ~MyViz();
void subCallback(const std_msgs::String& msg);
void pubThread();
- void PlayCircle(double index); // 圆圈线程执行函数
+ void PlayCircles(); // 圆圈线程执行函数
rosbag::View *view;
+ rosbag::View *view_;
+
private Q_SLOTS: // QT信号和槽
void setThickness( int thickness_percent );
void setCellSize( int cell_size_percent );
void setCloudTopic(const QString &newTopic);
- void setLaserTopic(const QString &newTopic);
- void setCloudSize(int cloudsize);
- void setLaserSize(int lasersize);
+ void setCloudSize(const QString& size);
+ void setCloudAlpha(const QString& text);
+ void setLaserAlpha(const QString& laserAlpha);
+ void setLaserTopic(const QString &newTopic);
+ void setLaserSize(const QString & laserSize);
void LaserColorChanged(int index); // 雷达颜色
void GridColorChanged(int index); // 格栅颜色
+ void CloudColorChanged(int index);
void setFixedFrame(const QString &FixedFrame);
void setBackgroundColor(const QString& bg_color); // 背景颜色
void AxesDisplayChanged(int index); // axe
- void CircleDisplayChanged(const QString& text); // 圆圈变化
void Tree_Display(QGridLayout* layout, int index);
void login_button_clicked();
void quit_login_button_clicked();
void slot_select(); // 切换至select模式
void slot_move_camera();
+ void CircleDisplayAdded(); // 增加圆圈按钮
+ void CircleDisplayDeleted(); // 删除圆圈按钮
+ void ViewZero(); // 视角回正
+ void ViewLeft(); // 视角左转
+ void ViewRight(); // 视角右转
+ void ViewTop(); // 视角俯视
// off
double extractDuration(const QByteArray& output);
void selectFile();
void SpeedChanged(int index);
void openFile();
+ void pcdFile();
+ void plyFile();
+ void bin();
+ std::string find(const std::string Path);
+
+ void pcd2ply (std::string &in_file, std::string& out_file);
+ void pcd2bin (std::string &in_file, std::string& out_file);
+ void ply2pcd (std::string &in_file, std::string& out_file);
+ void ply2bin (std::string &in_file, std::string& out_file);
+ void bin2pcd (std::string &in_file, std::string& out_file);
+ void bin2ply (std::string &in_file, std::string& out_file);
+ void TransformeType();
+
private:
rviz::VisualizationManager* manager_; //
rviz::RenderPanel* render_panel_;
rviz::ToolManager* tool_manager_;
+ rviz::ViewManager* view_man_; // 视角总类
+ rviz::ViewController* viewController; // 视角控制类
rviz::Display* grid_;
rviz::Display* cloud;
rviz::Display* laser_;
rviz::Display* axes_display;
rviz::Display* marker_;
- rviz::PropertyTreeWidget* tree_widget_ ;
+ rviz::PropertyTreeWidget* select_tree_widget_ ; // select框
+
+ // rviz::PropertyTreeWidget* view_tree_widget_ ;
ros::NodeHandle nh;
ros::Subscriber sub;
ros::Publisher pub;
std::thread pub_thread;
std::vector color_name; // 颜色的名称集合
+ // std::vector button_name; // 带图标按钮的名称集合
QString color_icon_filename;
+ QString button_icon_filename;
LoginDialog* dlg;
bool landed;
QString cur_fixed_frame;
+ int circle_index;
+ std::map circle_radius;
// off
- bool isclicked;// 用于判断play第几次按下play键
bool ispauseclick;// 用于判断暂停键第几次按下
int count;// 用于记录timeout的次数
bool sliderreleased;// 用于判断是否拖动了进度条
bool playagain;// 用于检测是否多次按下play按钮
bool isthreadplaying;// 用于标识线程是否在运行
- bool abs;// 用于单独开线程?
- bool stored;// 用于存储一次容器,只在第一次play的时候存储容器
+ bool stored = false;// 用于存储一次容器,只在第一次play的时候存储容器
bool is_pause = false;
bool is_reset = false;
bool is_end = false;
@@ -142,17 +173,30 @@ private:
bool threadout = false;
bool ischanged = false;
bool ismoved = false;
- double speed_rate;
+
+ bool sliderpause = false;
+ bool is_next = false;
+ bool is_previous = false;
+ bool flag = false;
+ bool pointcloud2 = false;
+ double speed_rate = 10;
+ QPushButton* play;
QSlider* progress;
QString filePath;
- double duration;
- int remain;
+ QString Topic;
+ QString SavefileName;
+ QString SaveMulfileName;
+
+ double sliderPosition = 0;
int prog_num = 0;
std::vector speed_name;
ros::Publisher scan_pub;
- std::vector indx;// 存储节点信息
- int countbag;// 存储播放的具体位置
- double indxsize;
+ ros::Publisher scan_pubpcd;
+ std::vector indx;// 存储laser节点信息
+ std::vector indxpcd;// 存储cloud节点信息
+ int countbag = 0;// 存储播放的具体位置
+ double indxsize = 0;
+ double indxpcdsize = 0;
int test = 0;
diff --git a/librviz_tutorial/src/node.cpp b/point_visual/src/node.cpp
similarity index 100%
rename from librviz_tutorial/src/node.cpp
rename to point_visual/src/node.cpp
diff --git a/librviz_tutorial/tools/color.cpp b/point_visual/tools/color.cpp
similarity index 100%
rename from librviz_tutorial/tools/color.cpp
rename to point_visual/tools/color.cpp
diff --git a/librviz_tutorial/tools/color.h b/point_visual/tools/color.h
similarity index 100%
rename from librviz_tutorial/tools/color.h
rename to point_visual/tools/color.h