Pythonスクリプトを引数に取る場合の--start-simulation

choreonoidの起動時の引数にPythonのスクリプトを取る場合は,--start-simulation が効かないようです.WRS用のスクリプトのようにプロジェクトをPythonのスクリプトで動的に生成し,その後でシミュレーションを開始するにはどうすればいいのでしょうか?

確かにそうなりますね。

–start-simulationは、読み込まれたプロジェクトに含まれるSimulatorItemに対して、シミュレーションを開始するようになっていますが、Pythonスクリプトを実行する場合は、あくまでそこで動的に生成されるSimulatorItemとなり、プロジェクトに含まれるものではありませんので、–start-simulationの実行タイミングとの兼ね合いで、このオプションが効かないようです。

こちらについても効くようにできないか今後検討しますが、とりあえずPythonスクリプトで実行しているのであれば、スクリプトからシミュレーションを開始できるので、それが早いのではないかと思います。

この例がsample/python/SR1Walk.py にあります。このスクリプトをコマンドライン引数に与えてChoreonoidを起動すると、SR1Walkサンプルと同じ内容をスクリプトで生成し、最後にシミュレーションを自動で開始します。開始するコードは

simulatorItem.startSimulation()

となっています。

このスクリプトではsimulatorItemを自前で生成しているので、それに対して上記の関数を実行していますが、他で読み込まれたアイテムであれば、最初にそれを取得しておきます。これは

simulatorItem = Item.find("AISTSimulator")

などとしてアイテム名で検索するか、

simulatorItem = RootItem.instance.findItem(SimulatorItem)

としてアイテム型で検索することもできます。

このような例として、やはりsample/python以下にGravityChangeIteration.pyというスクリプトもあります。ちなみにこのスクリプトの内容ですが、適当なプロジェクト、例えばSR1Walk.cnoidを読み込んで、GravitiyChangeIteration.pyも読み込んでスクリプトを実行すると、重力加速度を少しずつ変えながらシミュレーションを繰り返します。

中岡様,

回答ありがとうございます.

WRSのトンネル競技用に作られたWRSUtil.loadProject()の最後に

    simulatorItem = RootItem.instance.findItem(SimulatorItem)
    simulatorItem.startSimulation()

を追加することにより,起動時にシミュレーションを開始できるようになりました.

関連しての質問ですが,コマンドラインにおいてchoreonoid起動時に引数にしたPythonのスクリプトから,それ以降の引数を読むことができますか?

現状ではできません。
Choreonoidのコマンドライン引数でPythonスクリプトを指定する際に、そのスクリプトにも引数を与えたいということですよね?確かにPythonスクリプトは元々自身に引数を与えられるものですから、Choreonoid上で実行するときも同じことができれば便利そうですね。

了解しました.

Pythonのスクリプト内でシミュレーションを開始できるようになりましたので,それをするかしないかを後に続く引数で切り替えられないかと考えた次第です.

これについては現状でも環境変数を使うことで実現できます。
以下のコードはsample/python/SR1Walk.py について、冒頭で import os をし、最後のif文を追加したものです。

最後にシミュレーションを実行するかどうかについて、“start_simulation” という環境変数を参照して判定しています。この変数に何か値を設定していれば、条件が成立し、シミュレーションを実行します。

from cnoid.Util import *
from cnoid.Base import *
from cnoid.Body import *
from cnoid.BodyPlugin import *
import math
import os

worldItem = WorldItem()
RootItem.instance.addChildItem(worldItem)

robotItem = BodyItem()
robotItem.load("${SHARE}/model/SR1/SR1.body")

robot = robotItem.body
robot.rootLink.setTranslation([0.0, 0.0, 0.7135])

q = [ 0.0, -2.1, 0.0,   4.5, -2.4, 0.0,
     10.0, -0.2, 0.0, -90.0,  0.0, 0.0, 0.0,
      0.0, -2.1, 0.0,   4.5, -2.4, 0.0,
     10.0, -0.2, 0.0, -90.0,  0.0, 0.0, 0.0,
      0.0,  0.0, 0.0 ]

for i in range(robot.numJoints):
    robot.joint(i).q = math.radians(q[i])

robot.calcForwardKinematics()
robotItem.storeInitialState()

controllerItem = SimpleControllerItem()
controllerItem.setController("SR1WalkPatternController")
robotItem.addChildItem(controllerItem)
robotItem.setChecked(True)
worldItem.addChildItem(robotItem)

floorItem = BodyItem()
floorItem.load("${SHARE}/model/misc/floor.body")
worldItem.addChildItem(floorItem)

simulatorItem = AISTSimulatorItem()
simulatorItem.setTimeStep(0.002)
simulatorItem.setTimeRangeMode(SimulatorItem.TimeRangeMode.ACTIVE_CONTROL)
worldItem.addChildItem(simulatorItem)
simulatorItem.setSelected(True)

if os.environ.get('start_simulation'):
    simulatorItem.startSimulation()

実際に使用する際には、

./bin/choreonoid sample/python/SR1Walk.py

とすればシミュレーションは実行しませんが、

start_simulation=1 ./bin/choreonoid sample/python/SR1Walk.py

などとすれば実行するようになります。

なるほど,その手がありましたか.
試してみます.