2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第3回:ついにリムル様がジャンプ!Genesisでリムルを壁越えさせる

Last updated at Posted at 2025-01-03

はじめに

こんにちは、しゅんです!色々と落ち込んでて結局夜中寝れなくて、逃げて、連続3つの記事を書きました。重要事項:マジで遊んでるだけ
今回はGenesisの「駆動信号」を用いてスライムをジャンプさせ、壁の高さを越えを試みます。
僕も人生の壁を超えたい

modelパス

/your_path/rimuru.obj

適切なパスに置き換えすること

ジャンプ動作の追加

スライムにジャンプ動作を加えるにはset_actuationを使用します。以下は駆動信号を設定したコード例です。

コード:

for i in range(1000):
    if 100 <= i < 150:
        slime.set_actuation([2.0])
    else:
        slime.set_actuation([0.0])

    slime_pos = slime.get_state().pos.mean(axis=0).cpu().numpy()
    print(f"スライム位置: {slime_pos}")

    if slime_pos[2] > 0.15:
        print("スライムが壁を越えました!")
        break

    scene.step()

シミュレーションのコード全体は以下:


import numpy as np
import genesis as gs

# 初期化
gs.init(seed=0, precision='32', logging_level='debug')

# シーンの作成
scene = gs.Scene(
    sim_options=gs.options.SimOptions(
        substeps=10,
        gravity=(0, 0, -9.8),
    ),
    mpm_options=gs.options.MPMOptions(
        dt=1e-3,  # シミュレーションステップを調整
        lower_bound=(-1.0, -1.0, -0.2),
        upper_bound=(1.0, 1.0, 1.0),
    ),
    viewer_options=gs.options.ViewerOptions(
        camera_pos=(1.5, 0, 0.8),
        camera_lookat=(0.0, 0.0, 0.0),
        camera_fov=40,
    )
)

# 地面を追加
scene.add_entity(
    morph=gs.morphs.Plane(),
    material=gs.materials.Rigid(
        rho=1000,
        friction=0.5
    )
)

# 壁を追加
scene.add_entity(
    morph=gs.morphs.Box(
        pos=(0.3, 0.0, 0.075),  # 壁の位置(地面から少し高さを持たせる)
        size=(0.1, 0.3, 0.15),  # 壁の大きさ(幅, 奥行き, 高さ)
    ),
    material=gs.materials.Rigid(
        rho=1000,  # 密度
        friction=0.7  # 摩擦係数
    )
)

# スライムを追加
slime = scene.add_entity(
    morph=gs.morphs.Mesh(
        file='your_path/rimuru.obj',
        pos=(0.0, 0.0, 0.0),  # スライムの初期位置
        scale=0.05,
        euler=(90, 0, 0),
    ),
    material=gs.materials.MPM.Muscle(
        E=1e4,
        nu=0.45,
        rho=1000.,
        model='neohooken',
    )
)

# シーンを構築
scene.build()

# シミュレーションを実行
scene.reset()
for i in range(1000):
    # 駆動制御信号を設定してスライムをジャンプさせる
    if 100 <= i < 150:  # この範囲でスライムをジャンプさせる
        slime.set_actuation([2.0])  # 駆動信号を適度に減らす
    else:
        slime.set_actuation([0.0])  # 駆動信号をリセット

    # スライムの位置を取得して壁を越えたか判定
    slime_pos = slime.get_state().pos.mean(axis=0).cpu().numpy()  # ホスト側に転送
    print(f"スライム位置: {slime_pos}")

    if slime_pos[2] > 0.15:  # 壁の高さより高い位置に到達
        print(f"スライムが壁を越えました!位置: {slime_pos}")
        break

    scene.step()


結果

スライムはジャンプして壁の高さを越えることに成功しました!ただし、高さや飛ぶ時形状が崩れるなどの安定性には改善の余地があります。今後は強化学習による動作最適化を目指します。
こんな感じです
次回予告: リムルに学習能力を持たせ、動きを進化させる方法に挑戦します!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?