远程控制软件优化(1)

news2024/10/5 14:25:20

远程控制软件优化(1)

在这里插入图片描述

第一版存在以下缺点:

1、四大部分中 Robot States 部分过于简陋,不适合放到论文中

2、Lidar BEV 图像显示效果非常差,显示不全且很稀疏

3、视频流传输延时过高,无法实现远程控制

以上 3 个问题其实都挺棘手的,视频流传输延时的问题已经基本解决

软件界面优化

优化后的界面如下

在这里插入图片描述

不再显示状态信息,转而显示控制信息

1、对界面的布局进行了多次优化调整,整体显得简洁美观

2、设计转向模式的显示,在对应的转向模式下字体会变红,同时图标(Icon)会闪

void MainWindow::showMode0(const QString &mode0)
	{
		ui.front_steer->setVisible(true);
		ui.four_steer->setVisible(true);
		ui.pivot_steer->setVisible(!ui.pivot_steer->isVisible());

		ui.front_label->setStyleSheet("color:black;");
		ui.four_label->setStyleSheet("color:black;");
		ui.pivot_label->setStyleSheet("color:red;");
	}

	void MainWindow::showMode1(const QString &mode1)
	{
		ui.front_steer->setVisible(!ui.front_steer->isVisible());
		ui.four_steer->setVisible(true);
		ui.pivot_steer->setVisible(true);

		ui.front_label->setStyleSheet("color:red;");
		ui.four_label->setStyleSheet("color:black;");
		ui.pivot_label->setStyleSheet("color:black;");
	}

	void MainWindow::showMode2(const QString &mode2)
	{
		ui.front_steer->setVisible(true);
		ui.four_steer->setVisible(!ui.four_steer->isVisible());
		ui.pivot_steer->setVisible(true);

		ui.front_label->setStyleSheet("color:black;");
		ui.four_label->setStyleSheet("color:red;");
		ui.pivot_label->setStyleSheet("color:black;");
	}

3、速度控制通过仪表盘显示,更加直观

仪表盘这部分的实现还是比较有难度的,通过自定义控件实现

#ifndef GAUGEARC_H
#define GAUGEARC_H

/**
 * 圆弧仪表盘控件 作者:feiyangqingyun
 * 1:可设置范围值,支持负数值
 * 2:可设置精确度,最大支持小数点后3位
 * 3:可设置大刻度数量/小刻度数量
 * 4:可设置开始旋转角度/结束旋转角度
 * 5:可设置是否启用动画效果以及动画效果每次移动的步长
 * 6:可设置外圆背景/内圆背景/饼圆三种颜色/刻度尺颜色/文字颜色
 * 7:自适应窗体拉伸,刻度尺和文字自动缩放
 * 8:可自由拓展各种渐变色,各圆的半径
 * 9:指示器样式可选择 圆形指示器 指针指示器 圆角指针指示器 三角形指示器
 */

#include <QWidget>

class GaugeArc : public QWidget
{
	Q_OBJECT	
	Q_ENUMS(PointerStyle)

public:	
	enum PointerStyle {
        PointerStyle_Circle = 0,        //圆形指示器
        PointerStyle_Indicator = 1,     //指针指示器
        PointerStyle_IndicatorR = 2,    //圆角指针指示器
        PointerStyle_Triangle = 3       //三角形指示器
	};

	explicit GaugeArc(QWidget *parent = 0);
	~GaugeArc();

protected:
	void paintEvent(QPaintEvent *);
	void drawArc(QPainter *painter);
	void drawScale(QPainter *painter);
	void drawScaleNum(QPainter *painter);
    void drawPointerCircle(QPainter *painter);
    void drawPointerIndicator(QPainter *painter);
    void drawPointerIndicatorR(QPainter *painter);
    void drawPointerTriangle(QPainter *painter);
	void drawRoundCircle(QPainter *painter);
	void drawCenterCircle(QPainter *painter);
    void drawValue(QPainter *painter);

private:    
    double minValue;                //最小值
    double maxValue;                //最大值
    double value;                   //目标值
    int precision;                  //精确度,小数点后几位

    int scaleMajor;                 //大刻度数量
    int scaleMinor;                 //小刻度数量
    int startAngle;                 //开始旋转角度
    int endAngle;                   //结束旋转角度

    bool animation;                 //是否启用动画显示
    double animationStep;           //动画显示时步长

    QColor arcColor;                //圆弧颜色
    QColor scaleColor;              //刻度尺颜色
    QColor scaleNumColor;           //刻度值颜色
    QColor pointerColor;            //指针颜色
    QColor textColor;               //文字颜色

    PointerStyle pointerStyle;      //指针样式

    bool reverse;                   //是否往回走
    double currentValue;            //当前值
    QTimer *timer;                  //定时器绘制动画

public:	
	double getMinValue()            const;
	double getMaxValue()            const;
    double getValue()               const;
	int getPrecision()              const;

	int getScaleMajor()             const;
	int getScaleMinor()             const;
	int getStartAngle()             const;
	int getEndAngle()               const;

	bool getAnimation()             const;
	double getAnimationStep()       const;

	QColor getArcColor()            const;
	QColor getScaleColor()          const;
    QColor getScaleNumColor()       const;
	QColor getPointerColor()        const;
	QColor getTextColor()           const;

	PointerStyle getPointerStyle()  const;

    QSize sizeHint()                const;
    QSize minimumSizeHint()         const;

public Q_SLOTS:
	//设置范围值
	void setRange(double minValue, double maxValue);
	void setRange(int minValue, int maxValue);

	//设置最大最小值
	void setMinValue(double minValue);
	void setMaxValue(double maxValue);

	//设置目标值
    void setValue(double value);
	void setValue(int value);

	//设置精确度
	void setPrecision(int precision);

	//设置主刻度数量
	void setScaleMajor(int scaleMajor);
	//设置小刻度数量
	void setScaleMinor(int scaleMinor);
	//设置开始旋转角度
	void setStartAngle(int startAngle);
	//设置结束旋转角度
	void setEndAngle(int endAngle);

	//设置是否启用动画显示
	void setAnimation(bool animation);
	//设置动画显示的步长
	void setAnimationStep(double animationStep);

	//设置圆弧颜色
    void setArcColor(const QColor &arcColor);
	//设置刻度尺颜色
    void setScaleColor(const QColor &scaleColor);
    //设置刻度值颜色
    void setScaleNumColor(const QColor &scaleNumColor);
	//设置指针颜色
    void setPointerColor(const QColor &pointerColor);
	//设置文本颜色
    void setTextColor(const QColor &textColor);

	//设置指针样式
    void setPointerStyle(const PointerStyle &pointerStyle);

	void updateValue();

};

#endif //GAUGEARC_H

主要参考下面的博客

Qt 自定义仪表盘控件

Lidar BEV显示优化

可以分为两个问题,一个是稀疏性问题,一个是显示不全问题

稀疏性问题通过 Python 脚本中的分辨率解决,0.01m的分辨率过高,调整至0.05m即可

res=0.05
side_range=(-15., 15.)  
fwd_range=(-15., 15.) 
height_range=(-1.5, 1.5)

显示不全的问题如下图所示

在这里插入图片描述

显示不全的问题也遇到些挫折,推流端和拉流端图像的分辨率都是400x400,但拉流端显示不全

一开始是在 Python 脚本中先将灰度图转彩色图,赋一层 ColorMap 后再推流,但是拉流后显示的颜色和推流端差别很大

考虑是将灰度图转化为彩色图导致一些像素的丢失,尝试先直接推灰度图,拉流端拉取后再进行转换

def callback(lidarmsg):
    lidar = pc2.read_points(lidarmsg)
    img_points = np.array(list(lidar))
    img_arr = point_cloud_2_birdseye(img_points)
    img = img_arr
    # img = cv2.cvtColor(img_arr, cv2.COLOR_GRAY2BGR)
    # img = cv2.applyColorMap(img, cv2.COLORMAP_MAGMA)
    target_size = (400, 400)
    img = cv2.resize(img, target_size, interpolation= cv2.INTER_LINEAR)
    # Transfer OpenCV Image to ROS message
    global bridge
    img_pub = rospy.Publisher('/lidar_bev', Image, queue_size= 10)    
    # img_msg = bridge.cv2_to_imgmsg(img, encoding="bgr8")
    img_msg = bridge.cv2_to_imgmsg(img, encoding="mono8")
    img_pub.publish(img_msg)
   <node pkg="push_video" type="push_ros_bev" name="push_lidar_bev" output="screen" args="lidar_bev">
        <param name="width" type="int" value="400"/>
        <param name="height" type="int" value="400"/>
        <param name="fps" type="int" value="10"/>
        <param name="bit_rate" type="int" value="20"/>
        <param name="gop_size" type="int" value="30"/>
        <param name="pixel_type" type="string" value="Gray"/>
    </node>
    while (ros::ok())
    {
        drag_rtmp->startDrag();
        img = drag_rtmp->getImage();
        if (node_arg == "realsense_dis_rect")
        {
            drag_rtmp->rectifyImg(img);
        }
        if(node_arg == "lidar_bev")
        {
            applyColorMap(img, img, COLORMAP_OCEAN);
        }
        // imshow(node_name, img);
        // waitKey(1);
        img_msg = cv_bridge::CvImage(std_msgs::Header(), sensor_msgs::image_encodings::BGR8, img).toImageMsg();
        pub.publish(*img_msg);
        ros::spinOnce();
        loop.sleep();
    }

经过上述调整后能够较好显示 Lidar BEV 图像

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1630932.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学python的第二十三天

原文链接&#xff1a;Python 图形化界面设计&#xff08;Tkinter&#xff09; - 简书 (jianshu.com) 子窗体&#xff08;Toplevel&#xff09; 直接上代码&#xff1a; # 子窗体 from tkinter import *def newwindow():winNew Toplevel(root)winNew.geometry(320x240)winNe…

C语言-atoi和atof函数的使用

人生应该树立目标&#xff0c;否则你的精力会白白浪费。&#x1f493;&#x1f493;&#x1f493; 目录 •&#x1f319;知识回顾 &#x1f34b;知识点一&#xff1a;atoi函数的使用和实现 • &#x1f330;1.函数介绍 • &#x1f330;2.代码演示 • &#x1f330;3.atoi函数的…

《十一》Qt各种对话框之QInputDialog

QInputDialog QInputDialog 用于方便快捷地获取一个用户输入数据&#xff0c;支持整数 int、浮点数 double、文本 QString 三种数据。按照 QInputDialog 内部的输入控件&#xff0c;又可以分为整数输入控件 QSpinBox、浮点数输入控件 QDoubleSpinBox、单行文本输入控件 QLineE…

AI大模型日报#0428:AI聊天半年涨粉1000万、元象发布多模态XVERSE-V、字节发布视觉ViTamin

导读&#xff1a; 欢迎阅读《AI大模型日报》&#xff0c;内容基于Python爬虫和LLM自动生成。目前采用“文心一言”生成了每条资讯的摘要。AI大模型日报今日要点&#xff1a; 今日&#xff0c;AI大模型领域动作频频&#xff0c;多家科技巨头和初创公司展示了其最新研发成果。快手…

暗区突围如何申请测试资格?暗区突围测试申请的方法轻松掌握

游戏中健康系统与其它射击游戏有很大区别&#xff0c;根据受伤部位、伤势的不同&#xff0c;会有不同的表现。除了头部之外&#xff0c;其它部位如果损坏后继续受到伤害&#xff0c;那么伤害将会分摊到身体其它部位。在暗区内或者暗区外都可以对角色进行治疗&#xff0c;角色不…

FebHost:深入分析企业海外市场选通用域名还是国别域名?

企业想进入海外在线市场&#xff0c;非常重要的一个环节是如何选择一个在线品牌域名&#xff0c;很多企业面临着选择.COM还是国别域名。以下是一些需要考虑的因素。 域名可用性 一个网站的域名可以给人留下深刻的品牌印象。新企业更倾向于选择 .com、.net 和 .org 等标准通用顶…

【哔哩哔哩笔试题汇总】2024-04-28-哔哩哔哩春招笔试题-三语言题解(CPP/Python/Java)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新b站近期的春秋招笔试题汇总&#xff5e; &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497…

由于找不到msvcr120.dll,无法继续执行代码

在日常编程中&#xff0c;缺少关键的msvcr120.dll文件可能会导致代码无法执行&#xff0c;给我们带来不便。针对缺少msvcr120.dll文件的情况&#xff0c;我们可以采取一些有效的解决方法来解决这一问题。通过下载安装或使用Visual C Redistributable工具安装该msvcr120.dll文件…

MySQL/MariaDB 如何查看当前的用户

MySQL 的所有数据库用户信息是存储在 user 数据表中的。 可以在登录成功数据后运行 SQL&#xff1a; MariaDB [(none)]> select user,host from user;就可以查看到数据中的所有用户信息。 MariaDB [(none)]> select user,host from user; ERROR 1046 (3D000): No databa…

K8S哲学 - statefulSet 灰度发布

kubectl get - 获取资源及配置文件 kubectl get resource 【resourceName -oyaml】 kubectl create - 指定镜像创建或者 指定文件创建 kubectl create resource 【resourceName】 --imagemyImage 【-f my.yaml】 kubectl delete kubectl describe resource resourc…

医院敏感文件交互 如何保障安全和效率?

医院会产生大量的敏感文件&#xff0c;这些敏感文件交互时&#xff0c;都需要使用特殊的手段&#xff0c;来保障数据的安全性。 医院的敏感数据主要包括以下几类&#xff1a; 1、患者基本信息&#xff1a;包括患者的姓名、身份证号码、户籍地或现住址、联系方式、文化程度、既…

LeetCode - LCR 179.查找总价格为目标值的两个商品

一. 题目链接 LeetCode - LCR 179. 查找总价格为目标值的两个商品 解法&#xff08;双指针 - 对撞指针&#xff09;&#xff1a; 算法思路&#xff1a; 注意到本题是升序的数组&#xff0c;因此可以用「对撞指针」优化时间复杂度。 算法流程&#xff1a; 初始化left &#…

el-form 表单设置某个参数非必填验证

html <el-form ref"form" :rules"rules"><el-form-item prop"tiktokEmail" label"邮箱" ><el-input v-model"form.tiktokEmail" placeholder"邮箱" ></el-input></el-form-item&…

一篇了解reactor框架特性

一篇了解reactor框架特性 本文档的一些典型的名词如下&#xff1a; Publisher&#xff08;发布者&#xff09;、Subscriber&#xff08;订阅者&#xff09;、Subscription&#xff08;订阅 n.&#xff09;、subscribe&#xff08;订阅 v.&#xff09;。event/signal&#xff0…

一文搞懂 One-Hot Encoding(独热编码)

文章目录 前言 1、独热编码的原理 2、独热编码的分类 3、独热编码的应用 前言 本文将从独热编码的原理、独热编码的分类、独热编码的应用三个方面&#xff0c;来展开介绍独热编码 One-Hot Encoding。 1、独热编码的原理 特征数字化&#xff1a;将分类变量&#xff08;或称为离…

手机测试之-adb

一、Android Debug Bridge 1.1 Android系统主要的目录 1.2 ADB工具介绍 ADB的全称为Android Debug Bridge,就是起到调试桥的作用,是Android SDK里面一个多用途调试工具,通过它可以和Android设备或模拟器通信,借助adb工具,我们可以管理设备或手机模拟器的状态。还可以进行很多…

艾体宝案例 | 使用Redis和Spring Ai构建rag应用程序

随着AI技术的不断进步&#xff0c;开发者面临着如何有效利用现有工具和技术来加速开发过程的挑战。Redis与Spring AI的结合为Java开发者提供了一个强大的平台&#xff0c;以便快速构建并部署响应式AI应用。探索这一整合如何通过简化的开发流程&#xff0c;让开发者能够更专注于…

python——井字棋游戏——登入注册界面

本篇文章只讲解登入和注册页面&#xff0c;在后面的文章中会讲解井字棋游戏&#xff0c;然后把井字棋和登入界面进行连接&#xff0c;整合成一个完整的游戏。 登入注册界面在本篇文章的末尾。 1.实现登入界面 &#xff08;1&#xff09;导入图片 把这张图片存储在与代码路径…

小程序的合同是怎么样写的

​很多商家找第三方做小程序都遭遇到了各种问题&#xff0c;如访问速度慢、服务器关闭、反复收费等。如果当初商家找的是正规的第三方服务商&#xff0c;双方签订了明确的合同条款&#xff0c;出现任何问题后&#xff0c;相信都能够进行解决。下面将具体介绍合同内容&#xff0…

面试高频:什么情况下要用到缓存?如何应对缓存穿透、击穿及雪崩?

一、为什么要使用内存数据库&#xff1f; 我们先来看一下以往单体的Web系统架构图是什么样的&#xff1a; 从图中可以看出&#xff0c;早期的单体架构基本上是以业务为导向&#xff0c;同时用户群体不是很大&#xff0c;这种单体的架构基本上可以应付大多数使用场景。但随着互…