环境:ubuntu20.04,pycham+python+designer
1.使用python打开ubuntu终端并输入命令
法一:可以把命令放在一个文本中,使用subprocess模块+gnome-terminal来完成:(其中1为文本文件,内容为roscore)
例子:
import subprocess
command_ros_start = [
'gnome-terminal',
'--disable-factory',
'--',
'bash',
'-c',
'~/桌面/1'
]
subprocess.Popen(command_ros_start)
报错:(终端闪退+报错+包已安装)
... logging to /home/liu/.ros/log/4bd00e18-5a27-11ef-8886-f7dbbc1442c9/roslaunch-liu--Y7000P-IRX9-55726.log Checking log directory for disk usage. This may take a while. Press Ctrl-C to interrupt Done checking log file disk usage. Usage is <1GB. Resource not found: roslaunch The traceback for the exception was written to the log file
解决办法:在命令前面加入“加载 ROS 的环境变量“即source /opt/ros/noetic/setup.bash
备注:可以在一个终端加载多个环境变量,不会覆盖类似:
'gnome-terminal',
'--disable-factory',
'--',
'bash',
'-c',
'source /opt/ros/noetic/setup.bash; '
'source /home/liu/acman/devel/setup.bash;'
完善例子:
import subprocess
command_ros_start = [
'gnome-terminal',
'--disable-factory',
'--',
'bash',
'-c',
'source /opt/ros/noetic/setup.bash;~/桌面/1'
]
subprocess.Popen(command_ros_start)
法二:直接写入命令
subprocess.Popen(['gnome-terminal', '--', 'bash', '-c', 'source /opt/ros/noetic/setup.bash; rosrun turtlesim turtlesim_node; exec bash'])
其中:
1)subprocess.Popen([...])
:这个 Python 函数用于启动一个新的子进程。它接受一个命令列表,并在新的进程中执行该命令。
2)gnome-terminal
:启动一个新的 GNOME 终端窗口
3)--
:告诉 gnome-terminal
,接下来的参数是传递给新启动的 shell 的命令,多条命令时用于分别终端执行。
4)-c '...'
:Bash 的 -c
选项允许提供一个字符串作为命令来执行。在这个字符串中,可以包含多个命令,命令之间用 ;
分隔。
5)source /opt/ros/noetic/setup.bash
:加载 ROS 的环境配置,使得后续命令可以使用 ROS 相关的工具和节点。
6)rosrun turtlesim turtlesim_node
:运行 turtlesim
包中的 turtlesim_node
,这会打开一个带有海龟图形界面的窗口,并开始仿真。
7)exec bash
:最后的 exec bash
确保终端在命令执行完毕后不会关闭。exec
命令用当前 shell 替换正在运行的 shell,这样终端会保持打开状态。
总结:当需要执行多条命令参数设定时,可以
1)将它们合并成一个复合命令,通过 &&
或 ;
分隔每条命令。使用 &&
可以确保前一条命令成功执行后才执行后一条命令,而 ;
则无论前一条命令的执行结果如何都会继续执行后一条命令。
command_ros_start = [
'gnome-terminal',
'--disable-factory',
'--',
'bash',
'-c',
'source /opt/ros/noetic/setup.bash;'
'roscore &&'
'rosrun turtlesim turtlesim_node'
]
2)自己写一个launch文件,类似:
<launch>
<!-- 启动turtlesim节点 -->
<node name="turtlesim_node" pkg="turtlesim" type="turtlesim_node" output="screen"/>
<!-- 启动turtle_teleop_key节点 -->
<node name="turtle_teleop_key" pkg="turtlesim" type="turtle_teleop_key" output="screen"/>
</launch>
然后运行命令roslaunch+pkg包名(功能包)+launch文件名 ,如:
roslaunch ui_learning fangzhen.launch。
3)如果是需要多个终端执行多个命令时,可以类似下面,创建两个命令函数,在一个def中调用,先后执行。
command_2dmap_start = [
'gnome-terminal',
'--disable-factory',
'--',
'bash',
'-c',
'source /opt/ros/noetic/setup.bash; '
'source /home/liu/acman/devel/setup.bash;'
'roslaunch turn_on_wheeltec_robot mapping.launch ;'
]
command_rviz_start = [
'gnome-terminal',
'--disable-factory',
'--',
'bash',
'-c',
'source /opt/ros/noetic/setup.bash; '
'rviz;'
]
def map_start(self):
subprocess.Popen(command_2dmap_start)
subprocess.Popen(command_rviz_start)
2.模块导入:
1)import subprocess:
- `subprocess` 模块用于生成新进程、连接到它们的输入/输出/错误管道,以及获取它们的返回码。
- 可以通过这个模块来运行系统命令或其他可执行程序。
2)import rospy:
- `rospy` 是 ROS 的 Python 客户端库,提供了 ROS 节点与 ROS 生态系统中的其他部分(如主题、服务、参数服务器等)进行交互的接口。
- 通过它,可以编写和运行 ROS 节点。
3)import time:
- `time` 模块提供了与时间相关的各种函数,比如获取当前时间、暂停程序执行一段时间等。
4)import sys:
- `sys` 模块提供了一些与 Python 解释器和系统交互的功能,比如访问命令行参数、控制解释器退出等。
5)from PyQt5.QtWidgets import QApplication, QMainWindow:
- `PyQt5` 是一个用于在 Python 中创建图形用户界面的库,基于 Qt 框架。
- `QApplication` 是 GUI 应用程序的入口点,管理应用程序的控制流和主要设置。
- `QMainWindow` 是 PyQt 中的主窗口类,可以包含菜单栏、工具栏、状态栏等。
6)from ui import Ui_Dialog :
- 这一行从`ui`模块中导入了一个名为`Ui_Dialog`的类。
- `Ui_Dialog` 通常是在 Qt Designer 中设计的 UI,然后通过工具(如 `pyuic5`)转换成 Python 类。
- 这个类定义了 GUI 的布局和控件,并可以被进一步扩展以添加逻辑功能。
7 )import runpy:
- `runpy` 模块提供了一些函数,可以用于动态加载和运行 Python 模块或脚本。
- 通常用于在不直接导入模块的情况下运行 Python 代码。
8)from geometry_msgs.msg import Twist:
- `geometry_msgs.msg` 是 ROS 中定义的一组消息类型,用于表示几何信息。
- `Twist` 消息类型表示一个自由度中的线性和角速度,用于在机器人运动控制中广泛使用。
9)import os:
- `os` 模块提供了一些与操作系统进行交互的功能,比如文件和目录的操作、环境变量的获取和设置等。
备注:如果在整个文件中有多个未导入的模块,可以按 Alt+Enter
后选择“Optimize Imports”,这将自动为你导入所有缺少的模块并删除未使用的导入。
经验补充:
1) QAction
对象没有 clicked
信号,如果想要实现 QAction
的点击事件,连接它的 triggered
信号,triggered
信号在 QAction
被触发时(例如通过点击、快捷键等)发射。
例子:
(错误示范)self.action.clicked.connect(self.stop)
(正确) self.action.triggered.connect(self.stop)
2)每次在designer中修改后,需要保存并且重新生成pycharm中的ui转py文件。