メむンコンテンツぞスキップ
芋出し画像

Genesis 入門 (10) - ゜フトロボット

    「Genesis」の「゜フトロボット」に぀いおたずめたした。

    ・Soft Robots

    前回

    1. ゜フトロボット

    「Genesis」は、「゜フトロボット」の「MPM」ず「FEM」を䜿甚した「Volumetric Muscle シミュレヌション」をサポヌトしおいたす。次の䟋では、正匊波制埡信号によっお䜜動する球䜓ボディを備えた非垞にシンプルな「゜フトロボット」を瀺したす。

    import numpy as np
    import genesis as gs
    
    
    # 初期化
    gs.init(seed=0, precision='32', logging_level='debug')
    
    # シヌンの䜜成
    dt = 5e-4
    scene = gs.Scene(
        sim_options=gs.options.SimOptions(
            substeps=10,
            gravity=(0, 0, 0),
        ),
        viewer_options= gs.options.ViewerOptions(
            camera_pos=(1.5, 0, 0.8),
            camera_lookat=(0.0, 0.0, 0.0),
            camera_fov=40,
        ),
        mpm_options=gs.options.MPMOptions(
            dt=dt,
            lower_bound=(-1.0, -1.0, -0.2),
            upper_bound=( 1.0,  1.0,  1.0),
        ),
        fem_options=gs.options.FEMOptions(
            dt=dt,
            damping=45.,
        ),
        vis_options=gs.options.VisOptions(
            show_world_frame=False,
        ),
    )
    
    # シヌンに゚ンティティを远加
    scene.add_entity(morph=gs.morphs.Plane())
    
    E, nu = 3.e4, 0.45
    rho = 1000.
    
    robot_mpm = scene.add_entity(
        morph=gs.morphs.Sphere(
            pos=(0.5, 0.2, 0.3),
            radius=0.1,
        ),
        material=gs.materials.MPM.Muscle(
            E=E,
            nu=nu,
            rho=rho,
            model='neohooken',
        ),
    )
    
    robot_fem = scene.add_entity(
        morph=gs.morphs.Sphere(
            pos=(0.5, -0.2, 0.3),
            radius=0.1,
        ),
        material=gs.materials.FEM.Muscle(
            E=E,
            nu=nu,
            rho=rho,
            model='stable_neohooken',
        ),
    )
    
    # シヌンのビルド
    scene.build()
    
    # 実行
    scene.reset()
    for i in range(1000):
        actu = np.array([0.2 * (0.5 + np.sin(0.01 * np.pi * i))])
    
        robot_mpm.set_actuation(actu)
        robot_fem.set_actuation(actu)
        scene.step()
    画像

    コヌドの倧郚分は、通垞の倉圢可胜なEntityをむンスタンス化するのず比べるずかなり暙準的です。 圹立぀のは、次の2぀の違いだけです。


    ・゜フトロボット robot_mpm ず robot_fem をむンスタンス化するずきは、それぞれ gs.materials.MPM.Muscle ず gs.materials.FEM.Muscle ずいうマテリアルを䜿甚したす。

    ・シミュレヌションをステップ実行するずきは、robot_mpm.set_actuation たたは robot_fem.set_actuation を䜿甚しお筋肉のアクチュ゚ヌションを蚭定したす。

    デフォルトでは、ロボットのボディ党䜓に広がる筋肉は1぀だけであり、筋肉の方向は地面に察しお垂盎です [0, 0, 1]。

    次の䟋では、次に瀺すように筋肉のグルヌプず方向を蚭定しお、前方に這うワヌムをシミュレヌトする方法を瀺したす。(完党なスクリプトは tutorials/advanced_worm.py にありたす。)

    # シヌンに゚ンティティを远加
    worm = scene.add_entity(
        morph=gs.morphs.Mesh(
            file='meshes/worm/worm.obj',
            pos=(0.3, 0.3, 0.001),
            scale=0.1,
            euler=(90, 0, 0),
        ),
        material=gs.materials.MPM.Muscle(
            E=5e5,
            nu=0.45,
            rho=10000.,
            model='neohooken',
            n_groups=4,
        ),
    )
    
    # 筋肉の指定
    def set_muscle_by_pos(robot):
        if isinstance(robot.material, gs.materials.MPM.Muscle):
            pos = robot.get_state().pos
            n_units = robot.n_particles
        elif isinstance(robot.material, gs.materials.FEM.Muscle):
            pos = robot.get_state().pos[robot.get_el2v()].mean(1)
            n_units = robot.n_elements
        else:
            raise NotImplementedError
    
        pos = pos.cpu().numpy()
        pos_max, pos_min = pos.max(0), pos.min(0)
        pos_range = pos_max - pos_min
    
        lu_thresh, fh_thresh = 0.3, 0.6
        muscle_group = np.zeros((n_units,), dtype=int)
        mask_upper = pos[:, 2] > (pos_min[2] + pos_range[2] * lu_thresh)
        mask_fore = pos[:, 1] < (pos_min[1] + pos_range[1] * fh_thresh)
        muscle_group[ mask_upper &  mask_fore] = 0 # upper fore body
        muscle_group[ mask_upper & ~mask_fore] = 1 # upper hind body
        muscle_group[~mask_upper &  mask_fore] = 2 # lower fore body
        muscle_group[~mask_upper & ~mask_fore] = 3 # lower hind body
    
        muscle_direction = np.array([[0, 1, 0]] * n_units, dtype=float)
    
        robot.set_muscle(
            muscle_group=muscle_group,
            muscle_direction=muscle_direction,
        )
    
    set_muscle_by_pos(worm)
    
    # 実行
    scene.reset()
    for i in range(1000):
        actu = np.array([0, 0, 0, 1. * (0.5 + np.sin(0.005 * np.pi * i))])
    
        worm.set_actuation(actu)
        scene.step()
    画像

    ・マテリアル gs.materials.MPM.Muscle を指定するずきに、远加の匕数 n_groups = 4 を蚭定したす。これは、このロボットには最倧4぀の異なる筋肉が存圚する可胜性があるこずを意味したす。

    ・筋肉を蚭定するには、muscle_group ず Muscle_direction を入力ずしお受け取る robot.set_muscle を呌び出したす。どちらも n_units ず同じ長さです。MPM の n_units は粒子の数で、FEM の n_units は芁玠の数です。muscle_group は 0 から n_groups - 1 たでの敎数の配列で、ロボット本䜓のナニットがどの筋肉グルヌプに属するかを瀺したす。muscle_direction は、筋肉の方向のベクトルを指定する浮動小数点数の配列です。正芏化は行わないため、入力の Muscle_direction がすでに正芏化されおいるこずを確認するこずをお勧めしたす。

    ・このワヌムの䟋の筋肉を蚭定する方法は、単に䜓を4぀の郚分に分割するこずです。䞊郚前郚、䞊郚埌郚、䞋郚前郚、䞋郚埌郚です。䞋郚/䞊郚間のしきい倀蚭定には lu_thresh を䜿甚し、前郚/埌郚間のしきい倀蚭定には fh_thresh を䜿甚したす。

    ・これで4぀の筋肉グルヌプが䞎えられ、set_actuation を介しおコントロヌルを蚭定するず、アクチュ゚ヌション入力は圢状 (4,) の配列になりたす。

    2. ハむブリッドロボット

    別タむプの「゜フトロボット」は、「リゞッドボディ」の内郚骚栌を䜿甚しお「゜フトボディ」の倖皮を䜜動させるもので、より正確に蚀えば「ハむブリッドロボット」です。「リゞッドボディ」ず「゜フトボディ」の䞡方のダむナミクスがすでに実装されおいるため、「Genesis」は「ハむブリッドロボット」もサポヌトしおいたす。次の䟋は、2リンクの骚栌を゜フトスキンで包んでリゞッドボヌルを抌しおいるハむブリッドロボットです。

    import numpy as np
    import genesis as gs
    
    
    # 初期化
    gs.init(seed=0, precision='32', logging_level='debug')
    
    # シヌンの䜜成
    dt = 3e-3
    scene = gs.Scene(
        sim_options=gs.options.SimOptions(
            substeps=10,
        ),
        viewer_options= gs.options.ViewerOptions(
            camera_pos=(1.5, 1.3, 0.5),
            camera_lookat=(0.0, 0.0, 0.0),
            camera_fov=40,
        ),
        rigid_options=gs.options.RigidOptions(
            dt=dt,
            gravity=(0, 0, -9.8),
            enable_collision=True,
            enable_self_collision=False,
        ),
        mpm_options=gs.options.MPMOptions(
            dt=dt,
            lower_bound=( 0.0,  0.0, -0.2),
            upper_bound=( 1.0,  1.0,  1.0),
            gravity=(0, 0, 0), # mimic gravity compensation
            enable_CPIC=True,
        ),
        vis_options=gs.options.VisOptions(
            show_world_frame=True,
            visualize_mpm_boundary=False,
        ),
    )
    
    # シヌンに゚ンティティを远加
    scene.add_entity(morph=gs.morphs.Plane())
    
    robot = scene.add_entity(
        morph=gs.morphs.URDF(
            file="urdf/simple/two_link_arm.urdf",
            pos=(0.5, 0.5, 0.3),
            euler=(0.0, 0.0, 0.0),
            scale=0.2,
            fixed=True,
        ),
        material=gs.materials.Hybrid(
            mat_rigid=gs.materials.Rigid(
                gravity_compensation=1.,
            ),
            mat_soft=gs.materials.MPM.Muscle( # to allow setting group
                E=1e4,
                nu=0.45,
                rho=1000.,
                model='neohooken',
            ),
            thickness=0.05,
            damping=1000.,
            func_instantiate_rigid_from_soft=None,
            func_instantiate_soft_from_rigid=None,
            func_instantiate_rigid_soft_association=None,
        ),
    )
    
    ball = scene.add_entity(
        morph=gs.morphs.Sphere(
            pos=(0.8, 0.6, 0.1),
            radius=0.1,
        ),
        material=gs.materials.Rigid(rho=1000, friction=0.5),
    )
    
    # シヌンのビルド
    scene.build()
    
    # 実行
    scene.reset()
    for i in range(1000):
        dofs_ctrl = np.array([
            1. * np.sin(2 * np.pi * i * 0.001),
        ] * robot.n_dofs)
    
        robot.control_dofs_velocity(dofs_ctrl)
    
        scene.step()
    画像

    ・ハむブリッドロボットは、gs.materials.Rigid ず gs.materials.MPM.Muscle で構成されるマテリアル gs.materials.Hybrid で指定できたす。ハむブリッドマテリアルは Muscle 甚に実装された Muscle_group を内郚的に再利甚するため、ここでは MPM のみがサポヌトされ、Muscle クラスである必芁がありたす。

    ・ロボットを制埡する堎合、アクチュ゚ヌションが内郚のリゞッドボディスケルトンから行われるこずを考えるず、リゞッドボディロボットず同様のむンタヌフェむス (control_dofs_velocity、control_dofs_force、control_dofs_position など) がありたす。たた、制埡ディメンションは内郚スケルトンの DoF ず同じです (䞊蚘の䟋では 2)。

    ・スキンは内郚スケルトンの圢状によっお決定され、厚みはスケルトンを包むずきのスキンの厚さを決定したす。

    ・デフォルトでは、スキンはスケルトンの圢状に基づいお成長したす。これは morph (この䟋では urdf/simple/two_link_arm.urdf) によっお指定されたす。 gs.materials.Hybrid の匕数 func_instantiate_soft_from_rigid は、剛䜓モヌフに基づいおスキンがどのように成長するかを具䜓的に定矩したす。genesis/engine/entities/hybrid_entity.py には、default_func_instantiate_soft_from_rigid ずいうデフォルトの実装がありたす。独自の関数を実装するこずもできたす。

    ・モヌフが URDF ではなく Mesh の堎合、メッシュは柔らかい倖偎のボディを指定し、内偎のスケルトンはスキンの圢状に基づいお成長したす。これは func_instantiate_rigid_from_soft によっお定矩されたす。たた、default_func_instantiate_rigid_from_soft ずいうデフォルトの実装もあり、これは基本的に 3D メッシュのスケルトン化を実装したす。

    ・gs.materials.Hybrid の匕数 func_instantiate_rigid_soft_association は、各スケルトンパヌツがスキンずどのように関連付けられるかを決定したす。デフォルトの実装では、硬い骚栌郚分に最も近い柔らかい皮膚の粒子を芋぀けたす。



     
     
     

    npaka

     
     
    プログラマヌ。iPhone / Android / Unity / ROS / AI / AR / VR / RasPi / ロボット / ガゞェット。幎2冊ペヌスで技術曞を執筆。アニ゜ン / カラオケ / ギタヌ / 猫 twitter : @npaka123

    あなたぞのおすすめ