Chorenoid、graspPluginでpythonインターフェースが用意されている機能は、pythonスクリプトとしてchoreonoid上で実行可能となります。
ここでは、pythonスクリプトのサンプルと使用方法、pythonインターフェース作成方法を説明します。
Choreonoidのビルド時のCmakeで以下の項目をONにしてビルドする必要あります。
- BUILD_PYTHON_PLUGIN
- ENABLE_PYTHON
コマンドラインでChorenoidを起動するときにオプションで実行するPythonスクリプトを指定します。
$ choreonoid [project-file] -p <pythonscriptfile >
$ cd <chorenoidのパス> $ bin/chorenoid -p ext/graspPlugin/Grasp/python/script/grasp_example1.py
次は、プロジェクトファイルを読み込み、その後Pythonスクリプトを実行する例です。
$ cd <chorenoidのパス> $ bin/chorenoid ext/graspPlugin/Grasp/python/script/grasp_example.cnoid \ -p ext/graspPlugin/Grasp/python/script/grasp_example2.py
まず、実行方法を説明します。
プロジェクトに使用するPythonスクリプト情報を保存したファイルとして、
ext/graspPlugin/Grasp/python/script/grasp_example_withpython.cnoid
があります。
これをコレオノイドで起動します。
$ bin/chorenoid ext/graspPlugin/Grasp/python/script/grasp_example_wihtpython.cnoid
プロジェクトにPythonスクリプト情報を追加する方法を説明します。
・まず、もととなるプロジェクトファイル(cnoid)を読み込む、もしくは、まっさらな状態からモデル等をロードしておきます。
・メニューの[ファイル]->[読み込み]->[Pythonスクリプト]をクリックすると、ファイル選択ダイアログが表示されるので、対象となるPythonファイルを選択します。
・アイテムタブに対象ファイル名のアイテムが追加されます。対象アイテムにチェックが入っていることを確認してください。
チェックが入っていないとスクリプトが実行されません。
・メニューの[ファイル]->[名前を付けてプロジェクトを保存]で保存します。
上記の例では、スクリプト実行タイミングがスクリプト実行ボタンをクリックした時ですが、以下の手順でプロジェクトが読み込まれたとき
に実行するようにできます。
・アイテムタブの対象Pythonスクリプトアイテムを選択します。
・アイテムタブの下にプロパティタブがあり、その中の「読み込み時に実行」をTrueに変更します。
- grasp_exmaple1.py
PA10とahiruを読み込み、把持計画する処理
from cnoid.Util import * from cnoid.Base import * from cnoid.Body import * from cnoid.BodyPlugin import * from cnoid.GraspPlugin import * # choreonoidのディレクトリを取得 topdir = executableTopDirectory() # choreonoidのrootItemを取得 rootItem = RootItem.instance() ## load robot model # BodyItemを作成 robotItem = BodyItem() # PA10を読み込む robotItem.load(topdir + "/ext/graspPlugin/RobotModels/PA10/PA10.yaml") # PA10をrootItemに追加(アイテムタブに表示されるようになる) rootItem.addChildItem(robotItem) # PA10のアイテムをチェックする(シーンタブにPA10が表示される) ItemTreeView.instance().checkItem(robotItem) ## load object model # BodyItemを作成 objItem = BodyItem() # ahiruを読み込む objItem.load(topdir + "/ext/graspPlugin/Samples/Object/ahiruLowHrp.wrl") # ahiruを移動する objItem.body().rootLink().setTranslation([0.59, -0.1, 0.55]) # ahiruをrootItemに追加(アイテムタブに表示されるようになる) rootItem.addChildItem(objItem) # ahiruのアイテムをチェックする(シーンタブにahiruが表示される) ItemTreeView.instance().checkItem(objItem) ## set grasping robot # PA10に対しSetRobotする(PlannerバーのSetRobot) set_robot(robotItem) ## set target object # ahiruに対しSetObjectする(PlannerバーのSetObject) set_object(objItem) ## execute grasp # 把持計画を実行(PlannerバーのGrasp) grasp()
from cnoid.Util import *
from cnoid.Base import *
from cnoid.BodyPlugin import *
from cnoid.GraspPlugin import *
# choreonoidのrootItemを取得
rootItem = RootItem.instance()
## set grasping robot
# アイテムタブからPA10を探す
robotItem = rootItem.find("PA10")
# PA10に対しSetRobotする(PlannerバーのSetRobot)
set_robot(robotItem)
## set target object
# アイテムタブからahiruを探す
objItem = rootItem.find("ahiru")
# ahiruに対しSetObjectする(PlannerバーのSetObject)
set_object(objItem)
## execute grasp
# 把持計画を実行(PlannerバーのGrasp)
grasp()
プラグインにpythonインタフェースの追加方法を説明します。
既にpythonインタフェースがあるプラグインで追加・修正を行う場合は
1. 2. は行う必要はありません。
1.CMakeLists.txtの末尾に以下を追加
if(ENABLE_PYTHON) add_subdirectory(python) endif()
3.pythonディレクトリにCMakeLists.txtを作成
Grasp/python/CMakeLists.txtを参考にソースファイルなどを適宜変更
set(target PyGraspPlugin) # "PyGraspPlugin"を対象プラグインに合わせて名前変更
add_cnoid_python_module(${target}
PyGraspPluginModule.cpp # 対象プラグインに合わせて名前変更
# 以下PythonInterfaceを記述したソースファイルを追加
PyPlanBase.cpp
PyGrasp.cpp
)
target_link_libraries(${target} CnoidGraspPlugin CnoidPyBase PyBody PyBodyPlugin)
-PyGraspPluginModule.cpp
#include <cnoid/PyUtil>
// pythonへエクスポートする処理の関数宣言
// Graspプラグインでは
// PyPlanBase.cppに定義されているPlanBaseクラスをエクスポートするexportPlanBase()
// PyGrasp.cppに定義されているSetRobot,SetObject,Grasp機能をエクスポートするexportGrasp()
void exportPlanBase();
void exportGrasp();
BOOST_PYTHON_MODULE(GraspPlugin) { // GraspPlugin部分がモジュール名に相当
boost::python::import("cnoid.Base");
boost::python::import("cnoid.Body");
boost::python::import("cnoid.BodyPlugin");
// pythonへエクスポートする関数を実行
// 処理はPyPlanBase.cpp,PyGrasp.cppを参照。
exportPlanBase();
exportGrasp();
}
#include < iostream>
....
using namespace boost::python;
using namespace grasp;
namespace {
// 実際に行う処理をここに記述
void Grasp() {
....
}
bool Set_grasping_robot(cnoid::ItemPtr item, int arm_id = 0) {
cnoid::BodyItemPtr bodyitem = cnoid::dynamic_pointer_cast<cnoid::BodyItem, cnoid::Item>(item);
....
}
BOOST_PYTHON_FUNCTION_OVERLOADS(Set_grasping_robot_overloads, Set_grasping_robot, 1, 2)
void Set_grasped_object(cnoid::ItemPtr item) {
cnoid::BodyItemPtr bodyitem = cnoid::dynamic_pointer_cast<cnoid::BodyItem, cnoid::Item>(item);
PlanBase::instance()->SetGraspedObject(bodyitem);
}
}
// エクスポートする処理
void exportGrasp() {
def("grasp", Grasp);
def("set_robot", Set_grasping_robot, Set_grasping_robot_overloads());
def("set_object", Set_grasped_object);
}
def("set_robot", Set_grasping_robot, Set_grasping_robot_overloads());
はデフォルト引数がある関数を呼び出している例です。
Set_grasping_robotがデフォルト引数がある関数で、Set_grasping_robot_overloadsがデフォルト引数を扱うためのクラスで
BOOST_PYTHON_FUNCTION_OVERLOADS(Set_grasping_robot_overloads, Set_grasping_robot, 1, 2)
で作成しています。ここで第3引数、第4引数は引数の最小と最大の数です。