当前位置:网站首页>ROS learning (25) rviz plugin
ROS learning (25) rviz plugin
2022-07-07 01:52:00 【Ice cream with code】
List of articles
Preface
RVIZ yes ROS One provided 3D Visualization tools , As an extensible view tool , You can use the plug-in mechanism to add rich functional modules .RVIZ Laser data commonly used in 、 The visual display of image data is actually an official plug-in .
below , By implementing a speed control plug-in , be familiar with rviz plugin The implementation process of plug-ins .
The source code of this article comes from teacher Hu's book -《ROS Robot development practice 》.
One 、 Function description
The interface is as shown in the figure :
This plug-in uses Qt Development , Contains three input boxes , Topic names 、 Linear velocity and angular velocity .
Two 、 Create Feature Pack
The order is as follows :
catkin_create_pkg rviz_teleop_commander roscpp rviz std_msgs
This feature pack depends on RVIZ, because RVIZ Is based on Qt Developed , So there is no need to list right Qt Dependence .
3、 ... and 、 Code implementation
1、 establish teleop_pad.h file
The contents of the document are as follows :
#ifndef TELEOP_PAD_H
#define TELEOP_PAD_H
// The header file to be included
#ifndef Q_MOC_RUN
#include <ros/ros.h>
#include <ros/console.h>
#include <rviz/panel.h> //plugin Header file of base class
#endif
class QLineEdit;
namespace rviz_teleop_commander
{
// be-all plugin It has to be rviz::Panel Subclasses of
class TeleopPanel: public rviz::Panel
{
// You need to use Qt Signals and slots , All are QObject Subclasses of , So you need to declare Q_OBJECT macro
Q_OBJECT
public:
// Constructors , In the class will be used QWidget To achieve GUI Interface , Here, it is initialized to 0 that will do
TeleopPanel( QWidget* parent = 0 );
// heavy load rviz::Panel Functions in accumulation , Used to hold 、 Load the data in the configuration file , Here we are plugin
// in , The data is topic The name of
virtual void load( const rviz::Config& config );
virtual void save( rviz::Config config ) const;
// Common trough .
public Q_SLOTS:
// When user input topic After naming and pressing enter , The callback uses this slot to create a corresponding named topic publisher
void setTopic( const QString& topic );
// Internal slot .
protected Q_SLOTS:
void sendVel(); // Release the current speed value
void update_Linear_Velocity(); // Update the linear speed value according to the user's input
void update_Angular_Velocity(); // Update the angular velocity value according to the user's input
void updateTopic(); // Update according to user input topic name
// Internal variables .
protected:
// topic name Input box
QLineEdit* output_topic_editor_;
QString output_topic_;
// Linear velocity value input box
QLineEdit* output_topic_editor_1;
QString output_topic_1;
// Angular velocity value input box
QLineEdit* output_topic_editor_2;
QString output_topic_2;
// ROS Of publisher, Used to release speed topic
ros::Publisher velocity_publisher_;
// ROS inode handle
ros::NodeHandle nh_;
// Current saved linear and angular velocity values
float linear_velocity_;
float angular_velocity_;
};
} // end namespace rviz_teleop_commander
#endif // TELEOP_PANEL_H
2、 establish teleop_pad.cpp file
The contents of the document are as follows :
#include <stdio.h>
#include <QPainter>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QTimer>
#include <geometry_msgs/Twist.h>
#include <QDebug>
#include "teleop_pad.h"
namespace rviz_teleop_commander
{
// Constructors , Initialize variable
TeleopPanel::TeleopPanel( QWidget* parent )
: rviz::Panel( parent )
, linear_velocity_( 0 )
, angular_velocity_( 0 )
{
// Create an input topic Named window
QVBoxLayout* topic_layout = new QVBoxLayout;
topic_layout->addWidget( new QLabel( "Teleop Topic:" ));
output_topic_editor_ = new QLineEdit;
topic_layout->addWidget( output_topic_editor_ );
// Create a window for inputting linear velocity
topic_layout->addWidget( new QLabel( "Linear Velocity:" ));
output_topic_editor_1 = new QLineEdit;
topic_layout->addWidget( output_topic_editor_1 );
// Create a window for entering angular velocity
topic_layout->addWidget( new QLabel( "Angular Velocity:" ));
output_topic_editor_2 = new QLineEdit;
topic_layout->addWidget( output_topic_editor_2 );
QHBoxLayout* layout = new QHBoxLayout;
layout->addLayout( topic_layout );
setLayout( layout );
// Create a timer , Used to publish messages regularly
QTimer* output_timer = new QTimer( this );
// Set the connection between the signal and the slot
// Input topic name , After returning , call updateTopic()
connect( output_topic_editor_, SIGNAL( editingFinished() ), this, SLOT( updateTopic() ));
// Enter the linear speed value , After returning , call update_Linear_Velocity()
connect( output_topic_editor_1, SIGNAL( editingFinished() ), this, SLOT( update_Linear_Velocity() ));
// Enter the angular velocity value , After returning , call update_Angular_Velocity()
connect( output_topic_editor_2, SIGNAL( editingFinished() ), this, SLOT( update_Angular_Velocity() ));
// Set the timer's callback function , Call by cycle sendVel()
connect( output_timer, SIGNAL( timeout() ), this, SLOT( sendVel() ));
// Set the period of the timer ,100ms
output_timer->start( 100 );
}
// Update the linear speed value
void TeleopPanel::update_Linear_Velocity()
{
// Get the data in the input box
QString temp_string = output_topic_editor_1->text();
// Convert a string to a floating-point number
float lin = temp_string.toFloat();
// Save the current input value
linear_velocity_ = lin;
}
// Update the angular velocity value
void TeleopPanel::update_Angular_Velocity()
{
QString temp_string = output_topic_editor_2->text();
float ang = temp_string.toFloat() ;
angular_velocity_ = ang;
}
// to update topic name
void TeleopPanel::updateTopic()
{
setTopic( output_topic_editor_->text() );
}
// Set up topic name
void TeleopPanel::setTopic( const QString& new_topic )
{
// Check topic Change or not .
if( new_topic != output_topic_ )
{
output_topic_ = new_topic;
// If the name is empty , Do not publish any information
if( output_topic_ == "" )
{
velocity_publisher_.shutdown();
}
// otherwise , initialization publisher
else
{
velocity_publisher_ = nh_.advertise<geometry_msgs::Twist>( output_topic_.toStdString(), 1 );
}
Q_EMIT configChanged();
}
}
// Release the news
void TeleopPanel::sendVel()
{
if( ros::ok() && velocity_publisher_ )
{
geometry_msgs::Twist msg;
msg.linear.x = linear_velocity_;
msg.linear.y = 0;
msg.linear.z = 0;
msg.angular.x = 0;
msg.angular.y = 0;
msg.angular.z = angular_velocity_;
velocity_publisher_.publish( msg );
}
}
// Overload the function of the parent class
void TeleopPanel::save( rviz::Config config ) const
{
rviz::Panel::save( config );
config.mapSetValue( "Topic", output_topic_ );
}
// Overload the function of the parent class , Load configuration data
void TeleopPanel::load( const rviz::Config& config )
{
rviz::Panel::load( config );
QString topic;
if( config.mapGetString( "Topic", &topic ))
{
output_topic_editor_->setText( topic );
updateTopic();
}
}
} // end namespace rviz_teleop_commander
// Declare that this class is a rviz Plug in for
#include <pluginlib/class_list_macros.h>
PLUGINLIB_EXPORT_CLASS(rviz_teleop_commander::TeleopPanel,rviz::Panel )
// END_TUTORIAL
Four 、 Compile the plug-in
1、 establish plugin Description file for
Under the root directory of the function package , establish plugin Description file for , The file named plugin_description.xml, The contents are as follows :
<library path="lib/librviz_teleop_commander">
<class name="rviz_teleop_commander/TeleopPanel"
type="rviz_teleop_commander::TeleopPanel"
base_class_type="rviz::Panel">
<description>
A panel widget allowing simple diff-drive style robot base control.
</description>
</class>
</library>
2、 modify package.xml file
stay package.xml Add... To the file plugin_description.xml File path , The contents are as follows :
<export>
<rviz plugin="${prefix}/plugin_description.xml"/>
</export>
3、 modify CMakeLists.txt file
Add Compilation Rules , The contents are as follows :
## This plugin includes Qt widgets, so we must include Qt like so:
find_package(Qt5 COMPONENTS Core Widgets REQUIRED)
set(QT_LIBRARIES Qt5::Widgets)
## I prefer the Qt signals and slots to avoid defining "emit", "slots",
## etc because they can conflict with boost signals, so define QT_NO_KEYWORDS here.
add_definitions(-DQT_NO_KEYWORDS)
## Here we specify which header files need to be run through "moc",
## Qt's meta-object compiler.
qt5_wrap_cpp(MOC_FILES
src/teleop_pad.h
)
## Here we specify the list of source files, including the output of
## the previous command which is stored in ``${MOC_FILES}``.
set(SOURCE_FILES
src/teleop_pad.cpp
${
MOC_FILES}
)
## An rviz plugin is just a shared library, so here we declare the
## library to be called ``${PROJECT_NAME}`` (which is
## "rviz_plugin_tutorials", or whatever your version of this project
## is called) and specify the list of source files we collected above
## in ``${SOURCE_FILES}``.
add_library(${
PROJECT_NAME} ${
SOURCE_FILES})
## Link the library with whatever Qt libraries have been defined by
## the ``find_package(Qt4 ...)`` line above, and with whatever libraries
## catkin has included.
##
## Although this puts "rviz_plugin_tutorials" (or whatever you have
## called the project) as the name of the library, cmake knows it is a
## library and names the actual file something like
## "librviz_plugin_tutorials.so", or whatever is appropriate for your
## particular OS.
target_link_libraries(${
PROJECT_NAME} ${
QT_LIBRARIES} ${
catkin_LIBRARIES})
## END_TUTORIAL
## Install rules
install(TARGETS
${
PROJECT_NAME}
ARCHIVE DESTINATION ${
CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${
CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${
CATKIN_PACKAGE_BIN_DESTINATION}
)
install(FILES
plugin_description.xml
DESTINATION ${
CATKIN_PACKAGE_SHARE_DESTINATION})
After making the above changes , You can compile the function package , The order is as follows :
catkin_make --pkg rviz_teleop_commander
5、 ... and 、 Running plug-ins
The first run roscore, The order is as follows :
roscore
function RVIZ, The order is as follows :
rosrun rviz rviz
Click on the Panels Options , choice Add New Panel, You can see the plug-in just created in the plug-in list , Pictured :
Click on OK after , You can see that , The interface of the plug-in , Enter the parameter value , as follows :
Run the command :
rostopic echo /cmd_vel
The effect is as follows :
You can see ROS There are already nodes in the release /cmd_vel The news of the topic .
边栏推荐
- CISP-PTE之命令注入篇
- shell脚本快速统计项目代码行数
- What does front-end processor mean? What is the main function? What is the difference with fortress machine?
- How did partydao turn a tweet into a $200million product Dao in one year
- The difference between Tansig and logsig. Why does BP like to use Tansig
- Yunna - work order management system and process, work order management specification
- ROS学习(24)plugin插件
- Long press the button to execute the function
- Make DIY welding smoke extractor with lighting
- JS es5 peut également créer des constantes?
猜你喜欢
Clickhouse fields are grouped and aggregated, and SQL is queried according to the granularity of any time period
2022/0524/bookstrap
Appium基础 — Appium Inspector定位工具(一)
Let's see how to realize BP neural network in Matlab toolbox
Basic introduction and use of dvajs
Recognition of C language array
一文带你走进【内存泄漏】
CISP-PTE之命令注入篇
Set WordPress pseudo static connection (no pagoda)
JS reverse -- ob confusion and accelerated music that poked the [hornet's nest]
随机推荐
First experience of JSON learning - the third-party jar package realizes bean, list and map to create JSON format
Blue Bridge Cup 2022 13th provincial competition real topic - block painting
Use nodejs to determine which projects are packaged + released
sql中批量删除数据---实体中的集合
Instructions for using the domain analysis tool bloodhound
WCF Foundation
爬虫实战(六):爬笔趣阁小说
ROS学习(23)action通信机制
Box stretch and pull (left-right mode)
2022/0524/bookstrap
Hutool post requests to set the body parameter to JSON data
今日问题-2022/7/4 lambda体中修改String引用类型变量
CISP-PTE之命令注入篇
ROS学习(二十)机器人SLAM功能包——rgbdslam的安装与测试
WCF基金会
uva 1401 dp+Trie
ROS学习(25)rviz plugin插件
图片打水印 缩放 和一个输入流的转换
Domestic images of various languages, software and systems. It is enough to collect this warehouse: Thanks mirror
ZOJ Problem Set – 2563 Long Dominoes 【如压力dp】