ROS机器人GUI程序开发(蒋程扬)

编程入门 行业动态 更新时间:2024-10-21 17:30:37

ROS<a href=https://www.elefans.com/category/jswz/34/1771107.html style=机器人GUI程序开发(蒋程扬)"/>

ROS机器人GUI程序开发(蒋程扬)


title: ROS机器人GUI程序开发(蒋程扬)-一
date: 2020-07-12 08:35:59
tags: 记录


周末这两天完整的学了一下蒋程扬大佬做的ros的gui开发第二部分。简单做一下记录吧,以便以后能快速的复制粘贴😆,里面包括一些信号和槽函数的链接,编辑回调函数和信号函数,订阅图像话题,实现快速指令。。。

按键速度控制

连接:

connect(ui.horizontalSlider_linear,SIGNAL(valueChanged(int)),this,SLOT(on_horizontalSlider_linear_valueChanged(int)));
connect(ui.horizontalSlider_raw,SIGNAL(valueChanged(int)),this,SLOT(on_horizontalSlider_raw_valueChanged(int)));

槽函数:

void robot_hmi::MainWindow::on_horizontalSlider_linear_valueChanged(int value)
{ui.label_linear->setText(QString::number(value));}void robot_hmi::MainWindow::on_horizontalSlider_raw_valueChanged(int value)
{ui.label_raw->setText(QString::number(value));
}

话题发布:

ros::Publisher cmd_vel_pub;cmd_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",1000);

node与window接口:

public:void set_cmd_vel(char k, float linear, float angular);
void QNode::set_cmd_vel(char k, float linear, float angular)
{std::map<char, std::vector<float>> moveBindings{{'i', {1, 0, 0, 0}},{'o', {1, 0, 0, -1}},{'j', {0, 0, 0, 1}},{'l', {0, 0, 0, -1}},{'u', {1, 0, 0, 1}},{',', {-1, 0, 0, 0}},{'.', {-1, 0, 0, 1}},{'m', {-1, 0, 0, -1}},{'O', {1, -1, 0, 0}},{'I', {1, 0, 0, 0}},{'J', {0, 1, 0, 0}},{'L', {0, -1, 0, 0}},{'U', {1, 1, 0, 0}},{'<', {-1, 0, 0, 0}},{'>', {-1, -1, 0, 0}},{'M', {-1, 1, 0, 0}},{'t', {0, 0, 1, 0}},{'b', {0, 0, -1, 0}},{'k', {0, 0, 0, 0}},{'K', {0, 0, 0, 0}}};char key=k;//计算是往哪个方向float x = moveBindings[key][0];float y = moveBindings[key][1];float z = moveBindings[key][2];float th = moveBindings[key][3];// Update the Twist messagegeometry_msgs::Twist twist;twist.linear.x = x * linear;twist.linear.y = y * linear;twist.linear.z = z * linear;twist.angular.x = 0;twist.angular.y = 0;twist.angular.z = th * angular;// Publish it and resolve any remaining callbackscmd_vel_pub.publish(twist);
}

按钮:

connect(ui.pushButton_u,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));
connect(ui.pushButton_i,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));
connect(ui.pushButton_o,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));
connect(ui.pushButton_j,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));
connect(ui.pushButton_l,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));
connect(ui.pushButton_m,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));
connect(ui.pushButton_bb,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));
connect(ui.pushButton_bc,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));
void robot_hmi::MainWindow::on_pushButton_clicked()
{QPushButton* btn = qobject_cast<QPushButton*> (sender());char k = btn->text().toStdString()[0];// 全向轮模式bool is_all = ui.checkBox_is_all->isChecked();float linear = ui.label_linear->text().toFloat()*0.01;float angular = ui.label_raw->text().toFloat()*0.01;switch (k) {case 'u':qnode.set_cmd_vel(is_all?'U':'u',linear,angular);break;case 'i':qnode.set_cmd_vel(is_all?'I':'i',linear,angular);break;case 'o':qnode.set_cmd_vel(is_all?'O':'o',linear,angular);break;case 'j':qnode.set_cmd_vel(is_all?'J':'j',linear,angular);break;case 'l':qnode.set_cmd_vel(is_all?'L':'l',linear,angular);break;case 'm':qnode.set_cmd_vel(is_all?'M':'m',linear,angular);break;case ',':qnode.set_cmd_vel(is_all?'<':',',linear,angular);break;case '.':qnode.set_cmd_vel(is_all?'>':'.',linear,angular);break;default:break;}
}

速度仪表盘

最小size 300*300

创建两个仪表盘:

CCtrlDashBoard* speed_x_dashBoard;
CCtrlDashBoard* speed_y_dashBorad;
//ui
speed_x_dashBoard = new CCtrlDashBoard(ui.widget_speed_x);
speed_y_dashBorad = new CCtrlDashBoard(ui.widget_speed_y);
speed_x_dashBoard->setGeometry(ui.widget_speed_x->rect());
speed_y_dashBorad->setGeometry(ui.widget_speed_y->rect());
speed_x_dashBoard->setValue(0);
speed_x_dashBoard->setValue(0);

添加订阅者

#include <turtlesim/Pose.h>
ros::Subscriber pose_sub;
// 添加信号
Q_SIGNALS:void speed_vel(float linear_vel,float angular_vel);void pose_callBack(const turtlesim::Pose& msg);pose_sub = n.subscribe("/turtle1/pose",1000,&QNode::pose_callBack,this);

这里注意:emit 改成 Q_EMIT

void QNode::pose_callBack(const turtlesim::Pose& msg)
{Q_EMIT speed_vel(msg.linear_velocity,msg.angular_velocity);
}

此时可以在MainWindow连接这个信号:

connect(&qnode,SIGNAL(speed_vel(float,float)),this,SLOT(on_update_dashBoard(float,float)));void robot_hmi::MainWindow::on_update_dashBoard(float x,float y)
{ui.label_dir_x->setText(x>=0?"forward":"backward");ui.label_dir_y->setText(y>=0?"forward":"backward");speed_x_dashBoard->setValue(abs(x*100));speed_y_dashBoard->setValue(abs(y*100));
}

显示电池电量

添加一些图片

QNode:

void power_vel(float); //信号ros::Subscriber power_sub;void power_callBack(const std_msgs::Float32& msgs);power_sub = n.subscribe("power",1000,&QNode::power_callBack,this);void QNode::power_callBack(const std_msgs::Float32& msg)
{float p = 90.012;//Q_EMIT power_vel(msg.data);Q_EMIT power_vel(p);
}

MainWindow:

void on_update_power(float);connect(&qnode,SIGNAL(power_vel(float)),this,SLOT(on_update_power(float)));void robot_hmi::MainWindow::on_update_power(float value)
{ui.label_power_val->setText(QString::number(value).mid(0.5)+"V");ui.progressBar->setValue(value);
}

订阅图像话题并显示

添加依赖

find_package(catkin REQUIRED COMPONENTS qt_build roscppsensor_msgscv_bridgestd_msgsimage_transport
)

添加头文件

#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <QImage>

UI设计

Label的黑框,Frame的分隔符

声明图像话题订阅者

包括回调函数,信号函数

void image_val(QImage);	//信号哦函数
image_transport::Subscriber image_sub;
void image_callBack(const sensor_msgs::ImageConstPtr& msg);	QImage Mat2QImage(cv::Mat const& src);  //转换算法void QNode::image_callBack(const sensor_msgs::ImageConstPtr& msg)
{cv_bridge::CvImageConstPtr cv_Ptr;cv_Ptr=cv_bridge::toCvCopy(msg,msg->encoding);QImage im = Mat2QImage((cv_Ptr->image));Q_EMIT image_val(im);
}void QNode::sub_image(QString topic_name)
{ros::NodeHandle n;image_transport::ImageTransport it_(n);image_sub = it_.subscribe(topic_name.toStdString(),1000,&QNode::image_callBack,this);
}QImage QNode::Mat2QImage(cv::Mat const& src){QImage dest(src.cols, src.rows, QImage::Format_ARGB32);const float scale = 255.0;if (src.depth() == CV_8U) {if (src.channels() == 1) {for (int i = 0; i < src.rows; ++i) {for (int j = 0; j < src.cols; ++j) {int level = src.at<quint8>(i, j);dest.setPixel(j, i, qRgb(level, level, level));}}} else if (src.channels() == 3) {for (int i = 0; i < src.rows; ++i) {for (int j = 0; j < src.cols; ++j) {cv::Vec3b bgr = src.at<cv::Vec3b>(i, j);dest.setPixel(j, i, qRgb(bgr[2], bgr[1], bgr[0]));}}}} else if (src.depth() == CV_32F) {if (src.channels() == 1) {for (int i = 0; i < src.rows; ++i) {for (int j = 0; j < src.cols; ++j) {int level = scale * src.at<float>(i, j);dest.setPixel(j, i, qRgb(level, level, level));}}} else if (src.channels() == 3) {for (int i = 0; i < src.rows; ++i) {for (int j = 0; j < src.cols; ++j) {cv::Vec3f bgr = scale * src.at<cv::Vec3f>(i, j);dest.setPixel(j, i, qRgb(bgr[2], bgr[1], bgr[0]));}}}}return dest;}

链接信号

void on_update_image(QImage);
void on_sub_image();connect(ui.pushButton_sub_image,SIGNAL(clicked()),this,SLOT(on_sub_image()));void robot_hmi::MainWindow::on_update_image(QImage im)
{ui.label_image->setPixmap(QPixmap::fromImage(im));}void robot_hmi::MainWindow::on_sub_image()
{qnode.sub_image(ui.lineEdit_image->text());;
}

最后实现

没有图像话题,没有显示

运行终端命令实现快捷指令

ui设计

链接按钮信号和槽函数

void on_pushButton_turtlesim_clicked();//槽函数
void on_quick_output();QProcess* turtlesim_cmd;connect(ui.pushButton_turtlesim,SIGNAL(clicked()),this,SLOT(on_pushButton_turtlesim_clicked()));

ui添加回显

void robot_hmi::MainWindow::on_pushButton_turtlesim_clicked()
{turtlesim_cmd = new QProcess;// 运行系统命令行turtlesim_cmd->start("bash");turtlesim_cmd->write(ui.textEdit_turtlesim->toPlainText().toLocal8Bit()+"\n");connect(turtlesim_cmd,SIGNAL(readyReadStandardError()),this,SLOT(on_quick_output()));connect(turtlesim_cmd,SIGNAL(readyReadStandardOutput()),this,SLOT(on_quick_output()));
}void robot_hmi::MainWindow::on_quick_output()
{ui.textEdit_quick_output->append("<font color=\"#FF0000\">" + turtlesim_cmd->readAllStandardError() + "</font>");ui.textEdit_quick_output->append("<font color=\"#FFFFFF\">" + turtlesim_cmd->readAllStandardOutput() + "</font>");
}

最后效果:

更多推荐

ROS机器人GUI程序开发(蒋程扬)

本文发布于:2024-03-12 17:13:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1732001.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:机器人   程序开发   ROS   程扬   GUI

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!