# 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 生成的模块。