ROS开发:QT插件操控小乌龟

1 安装QT-ROS插件

本插件在安装过程中自行安装QT,无需额外安装。

1.1 Ubuntu16.04 安装步骤

打开Terminal,输入:

sudo add-apt-repository ppa:levi-armstrong/qt-libraries-xenial  
sudo add-apt-repository ppa:levi-armstrong/ppa  
sudo apt-get update && sudo apt-get install qt57creator-plugin-ros

可能需要删除旧的PPA:

sudo add-apt-repository --remove ppa:beineri/opt-qt57-xenial
sudo add-apt-repository --remove ppa:beineri/opt-qt571-xenial

如果您收到错误,请手动删除它:

sudo rm /etc/apt/sources.list.d/beineri-opt-qt57-xenial-xenial.list
sudo rm /etc/apt/sources.list.d/beineri-opt-qt571-xenial-xenial.list

1.2 测试插件

由于插件的更新,不需要安装qtcreator,插件自己依赖安装。
安装完成后在指令行输入qt,按Tab键看自己安装的。如图:
在这里插入图片描述

然后输入存在的qtcreatot-ros回车,qtcreator就启动了,就会看到有关于ros的创建选项了。如图:
在这里插入图片描述

安装有问题可以借鉴:

  1. http://blog.csdn.net/zhangrelay/article/details/52068657
  2. http://blog.csdn.net/u013453604/article/details/52186375
  3. http://blog.csdn.net/qq_30460905/article/details/79034633

2 使用QT编写ROS程序

2.1 实现步骤

  • Terminal新建工作空间catkin_qt,并创建src文件夹
mkdir -p catkin_qt/src
  • Terminal运行插件
qtcreator-ros

然后点击New Project,命名为catkin_qt(工程名称),选择第一步新建的功能包路径catkin_qt,点击Next,Finish。
这样新建的ROS.workspace就在新建的文件夹路径下了。文件夹内如图所示:
在这里插入图片描述

  • 创建测试包rostest

在QT界面下,打开工程目录,右键选择src文件夹,在当前路径下打开Terminal并创建测试功能包:

catkin_create_qt_pkg rostest

注意:需要预先安装建包工具:

sudo apt-get install ros-kinetic-qt-ros

注意catkin_qt/devel/setup.bash路径添加到bash文件中
在这里插入图片描述

  • 修改运行设置

点击Projects,选择Run选型,添加Add Run Step选项,Package和Target选项都选为新建的rostest,如图所示
在这里插入图片描述

  • 设计UI

在UI界面拖放几个按钮,右键更改Text名称为up,down,left,right
然后右键Go to slot…
选择clicked()
这样就新建了4个按键点击事件,如图所示:
在这里插入图片描述
在这里插入图片描述

  • 添加控制函数

打开主窗口qnode.hpp,注释void run(),并添加代码前进后退左转右转指令,如图所示:
在这里插入图片描述
然后写qnode.cpp文件,主要是一处头文件,两处ros通信程序,以及四个控制函数的修改。

/**
 * @file /src/qnode.cpp
 *
 * @brief Ros communication central!
 *
 * @date February 2011
 **/

/*****************************************************************************
** Includes
*****************************************************************************/

#include <ros/ros.h>
#include <ros/network.h>
#include <string>
#include <std_msgs/String.h>
#include <geometry_msgs/Twist.h>    //添加的地方
#include <sstream>
#include "../include/rostest/qnode.hpp"

/*****************************************************************************
** Namespaces
*****************************************************************************/

namespace rostest {

/*****************************************************************************
** Implementation
*****************************************************************************/

QNode::QNode(int argc, char** argv ) :
	init_argc(argc),
	init_argv(argv)
	{}

QNode::~QNode() {
    if(ros::isStarted()) {
      ros::shutdown(); // explicitly needed since we use ros::start();
      ros::waitForShutdown();
    }
	wait();
}

bool QNode::init() {
	ros::init(init_argc,init_argv,"rostest");
	if ( ! ros::master::check() ) {
		return false;
	}
	ros::start(); // explicitly needed since our nodehandle is going out of scope.
	ros::NodeHandle n;
	// Add your ros communications here.
	//添加的地方
    chatter_publisher = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 1000);
	start();
	return true;
}

bool QNode::init(const std::string &master_url, const std::string &host_url) {
	std::map<std::string,std::string> remappings;
	remappings["__master"] = master_url;
	remappings["__hostname"] = host_url;
	ros::init(remappings,"rostest");
	if ( ! ros::master::check() ) {
		return false;
	}
	ros::start(); // explicitly needed since our nodehandle is going out of scope.
	ros::NodeHandle n;
	// Add your ros communications here.
	//添加的地方
    chatter_publisher = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 1000);
	start();
	return true;
}
/*注释run()
void QNode::run() {
	ros::Rate loop_rate(1);
	int count = 0;
	while ( ros::ok() ) {

		std_msgs::String msg;
		std::stringstream ss;
		ss << "hello world " << count;
		msg.data = ss.str();
		chatter_publisher.publish(msg);
		log(Info,std::string("I sent: ")+msg.data);
		ros::spinOnce();
		loop_rate.sleep();
		++count;
	}
	std::cout << "Ros shutdown, proceeding to close the gui." << std::endl;
	Q_EMIT rosShutdown(); // used to signal the gui for a shutdown (useful to roslaunch)
}

*/
//---------------------主要添加的程序--------------------------------
void QNode::up()
{
  ros::Rate loop_rate(1);
  if( ros::ok() )
  {
    geometry_msgs::Twist msg;
    msg.linear.x = 1.0;
    msg.angular.z = 0.0;
    chatter_publisher.publish(msg);

    ros::spinOnce();
    loop_rate.sleep();
  }
}
void QNode::down()
{
  ros::Rate loop_rate(1);
  if( ros::ok() )
  {
    geometry_msgs::Twist msg;
    msg.linear.x = -1.0;
    msg.angular.z = 0.0;
    chatter_publisher.publish(msg);

    ros::spinOnce();
    loop_rate.sleep();
  }
}
void QNode::left()
{
  ros::Rate loop_rate(1);
  if( ros::ok() )
  {
    geometry_msgs::Twist msg;
    msg.linear.x = 0.0;
    msg.angular.z = 1.0;
    chatter_publisher.publish(msg);

    ros::spinOnce();
    loop_rate.sleep();
  }
}
void QNode::right()
{
  ros::Rate loop_rate(1);
  if( ros::ok() )
  {
    geometry_msgs::Twist msg;
    msg.linear.x = 0.0;
    msg.angular.z = -1.0;
    chatter_publisher.publish(msg);

    ros::spinOnce();
    loop_rate.sleep();
  }
}
//--------------------------------------------------------------------
void QNode::log( const LogLevel &level, const std::string &msg) {
	logging_model.insertRows(logging_model.rowCount(),1);
	std::stringstream logging_model_msg;
	switch ( level ) {
		case(Debug) : {
				ROS_DEBUG_STREAM(msg);
				logging_model_msg << "[DEBUG] [" << ros::Time::now() << "]: " << msg;
				break;
		}
		case(Info) : {
				ROS_INFO_STREAM(msg);
				logging_model_msg << "[INFO] [" << ros::Time::now() << "]: " << msg;
				break;
		}
		case(Warn) : {
				ROS_WARN_STREAM(msg);
				logging_model_msg << "[INFO] [" << ros::Time::now() << "]: " << msg;
				break;
		}
		case(Error) : {
				ROS_ERROR_STREAM(msg);
				logging_model_msg << "[ERROR] [" << ros::Time::now() << "]: " << msg;
				break;
		}
		case(Fatal) : {
				ROS_FATAL_STREAM(msg);
				logging_model_msg << "[FATAL] [" << ros::Time::now() << "]: " << msg;
				break;
		}
	}
	QVariant new_row(QString(logging_model_msg.str().c_str()));
	logging_model.setData(logging_model.index(logging_model.rowCount()-1),new_row);
	Q_EMIT loggingUpdated(); // used to readjust the scrollbar
}

}  // namespace rostest

把控制函数添加进按钮触发函数中(设计UI的那四个按键函数)
如图所示:
在这里插入图片描述

  • 编译运行

可以在运行设置Turtlesim_node,如图所示:
在这里插入图片描述
然后点击小锤子编译,完成编译。

  • 若main_window.hpp出现按钮事件函数声明错误:‘slots’ does not name a type

可将private slots:改为 private Q_SLOTS:
主要是因为编译器c++和ros编译器识别不同type。
在这里插入图片描述
在这里插入图片描述

2.2 测试QT程序

1.启动roscore
2.运行qt程序
3.勾选环境变量按钮,点击connect连接
4.使用按键进行控制小乌龟
在这里插入图片描述
在这里插入图片描述

3 参考资料

参考资料:

https://blog.csdn.net/weixin_43377151/article/details/84306914
https://blog.csdn.net/qq_39989653/article/details/79189605
https://blog.csdn.net/LOVE1055259415/article/details/80575432

此部分代码已上传github:
https://github.com/ShuaiWang-Code/ROS-ROBOT/tree/master/QT-ROS

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值