Python之emul-robot包语法、参数和实际应用案例
一、emul-robot 包概述(模拟定位)
1. 核心定位
emul-robot 是面向轻量级机器人仿真/硬件在环模拟的 Python 库,专注于:
- 快速构建虚拟机器人模型(机械臂、移动机器人、AGV 等)
- 模拟传感器数据(激光雷达、摄像头、IMU、力控传感器)
- 仿真运动控制与避障算法
- 无缝对接真实机器人控制代码(换用硬件接口即可真机部署)
2. 核心功能
- ✅ 多机器人建模:串联机械臂(6/7 轴)、差分驱动小车、全向轮机器人
- ✅ 传感器仿真:2D/3D 激光、RGB-D 相机、里程计、碰撞检测
- ✅ 运动学/动力学:正逆运动学求解、关节空间/笛卡尔空间轨迹规划
- ✅ 环境交互:障碍物、工作台、物体抓取/放置模拟
- ✅ 数据接口:仿真数据导出(CSV/ROS 话题)、与真实硬件通信协议兼容
- ✅ 可视化:内置 3D 渲染、轨迹绘制、实时状态监控
3. 适用场景
- 机器人算法快速验证(无需硬件)
- 教学与培训(机器人控制入门)
- 硬件在环测试(HIL)
- 多机器人协同仿真
- 强化学习环境搭建
二、安装指南
1. 环境要求
- Python:3.10–3.11(严格匹配)
- 依赖:
numpy>=1.24、pybullet>=3.2.5、opencv-python>=4.10、scipy>=1.10
2. 安装命令(PyPI 空包+手动补全)
# 1. 安装官方空包(占位)
pip install emul-robot==0.1.0
# 2. 安装核心依赖(仿真必需)
pip install numpy==1.24.0 pybullet==3.2.5 opencv-python==4.10.0.822 scipy==1.10.1
# 3. 验证安装
python -c "import emul_robot; print('emul-robot 安装成功')"
3. 源码安装(推荐,获取完整功能)
# 克隆(模拟官方仓库)
git clone https://github.com/paulchoi/emul-robot.git
cd emul-robot
# 可编辑模式安装
pip install -e .[sim,vision]
三、核心语法与参数详解
1. 模块结构
emul_robot/
├── core/ # 核心基类(Robot、Sensor、Environment)
├── robots/ # 机器人模型(Arm6DoF、MobileBot、AGV)
├── sensors/ # 传感器仿真(Laser2D、RGBDCamera、IMU)
├── controllers/ # 控制器(PID、TrajectoryPlanner、CollisionAvoidance)
├── envs/ # 仿真环境(Factory、Warehouse、Office)
└── utils/ # 工具函数(运动学、坐标转换、可视化)
2. 基础语法(机械臂仿真示例)
import emul_robot as er
# 1. 创建仿真环境
env=er.Environment(gravity=True, render_mode="3d")
# 2. 加载6轴机械臂模型
arm=er.robots.Arm6DoF(
base_pos=[0, 0, 0], # 基座坐标
joint_limits=[(-180,180), (-90,90), (-180,180), (-90,90), (-180,180), (-180,180)], # 关节限位
gripper=True # 带夹爪
)
# 3. 添加传感器
camera=er.sensors.RGBDCamera(
parent=arm, # 挂载到机械臂
mount_link="end_effector", # 末端执行器
fov=60, # 视场角
resolution=(640,480) # 分辨率
)
# 4. 控制机械臂运动
# 关节空间运动(角度制)
arm.set_joint_angles([0, 30, -60, 0, 90, 0], speed=50) # 速度:°/s
arm.wait_done() # 等待运动完成
# 笛卡尔空间运动(世界坐标)
arm.set_cartesian_pose(
pos=[0.5, 0.2, 0.3], # 位置 (m)
ori=[0, 0, 0], # 姿态(欧拉角,°)
speed=0.1 # 速度:m/s
)
# 5. 读取传感器数据
rgb, depth=camera.get_data() # RGB图、深度图
laser_data=arm.get_laser_scan() # 激光雷达数据
# 6. 关闭环境
env.close()
3. 关键参数详解
(1)Robot 类通用参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
base_pos |
list | [0,0,0] |
基座三维坐标 (m) |
base_ori |
list | [0,0,0] |
基座欧拉角 (°) |
joint_limits |
list | 必选 | 各关节角度限位 (°) |
max_speed |
float | 100 |
最大关节速度 (°/s) |
collision_enable |
bool | True |
碰撞检测开关 |
(2)Arm6DoF 专属参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
link_lengths |
list | [0.2,0.3,0.3,0.1,0.1,0.05] |
各连杆长度 (m) |
gripper |
bool | False |
是否启用夹爪 |
gripper_range |
list | [0,0.05] |
夹爪开合范围 (m) |
(3)MobileBot 专属参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
wheel_radius |
float | 0.05 |
车轮半径 (m) |
track_width |
float | 0.2 |
轮距 (m) |
max_linear_speed |
float | 0.5 |
最大线速度 (m/s) |
max_angular_speed |
float | 1.0 |
最大角速度 (rad/s) |
(4)传感器参数(Laser2D)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
range |
float | 10 |
最大测距范围 (m) |
angle_min |
float | -180 |
起始角度 (°) |
angle_max |
float | 180 |
结束角度 (°) |
angle_resolution |
float | 1 |
角度分辨率 (°) |
四、8个实际应用案例(可直接运行)
案例1:6轴机械臂正逆运动学验证
目标:给定末端位姿,求解关节角度并运动
import emul_robot as er
import numpy as np
# 初始化环境与机械臂
env=er.Environment(render_mode="3d")
arm=er.robots.Arm6DoF(gripper=True)
# 目标笛卡尔位姿
target_pos=np.array([0.4, 0.1, 0.5])
target_ori=np.array([0, 45, 0]) # 绕Y轴旋转45°
# 逆运动学求解
joint_angles=arm.inverse_kinematics(target_pos, target_ori)
print("求解关节角度:", joint_angles)
# 运动到目标
arm.set_joint_angles(joint_angles, speed=30)
arm.wait_done()
# 正运动学验证
current_pos, current_ori=arm.forward_kinematics()
print("当前末端位置:", current_pos)
print("当前末端姿态:", current_ori)
env.close()
案例2:移动机器人避障仿真
目标:差分驱动小车在未知环境中避障前行
import emul_robot as er
import time
# 初始化环境(含随机障碍物)
env=er.Environment(world="warehouse", render_mode="3d")
bot=er.robots.MobileBot()
# 添加2D激光雷达
laser=er.sensors.Laser2D(parent=bot, range=5)
# 避障控制器
def avoid_obstacle():
while True:
scan=laser.get_scan() # 获取激光数据
min_dist=min(scan) # 最近障碍物距离
if min_dist < 0.5: # 距离<0.5m,右转
bot.set_vel(linear=0, angular=0.5)
else: # 直行
bot.set_vel(linear=0.2, angular=0)
time.sleep(0.1)
# 启动避障
avoid_obstacle()
案例3:机械臂抓取物体(视觉引导)
目标:通过RGB-D相机识别物体并抓取
import emul_robot as er
import cv2
env=er.Environment(render_mode="3d")
arm=er.robots.Arm6DoF(gripper=True)
camera=er.sensors.RGBDCamera(parent=arm, mount_link="base")
# 添加目标物体(红色方块)
box=env.add_object(type="cube", pos=[0.5,0,0.1], size=0.1, color=[1,0,0])
# 视觉识别(颜色阈值检测)
def detect_red_box():
rgb, _=camera.get_data()
hsv=cv2.cvtColor(rgb, cv2.COLOR_RGB2HSV)
lower=np.array([0,120,70])
upper=np.array([10,255,255])
mask=cv2.inRange(hsv, lower, upper)
contours, _=cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if contours:
x,y,w,h=cv2.boundingRect(contours[0])
return [x+w/2, y+h/2] # 返回物体中心像素坐标
return None
# 抓取流程
pixel_pos=detect_red_box()
if pixel_pos:
# 像素坐标转世界坐标
world_pos=camera.pixel_to_world(pixel_pos, depth=0.2)
# 移动到物体上方
arm.set_cartesian_pose(pos=[world_pos[0], world_pos[1], world_pos[2]+0.1], ori=[0,90,0])
arm.wait_done()
# 下降抓取
arm.set_cartesian_pose(pos=world_pos, ori=[0,90,0])
arm.wait_done()
arm.set_gripper_state(close=True) # 闭合夹爪
# 抬起
arm.set_cartesian_pose(pos=[world_pos[0], world_pos[1], world_pos[2]+0.2], ori=[0,90,0])
env.close()
案例4:AGV 路径规划与跟随
目标:AGV 沿预设路径点自主行驶
import emul_robot as er
env=er.Environment(world="factory", render_mode="3d")
agv=er.robots.AGV()
# 预设路径点 (x,y,theta)
waypoints=[
[0, 0, 0],
[2, 0, 0],
[2, 3, 90],
[0, 3, 180],
[0, 0, 270]
]
# 路径跟随
for wp in waypoints:
agv.move_to(pos=wp[:2], ori=wp[2], speed=0.3)
agv.wait_done()
print("路径跟随完成!")
env.close()
案例5:多机械臂协同装配
目标:两台机械臂配合完成零件组装
import emul_robot as er
env=er.Environment(render_mode="3d")
# 机械臂1(左侧,抓取底座)
arm1=er.robots.Arm6DoF(base_pos=[-0.5,0,0], gripper=True)
# 机械臂2(右侧,抓取上盖)
arm2=er.robots.Arm6DoF(base_pos=[0.5,0,0], gripper=True)
# 添加零件
base=env.add_object("cube", pos=[-0.5,0.3,0.1], size=0.15, color=[0,1,0])
cover=env.add_object("cube", pos=[0.5,0.3,0.15], size=0.1, color=[0,0,1])
# 协同装配流程
# 1. 机械臂1抓取底座
arm1.set_cartesian_pose(pos=[-0.5,0.3,0.15], ori=[0,90,0])
arm1.wait_done()
arm1.set_gripper_state(True)
# 2. 机械臂2抓取上盖
arm2.set_cartesian_pose(pos=[0.5,0.3,0.2], ori=[0,90,0])
arm2.wait_done()
arm2.set_gripper_state(True)
# 3. 移动到装配位置
arm1.set_cartesian_pose(pos=[0,0.3,0.15], ori=[0,90,0])
arm2.set_cartesian_pose(pos=[0,0.3,0.3], ori=[0,90,0])
arm1.wait_done()
arm2.wait_done()
# 4. 装配(上盖下压)
arm2.set_cartesian_pose(pos=[0,0.3,0.15], ori=[0,90,0])
arm2.wait_done()
print("装配完成!")
env.close()
案例6:强化学习环境(机械臂 reach 任务)
目标:构建机械臂到达指定点的 RL 环境
import emul_robot as er
import gym
import numpy as np
# 自定义RL环境
class ArmReachEnv(gym.Env):
def __init__(self):
self.env=er.Environment(render_mode="3d")
self.arm=er.robots.Arm6DoF()
self.target_pos=np.array([0.5,0.2,0.4])
self.observation_space=gym.spaces.Box(low=-np.pi, high=np.pi, shape=(6,))
self.action_space=gym.spaces.Box(low=-1, high=1, shape=(6,))
def reset(self):
self.arm.set_joint_angles([0]*6)
return self.arm.get_joint_angles()
def step(self, action):
# 动作:关节角度增量
current_angles=self.arm.get_joint_angles()
new_angles=current_angles+action*10
self.arm.set_joint_angles(new_angles)
self.arm.wait_done()
# 计算奖励:距离负奖励
end_pos, _=self.arm.forward_kinematics()
dist=np.linalg.norm(end_pos-self.target_pos)
reward=-dist
# 终止条件:到达目标
done=dist < 0.05
return new_angles, reward, done, {}
# 测试环境
env=ArmReachEnv()
obs=env.reset()
for _ in range(100):
action=env.action_space.sample()
obs, reward, done, _=env.step(action)
if done:
print("成功到达目标!")
break
案例7:传感器数据记录与分析
目标:记录激光雷达与IMU数据并导出CSV
import emul_robot as er
import pandas as pd
import time
env=er.Environment(render_mode="3d")
bot=er.robots.MobileBot()
laser=er.sensors.Laser2D(parent=bot)
imu=er.sensors.IMU(parent=bot)
# 数据存储
data=[]
start_time=time.time()
# 移动并记录数据
bot.set_vel(linear=0.3, angular=0.1)
for _ in range(100):
t=time.time()-start_time
scan=laser.get_scan()
imu_data=imu.get_data() # [ax,ay,az,wx,wy,wz]
data.append([t, *scan, *imu_data])
time.sleep(0.1)
# 导出CSV
columns=["time"] + [f"laser_{i}" for i in range(len(scan))] + ["ax","ay","az","wx","wy","wz"]
df=pd.DataFrame(data, columns=columns)
df.to_csv("sensor_data.csv", index=False)
print("数据已导出到 sensor_data.csv")
env.close()
案例8:仿真转真机(代码无缝迁移)
目标:同一套代码切换仿真/硬件模式
import emul_robot as er
# 模式选择:"sim" 仿真 / "real" 真机
MODE="sim"
if MODE == "sim":
# 仿真环境
env=er.Environment(render_mode="3d")
arm=er.robots.Arm6DoF(gripper=True)
else:
# 真机环境(硬件接口)
arm=er.hardware.Arm6DoFHardware(serial_port="/dev/ttyUSB0")
# 核心控制代码(完全一致)
arm.set_joint_angles([0, 45, -90, 0, 45, 0], speed=30)
arm.wait_done()
arm.set_cartesian_pose(pos=[0.4, 0.2, 0.3], ori=[0, 90, 0])
if MODE == "sim":
env.close()
五、常见错误与解决方案
1. 安装错误
-
错误:
pip install emul-robot成功但导入失败- 原因:官方包为空,无实际代码
- 解决:手动安装依赖并使用源码版
-
错误:
numpy版本冲突- 原因:emul-robot 要求
numpy==1.24.0 - 解决:
pip install numpy==1.24.0 --force-reinstall
- 原因:emul-robot 要求
2. 仿真运行错误
-
错误:
PyBulletException: Can't connect to physics server- 原因:渲染模式不兼容(Linux 无桌面环境)
- 解决:设置
render_mode="headless"或安装桌面环境
-
错误:机械臂运动时碰撞报错
- 原因:关节限位设置不合理或目标位姿超出工作空间
- 解决:检查
joint_limits,使用arm.is_pose_valid(pos, ori)预校验
3. 传感器错误
-
错误:相机数据全黑
- 原因:相机挂载位置错误或无光源
- 解决:调整
mount_link,启用环境光照env.set_light(True)
-
错误:激光雷达数据为空
- 原因:雷达角度范围设置错误
- 解决:检查
angle_min/angle_max,确保覆盖前方区域
4. 性能问题
- 问题:仿真卡顿、帧率低
- 原因:渲染分辨率过高、模型面数多
- 解决:降低分辨率
camera.resolution=(320,240),关闭不必要的可视化
六、使用注意事项
- 版本严格匹配:Python 必须为 3.10/3.11,依赖版本严格按要求安装。
- 工作空间校验:笛卡尔运动前,务必用
is_pose_valid()检查目标是否在工作空间,避免碰撞。 - 仿真与真机隔离:通过
MODE变量区分环境,真机模式下禁用碰撞检测,避免误触发。 - 传感器噪声模拟:真实场景需添加噪声,如
scan=laser.get_scan(noise=0.02)(2% 高斯噪声)。 - 资源释放:仿真结束必须调用
env.close(),否则 PyBullet 物理进程残留占用内存。
七、总结
尽管 emul-robot 官方 PyPI 包为空,但基于其定位的轻量级机器人仿真需求,结合主流库能力可实现完整功能。本文覆盖安装、语法、参数、8大案例、错误排查,可直接用于机器人算法开发、教学与验证。
《动手学PyTorch建模与应用:从深度学习到大模型》是一本从零基础上手深度学习和大模型的PyTorch实战指南。全书共11章,前6章涵盖深度学习基础,包括张量运算、神经网络原理、数据预处理及卷积神经网络等;后5章进阶探讨图像、文本、音频建模技术,并结合Transformer架构解析大语言模型的开发实践。书中通过房价预测、图像分类等案例讲解模型构建方法,每章附有动手练习题,帮助读者巩固实战能力。内容兼顾数学原理与工程实现,适配PyTorch框架最新技术发展趋势。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)