# catkin_ws **Repository Path**: qiuros/catkin_ws ## Basic Information - **Project Name**: catkin_ws - **Description**: ros系统的学习项目 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-08-29 - **Last Updated**: 2025-08-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 使用 PyCharm 远程连接 ROS 环境进行开发(包括服务、动作、参数服务器),需要配置远程开发环境、规范 ROS 包结构、正确处理依赖编译等步骤。以下是完整操作流程,适用于 Ubuntu 远程服务器(已安装 ROS Noetic)和本地 PyCharm 专业版(需支持远程开发): ### **前置条件** 1. **远程 Ubuntu 环境**: - 已安装 ROS Noetic(`sudo apt install ros-noetic-desktop-full`)。 - 已创建 Catkin 工作空间(`~/catkin_ws`),并初始化(`catkin_make`)。 - 已安装 SSH 服务(`sudo apt install openssh-server`),且本地能通过 SSH 登录(如 `ssh 用户名@远程IP`)。 - 已安装 Python 依赖:`sudo apt install python3-catkin-tools python3-rosdep`。 2. **本地环境**: - 安装 PyCharm 专业版(社区版不支持远程 SSH 开发)。 - 确保本地与远程网络互通(可 `ping 远程IP` 测试)。 ### **步骤 1:PyCharm 远程连接配置** #### 1.1 配置远程 SSH 解释器 1. 打开 PyCharm,点击 `File → Settings → Project: 项目名 → Python Interpreter`。 2. 点击右上角齿轮图标 → `Add...` → 左侧选择 `SSH Interpreter` → 输入远程信息: - `Host`:远程 Ubuntu 的 IP 地址(如 `192.168.1.100`)。 - `Port`:22(默认 SSH 端口)。 - `Username`:远程 Ubuntu 的用户名(如 `ubuntu`)。 3. 点击 `Next`,选择认证方式(推荐 SSH 密钥,避免每次输入密码): - 若用密码:输入远程用户密码 → `Next`。 - 若用密钥:点击 `Key pair` → 选择本地私钥(如 `~/.ssh/id_rsa`)→ `Next`。 4. 选择远程 Python 解释器路径: - 通常为 `/usr/bin/python3`(系统默认)或 Conda 环境路径(如 `~/miniconda3/envs/ros_env/bin/python3`)。 - 点击 `Finish`,等待 PyCharm 同步远程环境。 #### 1.2 配置远程项目目录映射 1. 点击 `File → Open`,选择本地任意目录作为“项目映射目录”(如 `~/local_ros_projects`)。 2. 点击 `Tools → Deployment → Configuration`,添加远程服务器: - `Name`:自定义(如 `ROS_Remote`)。 - `Type`:`SFTP`。 - `SSH configuration`:选择步骤 1.1 配置的 SSH 连接。 - `Root path`:远程 Catkin 工作空间路径(如 `/home/ubuntu/catkin_ws`)。 - `Web server root URL`:留空。 3. 切换到 `Mappings` 标签: - `Local path`:本地项目目录(如 `~/local_ros_projects`)。 - `Deployment path on server`:`/`(映射到远程 `catkin_ws` 根目录)。 - `Web path`:留空。 4. 点击 `OK`,完成本地与远程 `catkin_ws` 的目录映射(本地修改会自动同步到远程)。 ### **步骤 2:创建 ROS 包并配置依赖** #### 2.1 在远程服务器创建 ROS 包 1. 在 PyCharm 底部打开 `Terminal`(默认已通过 SSH 连接远程),进入远程 `catkin_ws/src` 目录: ```bash cd ~/catkin_ws/src ``` 2. 创建包含服务、动作、参数服务器所需依赖的包(包名示例 `pycharm_ros_demos`): ```bash catkin_create_pkg pycharm_ros_demos rospy std_msgs actionlib actionlib_msgs ``` - 依赖说明:`rospy`(Python 开发)、`std_msgs`(标准消息)、`actionlib`/`actionlib_msgs`(动作通信)。 #### 2.2 配置包的编译规则(关键) 需修改 `CMakeLists.txt` 和 `package.xml`,确保服务(`.srv`)、动作(`.action`)能被编译为 Python 模块。 1. **修改 `package.xml`**(添加依赖声明): 在 `catkin` 后添加: ```xml rospy std_msgs actionlib actionlib_msgs message_generation message_runtime ``` 2. **修改 `CMakeLists.txt`**(配置编译规则): 在 `find_package(catkin REQUIRED COMPONENTS ...)` 中添加依赖: ```cmake find_package(catkin REQUIRED COMPONENTS rospy std_msgs actionlib actionlib_msgs message_generation # 用于生成消息/服务/动作 ) ``` 新增服务和动作的编译配置(放在 `catkin_package()` 之前): ```cmake # 声明服务文件(若有) add_service_files( FILES AddTwoInts.srv # 替换为你的 .srv 文件名 ) # 声明动作文件(若有) add_action_files( FILES CountUntil.action # 替换为你的 .action 文件名 ) # 生成消息/服务/动作对应的 Python 模块 generate_messages( DEPENDENCIES std_msgs actionlib_msgs # 动作依赖 ) # 声明运行时依赖 catkin_package( CATKIN_DEPENDS rospy std_msgs actionlib actionlib_msgs message_runtime ) ``` ### **步骤 3:编写三种通信模式的代码** 在 PyCharm 的项目结构中,远程 `catkin_ws/src/pycharm_ros_demos` 下创建以下目录和文件(本地编辑会自动同步到远程): #### 3.1 服务通信(Service) 1. **创建服务定义文件**: 在包内新建 `srv` 目录,创建 `AddTwoInts.srv`: ```srv int64 a int64 b --- int64 sum ``` 2. **服务端代码**: 在包内新建 `scripts` 目录(存放可执行脚本),创建 `service_server.py`: ```python #!/usr/bin/env python3 import rospy from pycharm_ros_demos.srv import AddTwoInts, AddTwoIntsResponse def handle_add(req): rospy.loginfo(f"收到请求:{req.a} + {req.b}") return AddTwoIntsResponse(req.a + req.b) if __name__ == '__main__': rospy.init_node('add_server') rospy.Service('add_two_ints', AddTwoInts, handle_add) rospy.loginfo("服务已启动,等待请求...") rospy.spin() ``` 3. **客户端代码**: 在 `scripts` 目录创建 `service_client.py`: ```python #!/usr/bin/env python3 import rospy from pycharm_ros_demos.srv import AddTwoInts if __name__ == '__main__': rospy.init_node('add_client') rospy.wait_for_service('add_two_ints') try: add = rospy.ServiceProxy('add_two_ints', AddTwoInts) resp = add(3, 5) # 调用服务,参数 a=3, b=5 rospy.loginfo(f"结果:3 + 5 = {resp.sum}") except rospy.ServiceException as e: rospy.logerr(f"服务调用失败:{e}") ``` #### 3.2 动作通信(Action) 1. **创建动作定义文件**: 在包内新建 `action` 目录,创建 `CountUntil.action`: ```action int32 target float32 period --- bool success int32 count --- int32 current float32 percent ``` 2. **动作服务器代码**: 在 `scripts` 目录创建 `action_server.py`: ```python #!/usr/bin/env python3 import rospy import actionlib from pycharm_ros_demos.msg import CountUntilAction, CountUntilResult, CountUntilFeedback class CountServer: def __init__(self): self.server = actionlib.SimpleActionServer( 'count_until', CountUntilAction, self.execute, auto_start=False ) self.server.start() def execute(self, goal): result = CountUntilResult() feedback = CountUntilFeedback() count = 0 rate = rospy.Rate(1.0 / goal.period) while count < goal.target and not rospy.is_shutdown(): if self.server.is_preempt_requested(): result.success = False self.server.set_preempted(result) return count += 1 feedback.current = count feedback.percent = (count / goal.target) * 100 self.server.publish_feedback(feedback) rate.sleep() result.success = True result.count = count self.server.set_succeeded(result) if __name__ == '__main__': rospy.init_node('count_server') server = CountServer() rospy.spin() ``` 3. **动作客户端代码**: 在 `scripts` 目录创建 `action_client.py`: ```python #!/usr/bin/env python3 import rospy import actionlib from pycharm_ros_demos.msg import CountUntilAction, CountUntilGoal def done_cb(status, result): rospy.loginfo(f"完成:状态={status}, 结果={result.success}") def feedback_cb(feedback): rospy.loginfo(f"反馈:当前={feedback.current}, 进度={feedback.percent}%") if __name__ == '__main__': rospy.init_node('count_client') client = actionlib.SimpleActionClient('count_until', CountUntilAction) client.wait_for_server() goal = CountUntilGoal(target=5, period=1.0) # 计数到5,间隔1秒 client.send_goal(goal, done_cb=done_cb, feedback_cb=feedback_cb) rospy.spin() ``` #### 3.3 参数服务器(Parameter Server) 在 `scripts` 目录创建 `param_demo.py`: ```python #!/usr/bin/env python3 import rospy if __name__ == '__main__': rospy.init_node('param_demo') # 设置参数 rospy.set_param('robot_name', 'PyCharm_Robot') rospy.set_param('max_speed', 0.8) # 获取参数 name = rospy.get_param('robot_name', 'Unknown') speed = rospy.get_param('max_speed', 0.5) rospy.loginfo(f"机器人名称:{name},最大速度:{speed}") # 列出所有参数 rospy.loginfo("所有参数:" + str(rospy.get_param_names())) ``` ### **步骤 4:编译 ROS 包并配置环境** #### 4.1 编译包(生成服务/动作模块) 在 PyCharm 终端(远程)执行: ```bash cd ~/catkin_ws catkin_make # 编译所有包,生成 .srv/.action 对应的 Python 模块 source devel/setup.bash # 刷新环境变量 ``` - 编译成功后,服务/动作的 Python 模块会生成在: `~/catkin_ws/devel/lib/python3/dist-packages/pycharm_ros_demos/srv/` `~/catkin_ws/devel/lib/python3/dist-packages/pycharm_ros_demos/msg/` #### 4.2 解决 PyCharm 无法识别 ROS 模块的问题 PyCharm 可能无法自动识别编译生成的 `srv`/`msg` 模块,需手动添加路径: 1. 在 PyCharm 中,右键项目根目录 → `Mark Directory as → Sources Root`。 2. 点击 `File → Settings → Project: ... → Python Interpreter`,点击解释器后的齿轮 → `Show All...`。 3. 选择远程解释器 → 点击 `Paths` → `+` → 添加远程路径: ``` /home/ubuntu/catkin_ws/devel/lib/python3/dist-packages /opt/ros/noetic/lib/python3/dist-packages # ROS 系统库路径 ``` 4. 点击 `OK`,PyCharm 会重新索引模块,解决 `import pycharm_ros_demos.srv` 报错问题。 ### **步骤 5:运行与调试代码** #### 5.1 启动 ROS 核心(roscore) 在 PyCharm 终端(远程)启动 `roscore`: ```bash roscore # 保持运行,作为 ROS 主节点 ``` #### 5.2 运行服务通信代码 1. **启动服务端**: 新建 PyCharm 终端(远程),执行: ```bash cd ~/catkin_ws source devel/setup.bash rosrun pycharm_ros_demos service_server.py ``` 2. **运行客户端**: 再新建终端,执行: ```bash source devel/setup.bash rosrun pycharm_ros_demos service_client.py ``` 预期输出:客户端终端显示 `结果:3 + 5 = 8`。 #### 5.3 运行动作通信代码 1. **启动动作服务器**: ```bash rosrun pycharm_ros_demos action_server.py ``` 2. **运行动作客户端**: ```bash rosrun pycharm_ros_demos action_client.py ``` 预期输出:客户端终端实时显示进度反馈,最终显示完成状态。 #### 5.4 运行参数服务器代码 ```bash rosrun pycharm_ros_demos param_demo.py ``` 预期输出:显示设置的参数值和所有参数列表。 #### 5.5 调试代码(设置断点) 1. 在 PyCharm 中打开 `service_server.py`,在 `handle_add` 函数内点击行号左侧设置断点。 2. 点击 `Run → Edit Configurations` → `+` → `Python`: - `Name`:`Debug Service Server`。 - `Script path`:远程脚本路径(如 `/home/ubuntu/catkin_ws/src/pycharm_ros_demos/scripts/service_server.py`)。 - `Python interpreter`:选择远程解释器。 - `Environment variables`:添加 `ROS_MASTER_URI=http://localhost:11311`。 3. 点击 `Debug` 按钮启动调试,客户端发送请求时会触发断点,可查看变量和调用栈。 ### **关键注意事项** 1. **权限问题**:确保 `scripts` 目录下的脚本有可执行权限: ```bash chmod +x ~/catkin_ws/src/pycharm_ros_demos/scripts/*.py ``` 2. **依赖缺失**:若编译报错 `No module named ...`,检查 `package.xml` 和 `CMakeLists.txt` 是否添加了对应依赖(如 `message_generation`)。 3. **环境变量**:每次新建终端需执行 `source ~/catkin_ws/devel/setup.bash`,或添加到 `.bashrc` 中: ```bash echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc ``` 通过以上流程,可在 PyCharm 中完整开发 ROS 的服务、动作、参数服务器通信,并利用 PyCharm 的语法提示、断点调试等功能提升开发效率。核心是确保远程环境配置正确、依赖编译完整,以及 PyCharm 能识别 ROS 生成的模块。