Repositori ini menyediakan implementasi mandiri berlisensi BSD dari berbagai metode optimasi untuk memecahkan masalah kinematika invers umum secara efisien.
Seluruh modul diterapkan oleh Philipp Ruppel sebagai bagian dari Tesis Masternya.
Untuk implementasi ulang algoritma "BioIK" asli berbasis C++, seperti yang awalnya dijual di toko Unity, Anda dapat menggunakan mode non-default bio1
. Mode default bio2_memetic
tidak berbagi kode dengan implementasi ini, terbukti mengunggulinya dalam hal tingkat keberhasilan, presisi dan efisiensi, dan sebenarnya dapat digunakan untuk aplikasi robotik yang tepat [4].
Anda memerlukan ROS versi Indigo atau yang lebih baru (wiki.ros.org). Perangkat lunak ini dikembangkan pada Ubuntu Linux 16.04 LTS dengan ROS Kinetic, tetapi juga telah diuji pada Ubuntu Linux 14.04 LTS dengan ROS Indigo. Versi ROS yang lebih baru seharusnya bisa berfungsi, tetapi mungkin memerlukan beberapa adaptasi. Lihat di bawah untuk instruksi khusus versi.
Unduh paket bio_ik
dan buka kemasannya ke ruang kerja catkin Anda.
Jalankan catkin_make
untuk mengkompilasi ruang kerja Anda:
roscd
cd src
git clone https://github.com/TAMS-Group/bio_ik.git
roscd
catkin_make
Konfigurasikan Moveit untuk menggunakan bio_ik sebagai pemecah kinematika (lihat bagian selanjutnya).
Gunakan Moveit untuk merencanakan dan melaksanakan gerakan atau gunakan kode Anda sendiri bersama dengan node move_group
untuk menggerakkan robot Anda.
Seperti biasa, API publik ditentukan dalam file header publik untuk paket bio_ik
, yang terletak di subdirektori include/bio_ik
; sumber termasuk beberapa file header pribadi ada di subdirektori src
.
Untuk kemudahan penggunaan dan kompatibilitas dengan kode yang ada, algoritma bio_ik dienkapsulasi sebagai plugin kinematika Moveit. Oleh karena itu, bio_ik dapat digunakan sebagai pengganti langsung pemecah IK berbasis Orocos/KDL default. Mengingat nama efektor akhir dan pose target 6-DOF, bio_ik akan mencari konfigurasi gabungan robot yang valid yang mencapai target yang ditentukan.
Dalam pengujian kami (lihat di bawah), baik dalam hal tingkat keberhasilan dan waktu solusi, bio_ik secara teratur mengungguli pemecah Orocos [1] dan bersaing dengan trac-ik [2]. Algoritme bio_ik juga dapat digunakan untuk sistem DOF tinggi seperti robot ular, dan secara otomatis akan menyatu ke solusi perkiraan terbaik untuk lengan DOF rendah di mana beberapa pose target tidak dapat dijangkau secara tepat.
Meskipun Anda dapat menulis file konfigurasi Moveit dengan tangan, cara termudah adalah dengan menjalankan asisten pengaturan Moveit untuk robot Anda, dan kemudian memilih bio_ik sebagai pemecah IK saat mengonfigurasi efektor akhir. Setelah dikonfigurasi, pemecah dapat dipanggil menggunakan API Moveit standar atau digunakan secara interaktif dari rviz menggunakan plugin MotionPlanning GUI.
Pastikan Anda memiliki model URDF (atau xacro) untuk robot Anda.
Jalankan asisten pengaturan moveit untuk membuat file konfigurasi Moveit:
rosrun moveit_setup_assistant moveit_setup_assistant
Asisten pengaturan secara otomatis mencari semua plugin pemecah IK yang tersedia di ruang kerja Anda. Oleh karena itu, Anda cukup memilih bio_ik sebagai pemecah IK dari daftar drop-down untuk setiap efektor akhir dan kemudian mengkonfigurasi parameter kinematika, yaitu akurasi posisi default (meter) dan batas waktu (dalam detik). Untuk senjata 6-DOF atau 7-DOF pada umumnya, akurasi 0,001 m (atau lebih kecil) dan batas waktu 1 mdetik sudah cukup. Robot yang lebih kompleks mungkin memerlukan waktu tunggu yang lebih lama.
Hasilkan file konfigurasi moveit dari asisten pengaturan. Tentu saja, Anda juga dapat mengedit file konfigurasi config/kinematics.yaml
dengan editor teks favorit Anda. Misalnya, konfigurasi robot PR2 mungkin terlihat seperti ini:
# example kinematics.yaml for the PR2 robot
right_arm:
# kinematics_solver: kdl_kinematics_plugin/KDLKinematicsPlugin
# kinematics_solver_attempts: 1
kinematics_solver: bio_ik/BioIKKinematicsPlugin
kinematics_solver_search_resolution: 0.005
kinematics_solver_timeout: 0.005
kinematics_solver_attempts: 1
left_arm:
kinematics_solver: bio_ik/BioIKKinematicsPlugin
kinematics_solver_search_resolution: 0.005
kinematics_solver_timeout: 0.005
kinematics_solver_attempts: 1
all:
kinematics_solver: bio_ik/BioIKKinematicsPlugin
kinematics_solver_search_resolution: 0.005
kinematics_solver_timeout: 0.02
kinematics_solver_attempts: 1
# optional bio_ik configuration parameters
# center_joints_weight: 1
# minimal_displacement_weight: 1
# avoid_joint_limits_weight: 1
Untuk pengujian pertama, jalankan peluncuran demo yang dibuat oleh Moveit. Setelah rviz berjalan, aktifkan plugin perencanaan gerak, lalu pilih salah satu efektor akhir robot Anda. Rviz harus menampilkan penanda interaktif 6-D (posisi dan orientasi) untuk efektor akhir yang dipilih. Pindahkan penanda interaktif dan saksikan bio_ik menghitung pose robot Anda.
Jika Anda juga menginstal demo bio_ik (lihat di bawah), Anda seharusnya dapat menjalankan salah satu demo yang telah ditentukan sebelumnya:
roslaunch pr2_bioik_moveit demo.launch
roslaunch pr2_bioik_moveit valve.launch
roslaunch pr2_bioik_moveit dance.launch
Anda sekarang siap menggunakan bio_ik dari program C/C++ dan Python Anda, menggunakan API Moveit standar. Untuk secara eksplisit meminta solusi IK di C++:
robot_model_loader::RobotModelLoader robot_model_loader(robot);
auto robot_model = robot_model_loader.getModel();
auto joint_model_group = robot_model->getJointModelGroup(group);
auto tip_names = joint_model_group->getSolverInstance()->getTipFrames();
kinematics::KinematicsQueryOptions opts;
opts.return_approximate_solution = true; // optional
robot_state::RobotState robot_state_ik(robot_model);
// traditional "basic" bio_ik usage. The end-effector goal poses
// and end-effector link names are passed into the setFromIK()
// call. The KinematicsQueryOptions are empty.
//
bool ok = robot_state_ik.setFromIK(
joint_model_group, // joints to be used for IK
tip_transforms, // multiple end-effector goal poses
tip_names, // names of the end-effector links
attempts, timeout, // solver attempts and timeout
moveit::core::GroupStateValidityCallbackFn(),
opts // mostly empty
);
Untuk banyak aplikasi robot, penting untuk menentukan lebih dari satu pose efektor akhir. Contoh tipikalnya meliputi
Dalam bio_ik, tugas-tugas tersebut ditentukan sebagai kombinasi dari beberapa tujuan individu.
Algoritme kemudian mencoba menemukan konfigurasi robot yang memenuhi semua tujuan yang diberikan secara bersamaan dengan meminimalkan fungsi kesalahan kuadrat yang dibangun dari tujuan individu yang diberi bobot. Meskipun API Moveit saat ini tidak mendukung tugas multi-tujuan secara langsung, API ini menyediakan kelas KinematicQueryOptions. Oleh karena itu, bio_ik hanya menyediakan serangkaian sasaran gerak yang telah ditentukan sebelumnya, dan kombinasi sasaran yang ditentukan pengguna diteruskan melalui Moveit ke pemecah IK. Tidak ada perubahan API yang diperlukan di Moveit, tetapi penggunaan pemecah IK sekarang terdiri dari meneruskan sasaran berbobot melalui KinematicQueryOptions. Tujuan yang telah ditetapkan antara lain:
Untuk memecahkan masalah gerak pada robot Anda, triknya sekarang adalah membuat kombinasi tujuan individu yang sesuai.
Pada contoh berikut, kita ingin memegang dan memutar roda katup secara perlahan dengan griper kiri dan kanan robot PR2:
bio_ik::BioIKKinematicsQueryOptions ik_options;
ik_options.replace = true;
ik_options.return_approximate_solution = true;
auto* ll_goal = new bio_ik::PoseGoal();
auto* lr_goal = new bio_ik::PoseGoal();
auto* rl_goal = new bio_ik::PoseGoal();
auto* rr_goal = new bio_ik::PoseGoal();
ll_goal->setLinkName("l_gripper_l_finger_tip_link");
lr_goal->setLinkName("l_gripper_r_finger_tip_link");
rl_goal->setLinkName("r_gripper_l_finger_tip_link");
rr_goal->setLinkName("r_gripper_r_finger_tip_link");
ik_options.goals.emplace_back(ll_goal);
ik_options.goals.emplace_back(lr_goal);
ik_options.goals.emplace_back(rl_goal);
ik_options.goals.emplace_back(rr_goal);
Kami juga menetapkan beberapa tujuan sekunder. Pertama, kita ingin agar kepala PR2 terlihat di tengah katup. Kedua, kami ingin menghindari batasan sendi pada semua sendi, jika memungkinkan. Ketiga, kami ingin solusi IK sedekat mungkin dengan konfigurasi gabungan sebelumnya, yang berarti pergerakan kecil dan efisien. Hal ini ditangani dengan menambahkan MinimalDisplacementGoal. Keempat, kami ingin menghindari gerakan mengangkat batang tubuh, yang sangat lambat pada PR2. Semua ini ditentukan dengan mudah:
auto* lookat_goal = new bio_ik::LookAtGoal();
lookat_goal->setLinkName("sensor_mount_link");
ik_options.goals.emplace_back(lookat_goal);
auto* avoid_joint_limits_goal = new bio_ik::AvoidJointLimitsGoal();
ik_options.goals.emplace_back(avoid_joint_limits_goal);
auto* minimal_displacement_goal = new bio_ik::MinimalDisplacementGoal();
ik_options.goals.emplace_back(minimal_displacement_goal);
auto* torso_goal = new bio_ik::PositionGoal();
torso_goal->setLinkName("torso_lift_link");
torso_goal->setWeight(1);
torso_goal->setPosition(tf::Vector3( -0.05, 0, 1.0 ));
ik_options.goals.emplace_back(torso_goal);
Untuk gerakan memutar sebenarnya, kami menghitung serangkaian pose gripper yang diperlukan dalam satu lingkaran:
for(int i = 0; ; i++) {
tf::Vector3 center(0.7, 0, 1);
double t = i * 0.1;
double r = 0.1;
double a = sin(t) * 1;
double dx = fmin(0.0, cos(t) * -0.1);
double dy = cos(a) * r;
double dz = sin(a) * r;
tf::Vector3 dl(dx, +dy, +dz);
tf::Vector3 dr(dx, -dy, -dz);
tf::Vector3 dg = tf::Vector3(0, cos(a), sin(a)) * (0.025 + fmin(0.025, fmax(0.0, cos(t) * 0.1)));
ll_goal->setPosition(center + dl + dg);
lr_goal->setPosition(center + dl - dg);
rl_goal->setPosition(center + dr + dg);
rr_goal->setPosition(center + dr - dg);
double ro = 0;
ll_goal->setOrientation(tf::Quaternion(tf::Vector3(1, 0, 0), a + ro));
lr_goal->setOrientation(tf::Quaternion(tf::Vector3(1, 0, 0), a + ro));
rl_goal->setOrientation(tf::Quaternion(tf::Vector3(1, 0, 0), a + ro));
rr_goal->setOrientation(tf::Quaternion(tf::Vector3(1, 0, 0), a + ro));
lookat_goal->setAxis(tf::Vector3(1, 0, 0));
lookat_goal->setTarget(rr_goal->getPosition());
// "advanced" bio_ik usage. The call parameters for the end-effector
// poses and end-effector link names are left empty; instead the
// requested goals and weights are passed via the ik_options object.
//
robot_state.setFromIK(
joint_model_group, // active PR2 joints
EigenSTL::vector_Affine3d(), // no explicit poses here
std::vector<std::string>(), // no end effector links here
0, 0.0, // take values from YAML file
moveit::core::GroupStateValidityCallbackFn(),
ik_options // four gripper goals and secondary goals
);
... // check solution validity and actually move the robot
}
Saat Anda menjalankan kode tersebut, PR2 akan meraih roda katup dan memutarnya. Sesekali ia tidak dapat mencapai katup dengan konfigurasi lengannya saat ini dan akan menarik kembali kemudi.
Lihat [3] dan [4] untuk contoh lebih lanjut.
BioIK telah dikembangkan untuk secara efisien menemukan solusi yang baik untuk masalah kinematika invers non-cembung dengan banyak tujuan dan minimum lokal. Namun, untuk beberapa aplikasi, hal ini dapat menyebabkan hasil yang tidak intuitif. Jika ada beberapa solusi yang mungkin untuk masalah IK tertentu, dan jika pengguna tidak secara eksplisit menentukan solusi mana yang harus dipilih, suatu hasil dapat dipilih secara acak dari himpunan semua solusi yang valid. Saat melacak jalur kartesius secara bertahap, hal ini dapat mengakibatkan lompatan yang tidak diinginkan, guncangan, dll. Untuk menghasilkan lintasan yang mulus secara bertahap menggunakan BioIK, perilaku yang diinginkan harus ditentukan secara eksplisit, yang dapat dilakukan dengan dua cara.
BioIK menawarkan sejumlah pemecah yang berbeda, termasuk pengoptimal global dan pengoptimal lokal. Secara default, BioIK menggunakan pengoptimal global memetika ( bio2_memetic
). Kelas pemecah yang berbeda dapat dipilih dengan mengatur parameter mode
di file kinematics.yaml
konfigurasi robot MoveIt Anda.
Contoh:
all:
kinematics_solver: bio_ik/BioIKKinematicsPlugin
kinematics_solver_search_resolution: 0.005
kinematics_solver_timeout: 0.02
kinematics_solver_attempts: 1
mode: gd_c
Pengoptimal lokal yang tersedia saat ini:
gd, gd_2, gd_4, gd_8
gd_r, gd_r_2, gd_r_4, gd_r_8
gd_c, gd_c_2, gd_c_4, gd_c_8
jac, jac_2, jac_4, jac_8
Konvensi penamaan: <solver type>_[<variant>_]<number of threads>
Catatan:
gd_*
mendukung jenis sasaran arbitrer.jac_*
hanya mendukung tujuan pose tetapi secara teori mungkin lebih stabil dalam beberapa kasus.gd_c
biasanya mengungguli pemecah lokal lainnya.gd_c
, gd
, atau jac
).Anda dapat memaksa pengoptimal global untuk mengembalikan nilai minimum lokal melalui regularisasi.
Untuk kasus spesifik gerakan robot tambahan (alias jogging ), solusi paling sederhana adalah dengan menentukan PoseGoal dan RegularizationGoal khusus, yang mencoba menjaga solusi IK ruang gabungan sedekat mungkin dengan konfigurasi benih robot yang diberikan. Biasanya Anda akan menggunakan bobot yang tinggi untuk PoseGoal dan bobot yang lebih kecil untuk pengatur.
Anda juga dapat menambahkan MinimalDisplacementGoal alih-alih RegularizationGoal . Kedua tujuan tersebut mencoba untuk menjaga solusi IK tetap dekat dengan keadaan robot saat ini/seed, namun sedikit berbeda dalam penanganan sambungan robot yang cepat dan lambat (misalnya PR2 memiliki sambungan lengan yang cepat dan sambungan angkat batang tubuh yang agak lambat). Anda mungkin ingin bermain dengan kedua gol tersebut untuk melihat mana yang lebih sesuai dengan kebutuhan Anda.
Beberapa pengontrol robot industri pada lengan 7-DOF berperilaku seolah-olah bekerja pada lengan 6-DOF dengan satu sambungan tambahan. Biasanya, nilai sambungan tambahan dapat ditentukan, dan solusi IK kemudian dicari untuk enam sambungan yang tersisa. Perilaku ini dapat dicapai dalam bio_ik dengan menggabungkan PoseGoal untuk efektor akhir dengan JointPositionGoal untuk satu (salah satu) sendi robot.
Trik lain yang berguna adalah mencoba menjaga sendi robot tetap berada di tengah, karena ini akan memungkinkan gerakan robot (sendi) di kedua arah. Gabungkan saja PoseGoal dengan CenterJointsGoal , dan opsional juga RegularizationGaol .
Anda juga dapat menggabungkan regularisasi dengan pemecah gd_*
lokal.
Pemecah bio_ik didasarkan pada algoritma memetika yang menggabungkan optimasi berbasis gradien dengan optimasi kawanan genetik dan partikel.
Secara internal, vektor dari semua nilai gabungan robot digunakan untuk mengkodekan solusi perantara yang berbeda ( genotipe algoritma genetika). Selama optimasi, nilai sambungan selalu diperiksa terhadap batas sambungan bawah dan atas yang aktif, sehingga hanya konfigurasi robot yang valid yang dihasilkan.
Untuk menghitung kebugaran individu, kesalahan kumulatif atas semua sasaran individu tertentu dihitung. Setiap individu dengan kesalahan nol merupakan solusi eksak untuk masalah IK, sedangkan individu dengan kesalahan kecil merupakan solusi perkiraan.
Individu diurutkan berdasarkan kebugarannya, dan pengoptimalan berbasis gradien dicoba pada beberapa konfigurasi terbaik, menghasilkan konvergensi yang cepat dan kinerja yang baik untuk banyak masalah. Jika tidak ada solusi yang ditemukan dari optimasi berbasis gradien, individu baru diciptakan oleh serangkaian operator mutasi dan rekombinasi, sehingga menghasilkan eksplorasi ruang pencarian yang baik.
Lihat [3] dan [4] untuk lebih jelasnya. Lihat [5] dan [6] untuk penjelasan mendalam tentang algoritma evolusioner sebelumnya untuk menganimasikan karakter video game.
Kami telah menguji bio_ik pada banyak lengan robot yang berbeda, baik menggunakan API efektor ujung tunggal tradisional maupun API efektor akhir multi tingkat lanjut berdasarkan KinematicsQueryOptions.
Satu pengujian mandiri sederhana terdiri dari menghasilkan konfigurasi robot acak yang valid, menjalankan kinematika maju untuk menghitung pose efektor akhir yang dihasilkan, dan menanyakan plugin IK untuk menemukan konfigurasi sambungan robot yang sesuai. Keberhasilan kemudian diperiksa dengan menjalankan kembali kinematika maju dan memeriksa bahwa pose efektor akhir untuk solusi IK yang dihasilkan cocok dengan pose target. Pendekatan ini dapat dijalankan dengan mudah untuk ribuan atau jutaan pose acak, mengambil sampel seluruh ruang kerja robot, dan memungkinkan dengan cepat menghasilkan perkiraan tingkat keberhasilan dan waktu solusi untuk pemecah IK yang dipilih.
Tentu saja, menjalankan pengujian memerlukan instalasi model robot yang sesuai dan menambahkan banyak dependensi. Oleh karena itu, tes tersebut tidak disertakan dalam paket standar bio_ik, namun dikemas terpisah.
Untuk kenyamanan, kami menyediakan paket pr2_bioik_moveit
, yang juga mencakup beberapa demo bio_ik untuk robot layanan PR2. Ini hanya demo kinematika; tapi tentu saja Anda juga dapat mencoba menjalankan demo di robot asli (jika ada) atau simulator Gazebo (jika Anda menginstal Gazebo).
Cukup kloning paket deskripsi PR2 (di dalam pr2_common
) dan paket pr2_bioik_moveit
ke dalam ruang kerja catkin Anda:
roscd
cd src
git clone https://github.com/PR2/pr2_common.git
git clone https://github.com/TAMS-Group/bioik_pr2.git
catkin_make
Untuk tes kinerja FK-IK-FK silahkan dijalankan
roslaunch pr2_bioik_moveit env_pr2.launch
roslaunch pr2_bioik_moveit test_fk_ik.launch
... // wait for test completion and results summary
Kinematika dan Dinamika Orocos, http://www.orocos.org
P. Beeson dan B. Ames, TRAC-IK: Perpustakaan sumber terbuka untuk peningkatan penyelesaian kinematika invers generik , Prosiding Konferensi IEEE RAS Humanoids, Seoul, Korea, November 2015.
Philipp Ruppel, Norman Hendrich, Sebastian Starke, Jianwei Zhang, Fungsi Biaya untuk Menentukan Tugas Gerakan Seluruh Tubuh dan Manipulasi Multi-Tujuan , Konferensi Internasional IEEE tentang Robotika dan Otomasi, (ICRA-2018), Brisbane, Australia. DOI: 10.1109/ICRA.2018.8460799
Philipp Ruppel, Optimalisasi kinerja dan implementasi kinematika invers evolusioner di ROS , tesis MSc, Universitas Hamburg, 2017 PDF
Sebastian Starke, Norman Hendrich, Jianwei Zhang, Algoritma Evolusi Memetik untuk Gerak Kinematik Artikulasi Waktu Nyata , IEEE Intl. Kongres Komputasi Evolusioner (CEC-2017), hal.2437-2479, 4-8 Juni 2017, San Sebastian, Spanyol. DOI: 10.1109/CEC.2017.7969605
Sebastian Starke, Norman Hendrich, Dennis Krupke, Jianwei Zhang, Optimasi Evolusioner Multi-Tujuan untuk Kinematika Terbalik pada Robot Artikulasi Tinggi dan Humanoid , IEEE Intl. Konferensi Robot dan Sistem Cerdas (IROS-2017), 24-28 September 2017, Vancouver, Kanada