在Isaac Sim中构建机器人工作单元

学习在Isaac Sim中搭建完整的机器人工作单元,包括机械臂、传送带、传感器和工件的集成配置。

Isaac Sim 工作单元 机械臂 传送带 仿真
在Isaac Sim中构建机器人工作单元

在Isaac Sim中构建机器人工作单元

一个完整的机器人工作单元(Work Cell)包括机械臂、末端执行器、传感器、传送带等组件。本文教你在Isaac Sim中搭建这样的系统。

工作单元组成

组件功能Isaac Sim资源
机械臂执行操作Franka / UR5 / UR10
夹爪抓取物体Robotiq 2F-85
相机视觉感知RGB-D Camera
传送带物料输送Conveyor
工件操作对象自定义模型

搭建机械臂

from isaacsim.core import World
from isaacsim.assets import FrankaRobot

world = World()
world.scene.add_default_ground_plane()

# 添加Franka机械臂
franka = FrankaRobot(
    prim_path="/World/Franka",
    name="franka",
    position=np.array([0.0, 0.0, 0.0])
)
world.scene.add(franka)
world.reset()

添加夹爪

from isaacsim.assets import RobotiqGripper

# 添加Robotiq 2F-85夹爪
gripper = RobotiqGripper(
    prim_path="/World/Franka/gripper",
    name="gripper"
)

# 连接到机械臂末端
franka.attach_gripper(gripper)

# 控制夹爪开合
gripper.open()   # 完全打开
gripper.close()  # 完全闭合
gripper.set_position(0.02)  # 指定开合距离(米)

配置传送带

from isaacsim.core.utils.prims import add_conveyor

# 创建传送带
conveyor = add_conveyor(
    prim_path="/World/Conveyor",
    position=np.array([0.5, 0.0, 0.0]),
    orientation=np.array([0.0, 0.0, 0.707, 0.707]),  # 旋转90度
    length=2.0,
    width=0.3,
    speed=0.1  # 米/秒
)

# 控制传送带
conveyor.set_speed(0.15)  # 调整速度
conveyor.stop()           # 停止
conveyor.start()          # 启动

添加相机传感器

from isaacsim.core.utils.prims import add_camera

# 添加顶部相机(俯视工作单元)
top_camera = add_camera(
    prim_path="/World/TopCamera",
    position=np.array([0.0, 0.0, 1.5]),
    look_at=np.array([0.0, 0.0, 0.0])
)
top_camera.set_resolution(1280, 720)

# 添加腕部相机(跟随机械臂)
wrist_camera = add_camera(
    prim_path="/World/Franka/gripper/camera",
    position=np.array([0.0, 0.0, 0.1]),
    look_at=np.array([0.1, 0.0, 0.0])
)
wrist_camera.set_resolution(640, 480)

生成工件

from isaacsim.core.utils.prims import add_cube, add_sphere

def spawn_workpiece(world, position):
    """在传送带上生成工件"""
    import random
    shape = random.choice(["cube", "sphere"])

    if shape == "cube":
        size = random.uniform(0.03, 0.06)
        obj = add_cube(
            prim_path=f"/World/Workpiece_{world.current_step}",
            size=size,
            color=np.array([random.random(), random.random(), random.random()]),
            position=position
        )
    else:
        radius = random.uniform(0.02, 0.04)
        obj = add_sphere(
            prim_path=f"/World/Workpiece_{world.current_step}",
            radius=radius,
            color=np.array([random.random(), random.random(), random.random()]),
            position=position
        )

    # 设置为刚体
    world.set_rigid_body(obj, mass=0.1)
    return obj

# 在仿真循环中定期生成工件
spawn_timer = 0
while simulation_app.is_running():
    world.step(render=True)

    spawn_timer += 1
    if spawn_timer % 120 == 0:  # 每5秒生成一个
        spawn_workpiece(world, np.array([0.5, -0.8, 0.05]))

完整的仿真循环

def main():
    # 初始化
    world = World()
    setup_work_cell(world)
    world.reset()

    # 控制状态
    state = "IDLE"
    target_object = None

    while simulation_app.is_running():
        world.step(render=True)

        # 获取相机图像
        image = top_camera.get_rgb()

        # 检测工件
        objects = detect_objects(image)

        if state == "IDLE" and objects:
            target_object = objects[0]
            state = "APPROACHING"

        elif state == "APPROACHING":
            # 规划并执行抓取
            trajectory = plan_grasp(target_object)
            franka.follow_trajectory(trajectory)
            state = "GRASPING"

        elif state == "GRASPING":
            gripper.close()
            state = "LIFTING"

        elif state == "LIFTING":
            # 抬升到放置位置
            franka.move_to(np.array([0.0, 0.5, 0.3]))
            state = "PLACING"

        elif state == "PLACING":
            gripper.open()
            state = "IDLE"

if __name__ == "__main__":
    main()

FAQ

如何导入自定义3D模型?

Isaac Sim支持USD、OBJ、FBX格式。使用add_reference_from_usd()导入自定义模型。

传送带速度不稳定怎么办?

检查传送带的物理参数设置,确保摩擦系数合理。也可以增加传送带的刚度参数。

多个机械臂如何协同?

每个机械臂作为独立的Prim,通过ROS2 Action进行协调控制。