From d0a1ee0adb87ef797d95f02baf06d0958a09d5fe Mon Sep 17 00:00:00 2001 From: dtotsila Date: Fri, 30 Aug 2024 14:58:11 +0200 Subject: [PATCH] supported robots updates --- src/docs/docs/images/tiago.png | Bin 0 -> 106375 bytes src/docs/docs/images/vx300.png | Bin 0 -> 18196 bytes src/docs/docs/robots.md | 40 +++++++++++++++++++++++++++++++-- src/docs/include/macros.py | 2 +- 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 src/docs/docs/images/tiago.png create mode 100644 src/docs/docs/images/vx300.png diff --git a/src/docs/docs/images/tiago.png b/src/docs/docs/images/tiago.png new file mode 100644 index 0000000000000000000000000000000000000000..fd223c04c9ca586465e5272f9ce57b8f810afe98 GIT binary patch literal 106375 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 L-J4T4TKN4B8!_<) literal 0 HcmV?d00001 diff --git a/src/docs/docs/images/vx300.png b/src/docs/docs/images/vx300.png new file mode 100644 index 0000000000000000000000000000000000000000..6b7cb4d63962680b217735458bde1189071dd912 GIT binary patch literal 18196 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 BXu1FZ literal 0 HcmV?d00001 diff --git a/src/docs/docs/robots.md b/src/docs/docs/robots.md index b7cc513c..16c9ffbb 100644 --- a/src/docs/docs/robots.md +++ b/src/docs/docs/robots.md @@ -49,7 +49,7 @@ We have two URDF files: {{TALOS}} === "Python" {{TALOS_PYTHON}} - + - `utheque/talos/talos_fast.urdf`: * no collision except for the feet, which are approximated by boxes * grippers are fixed (no movement is allowed) @@ -197,6 +197,43 @@ This hexapod is a simple 6-legged robot based on dynamixel actuators. It is simi === "Python" {{HELLO_WORLD_ROBOT_CREATION_PYTHON}} +## Vx-300 +![Vx-300 robotic arm](images/vx300.png){: style="display: block;margin-left: auto;margin-right: auto;width:70%"} + +The ViperX-300 is a versatile robotic arm developed by [Interbotix](https://docs.trossenrobotics.com/interbotix_xsarms_docs/specifications/vx300.html). It is designed for a range of applications including education, research, and light industrial tasks. + +- 5 degrees of freedom plus a gripper +- URDF: [[vx300.urdf](https://github.com/NOSALRO/robot_dart/blob/master/utheque/vx300/vx300.urdf)] +- Example: [[vx300.cpp](https://github.com/resibots/robot_dart/blob/master/src/examples/vx300.cpp)] [[vx300.py](https://github.com/resibots/robot_dart/blob/master/src/examples/python/vx300.py)] + +!!! note "Load Vx-300" + === "C++" +{{VX300}} + === "Python" +{{VX300_PYTHON}} + + + +## Tiago (PAL Robotics) +![Tiago single-arm robot](images/tiago.png){: style="display: block;margin-left: auto;margin-right: auto;width:70%"} + +Tiago is a mobile manipulator robot developed by [PAL Robotics](https://pal-robotics.com/robots/tiago/), designed for tasks such as navigation, object manipulation, and human-robot interaction. + +- Datasheet: [pdf](https://pal-robotics.com/wp-content/uploads/2024/04/Datasheet-TIAGo.pdfs) +- Height: 110 - 145 cm +- Weight: 70 kg +- Degrees of Freedom (DoF): 7 (Arm), 2 (Head), 2 (Mobile Base) +- Force/Torque sensor in the gripper +- URDF: [[tiago.urdf](https://github.com/NOSALRO/robot_dart/blob/master/utheque/tiago/tiago_steel.urdf)] +- Example: [[tiago.cpp](https://github.com/resibots/robot_dart/blob/master/src/examples/tiago.cpp)] [[tiago.py](https://github.com/resibots/robot_dart/blob/master/src/examples/python/tiago.py)] + +!!! note "Load Tiago" + === "C++" +{{TIAGO}} + === "Python" +{{TIAGO_PYTHON}} + + ## Simple arm ![simple arm robot](images/arm.png){: style="display: block;margin-left: auto;margin-right: auto;width:70%"} @@ -236,4 +273,3 @@ RobotDART gives you the ability to load custom robots that are defined in [URDF your_robot = robot_dart.Robot("path/to/model.urdf", your_model_packages) ``` - \ No newline at end of file diff --git a/src/docs/include/macros.py b/src/docs/include/macros.py index 6b5bcfb3..9187e1f2 100644 --- a/src/docs/include/macros.py +++ b/src/docs/include/macros.py @@ -1,5 +1,5 @@ def define_env(env): - variables = {'SET_ACTUATOR': '\t```cpp\n\t// Set all DoFs to same actuator\n\trobot->set_actuator_types("servo"); // actuator types can be "servo", "torque", "velocity", "passive", "locked", "mimic"\n\t// You can also set actuator types separately\n\trobot->set_actuator_type("torque", "iiwa_joint_5");\n\t```', 'POSITIONS_ENFORCED': '\t```cpp\n\t// Εnforce joint position and velocity limits\n\trobot->set_position_enforced(true);\n\t```', 'MODIFY_LIMITS': '\t```cpp\n\t// Modify Position Limits\n\tEigen::VectorXd pos_upper_lims(7);\n\tpos_upper_lims << 2.096, 2.096, 2.096, 2.096, 2.096, 2.096, 2.096;\n\trobot->set_position_upper_limits(pos_upper_lims, dof_names);\n\trobot->set_position_lower_limits(-pos_upper_lims, dof_names);\n\t\n\t// Modify Velocity Limits\n\t\n\tEigen::VectorXd vel_upper_lims(7);\n\tvel_upper_lims << 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5;\n\trobot->set_velocity_upper_limits(vel_upper_lims, dof_names);\n\trobot->set_velocity_lower_limits(-vel_upper_lims, dof_names);\n\t\n\t// Modify Force Limits\n\t\n\tEigen::VectorXd force_upper_lims(7);\n\tforce_upper_lims << 150, 150, 150, 150, 150, 150, 150;\n\trobot->set_force_upper_limits(force_upper_lims, dof_names);\n\trobot->set_force_lower_limits(-force_upper_lims, dof_names);\n\t\n\t// Modify Acceleration Limits\n\tEigen::VectorXd acc_upper_lims(7);\n\tacc_upper_lims << 1500, 1500, 1500, 1500, 1500, 1500, 1500;\n\trobot->set_acceleration_upper_limits(acc_upper_lims, dof_names);\n\trobot->set_acceleration_lower_limits(-acc_upper_lims, dof_names);\n\t```', 'MODIFY_COEFFS': '\t```cpp\n\t// Modify Damping Coefficients\n\tstd::vector damps = {0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4};\n\trobot->set_damping_coeffs(damps, dof_names);\n\t\n\t// Modify Coulomb Frictions\n\tstd::vector cfrictions = {0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001};\n\trobot->set_coulomb_coeffs(cfrictions, dof_names);\n\t\n\t// Modify Spring Stiffness\n\tstd::vector stiffnesses = {0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001};\n\trobot->set_spring_stiffnesses(stiffnesses, dof_names);\n\t```', 'SET_COLLISION_DETECTOR': '\t```cpp\n\tsimu.set_collision_detector("fcl"); // collision_detector can be "dart", "fcl", "ode" or "bullet" (case does not matter)\n\t```', 'SELF_COLLISIONS': '\t```cpp\n\tif (!robot->self_colliding()) {\n\t std::cout << "Self collision is not enabled" << std::endl;\n\t // set self collisions to true and adjacent collisions to false\n\t robot->set_self_collision(true, false);\n\t}\n\t```', 'SIMPLE_ARM': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'CAMERAS_PARALLEL': '\t```cpp\n\t// Load robot from URDF\n\tauto global_robot = std::make_shared();\n\t\n\tstd::vector workers;\n\t\n\t// Set maximum number of parallel GL contexts (this is GPU-dependent)\n\trobot_dart::gui::magnum::GlobalData::instance()->set_max_contexts(4);\n\t\n\t// We want 15 parallel simulations with different GL context each\n\tsize_t N_workers = 15;\n\tstd::mutex mutex;\n\tsize_t id = 0;\n\t// Launch the workers\n\tfor (size_t i = 0; i < N_workers; i++) {\n\t workers.push_back(std::thread([&] {\n\t mutex.lock();\n\t size_t index = id++;\n\t mutex.unlock();\n\t\n\t // Get the GL context -- this is a blocking call\n\t // will wait until one GL context is available\n\t // get_gl_context(gl_context); // this call will not sleep between failed queries\n\t get_gl_context_with_sleep(gl_context, 20); // this call will sleep 20ms between each failed query\n\t\n\t // Do the simulation\n\t auto robot = global_robot->clone();\n\t\n\t robot_dart::RobotDARTSimu simu(0.001);\n\t\n\t Eigen::VectorXd ctrl = robot_dart::make_vector({0., M_PI / 3., 0., -M_PI / 4., 0., 0., 0.});\n\t\n\t auto controller = std::make_shared(ctrl);\n\t robot->add_controller(controller);\n\t controller->set_pd(300., 50.);\n\t\n\t // Magnum graphics\n\t robot_dart::gui::magnum::GraphicsConfiguration configuration = robot_dart::gui::magnum::WindowlessGraphics::default_configuration();\n\t\n\t configuration.width = 1024;\n\t configuration.height = 768;\n\t auto graphics = std::make_shared(configuration);\n\t simu.set_graphics(graphics);\n\t // Position the camera differently for each thread to visualize the difference\n\t graphics->look_at({0.4 * index, 3.5 - index * 0.1, 2.}, {0., 0., 0.25});\n\t // record images from main camera/graphics\n\t // graphics->set_recording(true); // WindowlessGLApplication records images by default\n\t\n\t simu.add_robot(robot);\n\t simu.run(6);\n\t\n\t // Save the image for verification\n\t robot_dart::gui::save_png_image("camera_" + std::to_string(index) + ".png",\n\t graphics->image());\n\t\n\t // Release the GL context for another thread to use\n\t release_gl_context(gl_context);\n\t }));\n\t}\n\t\n\t// Wait for all the workers\n\tfor (size_t i = 0; i < workers.size(); i++) {\n\t workers[i].join();\n\t}\n\t```', 'INIT_SIMU': '\t```cpp\n\t// choose time step of 0.001 seconds\n\trobot_dart::RobotDARTSimu simu(0.001);\n\t```', 'MODIFY_SIMU_DT': '\t```cpp\n\t// set timestep to 0.005 and update control frequency(bool)\n\tsimu.set_timestep(0.005, true);\n\t```', 'SIMU_GRAVITY': '\t```cpp\n\t// Set gravitational force of mars\n\tEigen::Vector3d mars_gravity = {0., 0., -3.721};\n\tsimu.set_gravity(mars_gravity);\n\t```', 'GRAPHICS_PARAMS': '\t```cpp\n\trobot_dart::gui::magnum::GraphicsConfiguration configuration;\n\t// We can change the width/height of the window (or camera image dimensions)\n\tconfiguration.width = 1280;\n\tconfiguration.height = 960;\n\tconfiguration.title = "Graphics Tutorial"; // We can set a title for our window\n\t\n\t// We can change the configuration for shadows\n\tconfiguration.shadowed = true;\n\tconfiguration.transparent_shadows = true;\n\tconfiguration.shadow_map_size = 1024;\n\t\n\t// We can also alter some specifications for the lighting\n\tconfiguration.max_lights = 3; // maximum number of lights for our scene [default=3]\n\tconfiguration.specular_strength = 0.25; // strength of the specular component\n\t\n\t// Some extra configuration for the main camera\n\tconfiguration.draw_main_camera = true;\n\tconfiguration.draw_debug = true;\n\tconfiguration.draw_text = true;\n\t\n\t// We can also change the background color [default=black]\n\tconfiguration.bg_color = Eigen::Vector4d{1.0, 1.0, 1.0, 1.0};\n\t\n\t// Create the graphics object with the configuration as parameter\n\tauto graphics = std::make_shared(configuration);\n\t```', 'SHADOWS_GRAPHICS': '\t```cpp\n\t// Disable shadows\n\tgraphics->enable_shadows(false, false);\n\tsimu.run(1.);\n\t// Enable shadows only for non-transparent objects\n\tgraphics->enable_shadows(true, false);\n\tsimu.run(1.);\n\t// Enable shadows for transparent objects as well\n\tgraphics->enable_shadows(true, true);\n\tsimu.run(1.);\n\t```', 'CLR_LIGHT': '\t```cpp\n\t// Clear Lights\n\tgraphics->clear_lights();\n\t```', 'LIGHT_MATERIAL': '\t```cpp\n\t// Create Light material\n\tMagnum::Float shininess = 1000.f;\n\tMagnum::Color4 white = {1.f, 1.f, 1.f, 1.f};\n\t\n\t// ambient, diffuse, specular\n\tauto custom_material = robot_dart::gui::magnum::gs::Material(white, white, white, shininess);\n\t```', 'POINT_LIGHT': '\t```cpp\n\t// Create point light\n\tMagnum::Vector3 position = {0.f, 0.f, 2.f};\n\tMagnum::Float intensity = 1.f;\n\tMagnum::Vector3 attenuation_terms = {1.f, 0.f, 0.f};\n\tauto point_light = robot_dart::gui::magnum::gs::create_point_light(position, custom_material, intensity, attenuation_terms);\n\tgraphics->add_light(point_light);\n\t```', 'DIRECTIONAL_LIGHT': '\t```cpp\n\t// Create directional light\n\tMagnum::Vector3 direction = {-1.f, -1.f, -1.f};\n\tauto directional_light = robot_dart::gui::magnum::gs::create_directional_light(direction, custom_material);\n\tgraphics->add_light(directional_light);\n\t```', 'SPOT_LIGHT': '\t```cpp\n\t// Create spot light\n\tMagnum::Vector3 position = {0.f, 0.f, 1.f};\n\tMagnum::Vector3 direction = {-1.f, -1.f, -1.f};\n\tMagnum::Float intensity = 1.f;\n\tMagnum::Vector3 attenuation_terms = {1.f, 0.f, 0.f};\n\tMagnum::Float spot_exponent = M_PI;\n\tMagnum::Float spot_cut_off = M_PI / 8;\n\tauto spot_light = robot_dart::gui::magnum::gs::create_spot_light(position, custom_material, direction, spot_exponent, spot_cut_off, intensity, attenuation_terms);\n\tgraphics->add_light(spot_light);\n\t```', 'LOAD_IICUB': '\t```cpp\n\tauto robot = std::make_shared();\n\t// Set actuator types to VELOCITY motors so that they stay in position without any controller\n\trobot->set_actuator_types("velocity");\n\trobot_dart::RobotDARTSimu simu(0.001);\n\tsimu.set_collision_detector("fcl");\n\t```', 'ICUB_PRINT_IMU': '\t```cpp\n\tstd::cout << "Angular Position: " << robot->imu().angular_position_vec().transpose().format(fmt) << std::endl;\n\tstd::cout << "Angular Velocity: " << robot->imu().angular_velocity().transpose().format(fmt) << std::endl;\n\tstd::cout << "Linear Acceleration: " << robot->imu().linear_acceleration().transpose().format(fmt) << std::endl;\n\tstd::cout << "=================================" << std::endl;\n\t```', 'ICUB_PRINT_FT': '\t```cpp\n\tstd::cout << "FT ( force): " << robot->ft_foot_left().force().transpose().format(fmt) << std::endl;\n\tstd::cout << "FT (torque): " << robot->ft_foot_left().torque().transpose().format(fmt) << std::endl;\n\tstd::cout << "=================================" << std::endl;\n\t```', 'CAMERA_SENSOR_RGBD_RECORD_DEPTH': '\t```cpp\n\tcamera->camera().record(true, true); // cameras are recording color images by default, enable depth images as well for this example\n\t```', 'TORQUE_SENSOR': '\t```cpp\n\t// Add torque sensors to the robot\n\tint ct = 0;\n\tstd::vector> tq_sensors(robot->num_dofs());\n\tfor (const auto& joint : robot->dof_names())\n\t tq_sensors[ct++] = simu.add_sensor(robot, joint, 1000);\n\t```', 'FORCE_TORQUE_SENSOR': '\t```cpp\n\t// Add force-torque sensors to the robot\n\tct = 0;\n\tstd::vector> f_tq_sensors(robot->num_dofs());\n\tfor (const auto& joint : robot->dof_names())\n\t f_tq_sensors[ct++] = simu.add_sensor(robot, joint, 1000, "parent_to_child");\n\t```', 'IMU_SENSOR': '\t```cpp\n\t// Add IMU sensors to the robot\n\tct = 0;\n\tstd::vector> imu_sensors(robot->num_bodies());\n\tfor (const auto& body_node : robot->body_names()) {\n\t // _imu(std::make_shared(sensor::IMUConfig(body_node("head"), frequency))),\n\t imu_sensors[ct++] = simu.add_sensor(robot_dart::sensor::IMUConfig(robot->body_node(body_node), 1000));\n\t}\n\t```', 'TORQUE_MEASUREMENT': '\t```cpp\n\t// vector that contains the torque measurement for every joint (scalar)\n\tEigen::VectorXd torques_measure(robot->num_dofs());\n\tfor (const auto& tq_sens : tq_sensors)\n\t torques_measure.block<1, 1>(ct++, 0) = tq_sens->torques();\n\t```', 'FORCE_TORQUE_MEASUREMENT': '\t```cpp\n\t// matrix that contains the torque measurement for every joint (3d vector)\n\tEigen::MatrixXd ft_torques_measure(robot->num_dofs(), 3);\n\t// matrix that contains the force measurement for every joint (3d vector)\n\tEigen::MatrixXd ft_forces_measure(robot->num_dofs(), 3);\n\t// matrix that contains the wrench measurement for every joint (6d vector)[torque, force]\n\tEigen::MatrixXd ft_wrench_measure(robot->num_dofs(), 6);\n\tct = 0;\n\tfor (const auto& f_tq_sens : f_tq_sensors) {\n\t ft_torques_measure.block<1, 3>(ct, 0) = f_tq_sens->torque();\n\t ft_forces_measure.block<1, 3>(ct, 0) = f_tq_sens->force();\n\t ft_wrench_measure.block<1, 6>(ct, 0) = f_tq_sens->wrench();\n\t ct++;\n\t}\n\t```', 'IMU_MEASUREMENT': '\t```cpp\n\tEigen::MatrixXd imu_angular_positions_measure(robot->num_bodies(), 3);\n\tEigen::MatrixXd imu_angular_velocities_measure(robot->num_bodies(), 3);\n\tEigen::MatrixXd imu_linear_acceleration_measure(robot->num_bodies(), 3);\n\tct = 0;\n\tfor (const auto& imu_sens : imu_sensors) {\n\t imu_angular_positions_measure.block<1, 3>(ct, 0) = imu_sens->angular_position_vec();\n\t imu_angular_velocities_measure.block<1, 3>(ct, 0) = imu_sens->angular_velocity();\n\t imu_linear_acceleration_measure.block<1, 3>(ct, 0) = imu_sens->linear_acceleration();\n\t ct++;\n\t}\n\t```', 'RGB_SENSOR': '\t```cpp\n\t// a nested std::vector (w*h*3) of the last image taken can be retrieved\n\tauto rgb_image = camera->image();\n\t```', 'RGB_SENSOR_MEASURE': '\t```cpp\n\t// we can also save them to png\n\trobot_dart::gui::save_png_image("camera-small.png", rgb_image);\n\t// convert an rgb image to grayscale (useful in some cases)\n\tauto gray_image = robot_dart::gui::convert_rgb_to_grayscale(rgb_image);\n\trobot_dart::gui::save_png_image("camera-gray.png", gray_image);\n\t```', 'RGB_D_SENSOR': '\t```cpp\n\t// get the depth image from a camera\n\t// with a version for visualization or bigger differences in the output\n\tauto rgb_d_image = camera->depth_image();\n\t// and the raw values that can be used along with the camera parameters to transform the image to point-cloud\n\tauto rgb_d_image_raw = camera->raw_depth_image();\n\t```', 'RGB_D_SENSOR_MEASURE': '\t```cpp\n\trobot_dart::gui::save_png_image("camera-depth.png", rgb_d_image);\n\trobot_dart::gui::save_png_image("camera-depth-raw.png", rgb_d_image_raw);\n\t```', 'FRANKA': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'PD_CONTROL': '\t```cpp\n\t// add a PD-controller to the arm\n\t// set desired positions\n\tEigen::VectorXd ctrl = robot_dart::make_vector({0., M_PI / 4., 0., -M_PI / 4., 0., M_PI / 2., 0., 0.});\n\t\n\t// add the controller to the robot\n\tauto controller = std::make_shared(ctrl);\n\trobot->add_controller(controller);\n\tcontroller->set_pd(300., 50.);\n\t```', 'ROBOT_CONTROL': '\t```cpp\n\tclass MyController : public robot_dart::control::RobotControl {\n\tpublic:\n\t MyController() : robot_dart::control::RobotControl() {}\n\t\n\t MyController(const Eigen::VectorXd& ctrl, bool full_control) : robot_dart::control::RobotControl(ctrl, full_control) {}\n\t MyController(const Eigen::VectorXd& ctrl, const std::vector& dof_names) : robot_dart::control::RobotControl(ctrl, dof_names) {}\n\t\n\t void configure() override\n\t {\n\t _active = true;\n\t }\n\t\n\t Eigen::VectorXd calculate(double) override\n\t {\n\t auto robot = _robot.lock();\n\t Eigen::VectorXd cmd = 100. * (_ctrl - robot->positions(_controllable_dofs));\n\t return cmd;\n\t }\n\t std::shared_ptr clone() const override\n\t {\n\t return std::make_shared(*this);\n\t }\n\t};\n\t```', 'TALOS': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'RECORD_VIDEO_ROBOT_GRAPHICS_PARAMS': '\t```cpp\n\tgraphics->record_video("talos_dancing.mp4");\n\t```', 'SIMPLE_CONTROL': '\t```cpp\n\tauto controller1 = std::make_shared(ctrl);\n\t// add the controller to the robot, with a default weight of 1.0\n\trobot->add_controller(controller1);\n\t```', 'A1': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'A1_PRINT_IMU': '\t```cpp\n\tstd::cout << "Angular Position: " << robot->imu().angular_position_vec().transpose().format(fmt) << std::endl;\n\tstd::cout << "Angular Velocity: " << robot->imu().angular_velocity().transpose().format(fmt) << std::endl;\n\tstd::cout << "Linear Acceleration: " << robot->imu().linear_acceleration().transpose().format(fmt) << std::endl;\n\tstd::cout << "=================================" << std::endl;\n\t```', 'HEXAPOD': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'HELLO_WORLD_INCLUDE': '\t```cpp\n\t#include \n\t\n\t#ifdef GRAPHIC\n\t#include \n\t#endif\n\t```', 'HELLO_WORLD_ROBOT_CREATION': '\t```cpp\n\tauto robot = std::make_shared("pexod.urdf");\n\t```', 'HELLO_WORLD_ROBOT_PLACING': '\t```cpp\n\trobot->set_base_pose(robot_dart::make_tf({0., 0., 0.2}));\n\t```', 'HELLO_WORLD_ROBOT_SIMU': '\t```cpp\n\trobot_dart::RobotDARTSimu simu(0.001); // dt=0.001, 1KHz simulation\n\tsimu.add_floor();\n\tsimu.add_robot(robot);\n\t```', 'HELLO_WORLD_ROBOT_GRAPHIC': '\t```cpp\n\tauto graphics = std::make_shared();\n\tsimu.set_graphics(graphics);\n\tgraphics->look_at({0.5, 3., 0.75}, {0.5, 0., 0.2});\n\t```', 'HELLO_WORLD_ROBOT_RUN': '\t```cpp\n\tsimu.run(10.);\n\t```', 'TALOS_FAST': '\t```cpp\n\t// load talos fast\n\tauto robot = std::make_shared();\n\t```', 'ADD_NEW_CAMERA': '\t```cpp\n\t// Add camera\n\tauto camera = std::make_shared(graphics->magnum_app(), 256, 256);\n\t```', 'MANIPULATE_CAM_SEP': '\t```cpp\n\tcamera->camera().set_far_plane(5.f);\n\tcamera->camera().set_near_plane(0.01f);\n\tcamera->camera().set_fov(60.0f);\n\t```', 'MANIPULATE_CAM': '\t```cpp\n\tcamera->camera().set_camera_params(5., // far plane\n\t 0.01f, // near plane\n\t 60.0f, // field of view\n\t 600, // width\n\t 400 // height\n\t);\n\t```', 'RECORD_VIDEO_CAMERA': '\t```cpp\n\t// cameras can also record video\n\tcamera->record_video("video-camera.mp4");\n\t```', 'CAM_POSITION': '\t```cpp\n\t// set the position of the camera, and the position where the main camera is looking at\n\tEigen::Vector3d cam_pos = {-0.5, -3., 0.75};\n\tEigen::Vector3d cam_looks_at = {0.5, 0., 0.2};\n\tcamera->look_at(cam_pos, cam_looks_at);\n\t```', 'CAM_ATTACH': '\t```cpp\n\tEigen::Isometry3d tf;\n\ttf = Eigen::AngleAxisd(3.14, Eigen::Vector3d{1., 0., 0.});\n\ttf *= Eigen::AngleAxisd(1.57, Eigen::Vector3d{0., 0., 1.});\n\ttf.translation() = Eigen::Vector3d(0., 0., 0.1);\n\tcamera->attach_to_body(robot->body_node("iiwa_link_ee"), tf); // cameras are looking towards -z by default\n\t```', 'ROBOT_POOL_INCLUDE': '\t```cpp\n\t#include \n\t```', 'ROBOT_POOL_GLOBAL_NAMESPACE': '\t```cpp\n\tnamespace pool {\n\t // This function should load one robot: here we load Talos\n\t inline std::shared_ptr robot_creator()\n\t {\n\t return std::make_shared();\n\t }\n\t\n\t // To create the object we need to pass the robot_creator function and the number of maximum parallel threads\n\t robot_dart::RobotPool robot_pool(robot_creator, NUM_THREADS);\n\t} // namespace pool\n\t```', 'ROBOT_POOL_EVAL': '\t```cpp\n\tinline void eval_robot(int i)\n\t{\n\t // We get one available robot\n\t auto robot = pool::robot_pool.get_robot();\n\t std::cout << "Robot " << i << " got [" << robot->skeleton() << "]" << std::endl;\n\t\n\t /// --- some robot_dart code ---\n\t simulate_robot(robot);\n\t // --- do something with the result\n\t\n\t std::cout << "End of simulation " << i << std::endl;\n\t\n\t // CRITICAL : free your robot !\n\t pool::robot_pool.free_robot(robot);\n\t\n\t std::cout << "Robot " << i << " freed!" << std::endl;\n\t}\n\t```', 'ROBOT_POOL_CREATE_THREADS': '\t```cpp\n\t// for the example, we run NUM_THREADS threads of eval_robot()\n\tstd::vector threads(NUM_THREADS * 2); // *2 to see some reuse\n\tfor (size_t i = 0; i < threads.size(); ++i)\n\t threads[i] = std::thread(eval_robot, i); // eval_robot is the function that uses the robot\n\t```', 'KINEMATICS': '\t```cpp\n\t// Get Joint Positions(Angles)\n\tauto joint_positions = robot->positions();\n\t\n\t// Get Joint Velocities\n\tauto joint_vels = robot->velocities();\n\t\n\t// Get Joint Accelerations\n\tauto joint_accs = robot->accelerations();\n\t\n\t// Get link_name(str) Transformation matrix with respect to the world frame.\n\tauto eef_tf = robot->body_pose(link_name);\n\t\n\t// Get translation vector from transformation matrix\n\tauto eef_pos = eef_tf.translation();\n\t\n\t// Get rotation matrix from tranformation matrix\n\tauto eef_rot = eef_tf.rotation();\n\t\n\t// Get link_name 6d pose vector [logmap(eef_tf.linear()), eef_tf.translation()]\n\tauto eef_pose_vec = robot->body_pose_vec(link_name);\n\t\n\t// Get link_name 6d velocity vector [angular, cartesian]\n\tauto eef_vel = robot->body_velocity(link_name);\n\t\n\t// Get link_name 6d acceleration vector [angular, cartesian]\n\tauto eef_acc = robot->body_acceleration(link_name);\n\t\n\t// Jacobian targeting the origin of link_name(str)\n\tauto jacobian = robot->jacobian(link_name);\n\t\n\t// Jacobian time derivative\n\tauto jacobian_deriv = robot->jacobian_deriv(link_name);\n\t\n\t// Center of Mass Jacobian\n\tauto com_jacobian = robot->com_jacobian();\n\t\n\t// Center of Mass Jacobian Time Derivative\n\tauto com_jacobian_deriv = robot->com_jacobian_deriv();\n\t```', 'DYNAMICS': "\t```cpp\n\t// Get Joint Forces\n\tauto joint_forces = robot->forces();\n\t\n\t// Get link's mass\n\tauto eef_mass = robot->body_mass(link_name);\n\t\n\t// Mass Matrix of robot\n\tauto mass_matrix = robot->mass_matrix();\n\t\n\t// Inverse of Mass Matrix\n\tauto inv_mass_matrix = robot->inv_mass_matrix();\n\t\n\t// Augmented Mass matrix\n\tauto aug_mass_matrix = robot->aug_mass_matrix();\n\t\n\t// Inverse of Augmented Mass matrix\n\tauto inv_aug_mass_matrix = robot->inv_aug_mass_matrix();\n\t\n\t// Coriolis Force vector\n\tauto coriolis = robot->coriolis_forces();\n\t\n\t// Gravity Force vector\n\tauto gravity = robot->gravity_forces();\n\t\n\t// Combined vector of Coriolis Force and Gravity Force\n\tauto coriolis_gravity = robot->coriolis_gravity_forces();\n\t\n\t// Constraint Force Vector\n\tauto constraint_forces = robot->constraint_forces();\n\t```", 'IIWA': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'ROBOT_GHOST': '\t```cpp\n\t// Add a ghost robot; only visuals, no dynamics, no collision\n\tauto ghost = robot->clone_ghost();\n\tsimu.add_robot(ghost);\n\t```', 'LOAD_IICUB_PYTHON': '\t```python\n\trobot = rd.ICub()\n\t\n\t# Set actuator types to VELOCITY motors so that they stay in position without any controller\n\trobot.set_actuator_types("velocity")\n\tsimu = rd.RobotDARTSimu(0.001)\n\tsimu.set_collision_detector("fcl")\n\t```', 'ICUB_PRINT_IMU_PYTHON': '\t```python\n\tprint("Angular Position: ", robot.imu().angular_position_vec().transpose())\n\tprint("Angular Velocity: ", robot.imu().angular_velocity().transpose())\n\tprint("Linear Acceleration: ", robot.imu().linear_acceleration().transpose())\n\tprint("=================================" )\n\t```', 'ICUB_PRINT_FT_PYTHON': '\t```python\n\tprint("FT ( force): ", robot.ft_foot_left().force().transpose())\n\tprint("FT (torque): ", robot.ft_foot_left().torque().transpose())\n\tprint("=================================")\n\t```', 'CAMERAS_PARALLEL_PYTHON': '\t```python\n\trobot = rd.Robot("arm.urdf", "arm", False)\n\trobot.fix_to_world()\n\t\n\tdef test():\n\t pid = os.getpid()\n\t ii = pid%15\n\t\n\t # create the controller\n\t pdcontrol = rd.PDControl([0.0, 1.0, -1.5, 1.0], False)\n\t\n\t # clone the robot\n\t grobot = robot.clone()\n\t\n\t # add the controller to the robot\n\t grobot.add_controller(pdcontrol, 1.)\n\t pdcontrol.set_pd(200., 20.)\n\t\n\t # create the simulation object\n\t simu = rd.RobotDARTSimu(0.001)\n\t\n\t # set the graphics\n\t graphics = rd.gui.WindowlessGraphics()\n\t simu.set_graphics(graphics)\n\t\n\t graphics.look_at([0.4 * ii, 3.5 - ii * 0.1, 2.], [0., 0., 0.25], [0., 0., 1.])\n\t\n\t # add the robot and the floor\n\t simu.add_robot(grobot)\n\t simu.add_checkerboard_floor()\n\t\n\t # run\n\t simu.run(20.)\n\t\n\t # save last frame for visualization purposes\n\t img = graphics.image()\n\t rd.gui.save_png_image(\'camera-\' + str(ii) + \'.png\', img)\n\t\n\t# helper function to run in parallel\n\tdef runInParallel(N):\n\t proc = []\n\t for i in range(N):\n\t # rd.gui.run_with_gl_context accepts 2 parameters:\n\t # (func, wait_time_in_ms)\n\t # the func needs to be of the following format: void(), aka no return, no arguments\n\t p = Process(target=rd.gui.run_with_gl_context, args=(test, 20))\n\t p.start()\n\t proc.append(p)\n\t for p in proc:\n\t p.join()\n\t\n\tprint(\'Running parallel evaluations\')\n\tN = 15\n\tstart = timer()\n\trunInParallel(N)\n\tend = timer()\n\tprint(\'Time:\', end-start)\n\t```', 'SIMPLE_CONTROL_PYTHON': '\t```python\n\tcontroller1 = rd.SimpleControl(ctrl)\n\t# add the controller to the robot, with a default weight of 1.0\n\trobot.add_controller(controller1)\n\t```', 'INIT_SIMU_PYTHON': '\t```python\n\t# choose time step of 0.001 seconds\n\tsimu = rd.RobotDARTSimu(0.001)\n\t```', 'MODIFY_SIMU_DT_PYTHON': '\t```python\n\t# set timestep to 0.005 and update control frequency(bool)\n\tsimu.set_timestep(0.005, True)\n\t```', 'SIMU_GRAVITY_PYTHON': '\t```python\n\t# set gravitational force of mars\n\tmars_gravity = [0., 0., -3.721]\n\tsimu.set_gravity(mars_gravity)\n\t```', 'GRAPHICS_PARAMS_PYTHON': '\t```python\n\tconfiguration = rd.gui.GraphicsConfiguration()\n\t# We can change the width/height of the window (or camera, dimensions)\n\tconfiguration.width = 1280\n\tconfiguration.height = 960\n\tconfiguration.title = "Graphics Tutorial" # We can set a title for our window\n\t\n\t# We can change the configuration for shadows\n\tconfiguration.shadowed = True\n\tconfiguration.transparent_shadows = True\n\tconfiguration.shadow_map_size = 1024\n\t\n\t# We can also alter some specifications for the lighting\n\tconfiguration.max_lights = 3 # maximum number of lights for our scene\n\tconfiguration.specular_strength = 0.25 # strength og the specular component\n\t\n\t# Some extra configuration for the main camera\n\tconfiguration.draw_main_camera = True\n\tconfiguration.draw_debug = True\n\tconfiguration.draw_text = True\n\t\n\t# We can also change the background color [default = black]\n\tconfiguration.bg_color = [1., 1., 1., 1.]\n\t\n\t# create the graphics object with the configuration as a parameter\n\tgraphics = rd.gui.Graphics(configuration)\n\t```', 'SHADOWS_GRAPHICS_PYTHON': '\t```python\n\t# Disable shadows\n\tgraphics.enable_shadows(False, False)\n\tsimu.run(1.)\n\t# Enable shadows only for non-transparent objects\n\tgraphics.enable_shadows(True, False)\n\tsimu.run(1.)\n\t# Enable shadows for transparent objects as well\n\tgraphics.enable_shadows(True, True)\n\tsimu.run(1.)\n\t```', 'CLR_LIGHT_PYTHON': '\t```python\n\t# Clear Lights\n\tgraphics.clear_lights()\n\t```', 'LIGHT_MATERIAL_PYTHON': '\t```python\n\t# Clear Light material\n\tshininess = 1000.\n\twhite = magnum.Color4(1., 1., 1., 1.)\n\t\n\t# ambient, diffuse, specular\n\tcustom_material = rd.gui.Material(white, white, white, shininess)\n\t```', 'POINT_LIGHT_PYTHON': '\t```python\n\t# Create point light\n\tposition = magnum.Vector3(0., 0., 2.)\n\tintensity = 1.\n\tattenuation_terms = magnum.Vector3(1., 0., 0.)\n\tpoint_light = rd.gui.create_point_light(position, custom_material, intensity, attenuation_terms)\n\tgraphics.add_light(point_light)\n\t```', 'DIRECTIONAL_LIGHT_PYTHON': '\t```python\n\t# Create directional light\n\tdirection = magnum.Vector3(-1, -1, -1)\n\tdirectional_light = rd.gui.create_directional_light(direction, custom_material)\n\tgraphics.add_light(directional_light)\n\t```', 'SPOT_LIGHT_PYTHON': '\t```python\n\t# Create spot light\n\tposition = magnum.Vector3(0., 0., 1.)\n\tdirection = magnum.Vector3(-1, -1, -1)\n\tintensity = 1.\n\tattenuation_terms = magnum.Vector3(1., 0., 0.)\n\tspot_exponent = np.pi\n\tspot_cut_off = np.pi / 8\n\tspot_light = rd.gui.create_spot_light(position, custom_material, direction, spot_exponent, spot_cut_off, intensity, attenuation_terms)\n\tgraphics.add_light(spot_light)\n\t```', 'SET_COLLISION_DETECTOR_PYTHON': '\t```python\n\tsimu.set_collision_detector("fcl") # collision_detector can be "dart", "fcl", "ode" or "bullet" (case does not matter)\n\t```', 'SELF_COLLISIONS_PYTHON': '\t```python\n\tif(not robot.self_colliding()):\n\t print("Self collision is not enabled")\n\t # set self collisions to true and adjacent collisions to false\n\t robot.set_self_collision(True, False)\n\t```', 'ROBOT_CONTROL_PYTHON': '\t```python\n\tclass MyController(rd.RobotControl):\n\t def __init__(self, ctrl, full_control):\n\t rd.RobotControl.__init__(self, ctrl, full_control)\n\t\n\t def __init__(self, ctrl, controllable_dofs):\n\t rd.RobotControl.__init__(self, ctrl, controllable_dofs)\n\t\n\t def configure(self):\n\t self._active = True\n\t\n\t def calculate(self, t):\n\t target = np.array([self._ctrl])\n\t cmd = 100*(target-self.robot().positions(self._controllable_dofs))\n\t return cmd[0]\n\t\n\t # TO-DO: This is NOT working at the moment!\n\t def clone(self):\n\t return MyController(self._ctrl, self._controllable_dofs)\n\t```', 'SET_ACTUATOR_PYTHON': '\t```python\n\t# Set all DoFs to same actuator\n\t# actuator types can be "servo", "torque", "velocity", "passive", "locked", "mimic"\n\trobot.set_actuator_types("servo")\n\t# You can also set actuator types separately\n\trobot.set_actuator_type("torque", "iiwa_joint_5")\n\t```', 'POSITIONS_ENFORCED_PYTHON': '\t```python\n\t# Εnforce joint position and velocity limits\n\trobot.set_position_enforced(True)\n\t```', 'MODIFY_LIMITS_PYTHON': '\t```python\n\t# Modify Position Limits\n\tpos_upper_lims = np.array([2.096, 2.096, 2.096, 2.096, 2.096, 2.096, 2.096])\n\trobot.set_position_upper_limits(pos_upper_lims, dof_names)\n\trobot.set_position_lower_limits(-1*pos_upper_lims, dof_names)\n\t\n\t# Modify Velocity Limits\n\tvel_upper_lims = np.array([1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5])\n\t\n\trobot.set_velocity_upper_limits(vel_upper_lims, dof_names)\n\trobot.set_velocity_lower_limits(-1*vel_upper_lims, dof_names)\n\t\n\t# Modify Force Limits\n\tforce_upper_lims = np.array([150, 150, 150, 150, 150, 150, 150])\n\trobot.set_force_upper_limits(force_upper_lims, dof_names)\n\trobot.set_force_lower_limits(-1*force_upper_lims, dof_names)\n\t\n\t# Modify Acceleration Limits\n\tacc_upper_lims = np.array([1500, 1500, 1500, 1500, 1500, 1500, 1500])\n\trobot.set_acceleration_upper_limits(acc_upper_lims, dof_names)\n\trobot.set_acceleration_lower_limits(-1*acc_upper_lims, dof_names)\n\t```', 'MODIFY_COEFFS_PYTHON': '\t```python\n\t# Modify Damping Coefficients\n\tdamps = [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]\n\trobot.set_damping_coeffs(damps, dof_names)\n\t\n\t# Modify Coulomb Frictions\n\tcfrictions = [0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001]\n\trobot.set_coulomb_coeffs(cfrictions, dof_names)\n\t\n\t# Modify Spring Stiffness\n\tstiffnesses = [0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001]\n\trobot.set_spring_stiffnesses(stiffnesses, dof_names)\n\t```', 'IIWA_PYTHON': '\t```python\n\trobot = rd.Iiwa()\n\t```', 'ROBOT_GHOST_PYTHON': '\t```python\n\t# Add a ghost robot; only visuals, no dynamics, no collision\n\tghost = robot.clone_ghost()\n\tsimu.add_robot(ghost)\n\t```', 'HEXAPOD_PYTHON': '\t```python\n\trobot = rd.Hexapod()\n\t```', 'TALOS_FAST_PYTHON': '\t```python\n\trobot = rd.TalosFastCollision()\n\t```', 'RECORD_VIDEO_ROBOT_GRAPHICS_PARAMS_PYTHON': '\t```python\n\tgraphics.record_video("talos_dancing.mp4")\n\t```', 'SIMPLE_ARM_PYTHON': '\t```python\n\trobot = rd.Arm()\n\t```', 'A1_PYTHON': '\t```python\n\trobot = rd.A1()\n\t```', 'A1_PRINT_IMU_PYTHON': '\t```python\n\tprint( "Angular Position: ", robot.imu().angular_position_vec().transpose())\n\tprint( "Angular Velocity: ", robot.imu().angular_velocity().transpose())\n\tprint( "Linear Acceleration: ", robot.imu().linear_acceleration().transpose())\n\tprint( "=================================")\n\t```', 'CAMERA_SENSOR_RGBD_RECORD_DEPTH_PYTHON': '\t```python\n\t# cameras are recording color images by default, enable depth images as well for this example\n\tcamera.camera().record(True, True)\n\t```', 'TORQUE_SENSOR_PYTHON': '\t```python\n\t# Add torque sensors to the robot\n\ttq_sensors = np.empty(robot.num_dofs(), dtype=rd.sensor.Torque)\n\tct = 0\n\tfor joint in robot.dof_names():\n\t simu.add_sensor(rd.sensor.Torque(robot, joint, 1000))\n\t tq_sensors[ct] = simu.sensors()[-1]\n\t ct += 1\n\t```', 'FORCE_TORQUE_SENSOR_PYTHON': '\t```python\n\t# Add force-torque sensors to the robot\n\tf_tq_sensors = np.empty(robot.num_dofs(), dtype=rd.sensor.ForceTorque)\n\tct = 0\n\tfor joint in robot.dof_names():\n\t simu.add_sensor(rd.sensor.ForceTorque(\n\t robot, joint, 1000, "parent_to_child"))\n\t f_tq_sensors[ct] = simu.sensors()[-1]\n\t print(f_tq_sensors)\n\t ct += 1\n\t```', 'IMU_SENSOR_PYTHON': '\t```python\n\t# Add IMU sensors to the robot\n\tct = 0\n\timu_sensors = np.empty(robot.num_bodies(), dtype=rd.sensor.IMU)\n\tfor body_node in robot.body_names():\n\t simu.add_sensor(rd.sensor.IMU(\n\t rd.sensor.IMUConfig(robot.body_node(body_node), 1000)))\n\t imu_sensors[ct] = simu.sensors()[-1]\n\t ct += 1\n\t```', 'TORQUE_MEASUREMENT_PYTHON': '\t```python\n\t# vector that contains the torque measurement for every joint (scalar)\n\ttorques_measure = np.empty(robot.num_dofs())\n\tct = 0\n\tfor tq_sens in tq_sensors:\n\t torques_measure[ct] = tq_sens.torques()\n\t ct += 1\n\t```', 'FORCE_TORQUE_MEASUREMENT_PYTHON': '\t```python\n\t# matrix that contains the torque measurement for every joint (3d vector)\n\tft_torques_measure = np.empty([robot.num_dofs(), 3])\n\t# matrix that contains the force measurement for every joint (3d vector)\n\tft_forces_measure = np.empty([robot.num_dofs(), 3])\n\t# matrix that contains the wrench measurement for every joint (6d vector)[torque, force]\n\tft_wrench_measure = np.empty([robot.num_dofs(), 6])\n\tct = 0\n\tfor f_tq_sens in f_tq_sensors:\n\t ft_torques_measure[ct, :] = f_tq_sens.torque()\n\t ft_forces_measure[ct, :] = f_tq_sens.force()\n\t ft_wrench_measure[ct, :] = f_tq_sens.wrench()\n\t ct += 1\n\t\n\t```', 'IMU_MEASUREMENT_PYTHON': '\t```python\n\timu_angular_positions_measure = np.empty([robot.num_bodies(), 3])\n\timu_angular_velocities_measure = np.empty([robot.num_bodies(), 3])\n\timu_linear_acceleration_measure = np.empty([robot.num_bodies(), 3])\n\tct = 0\n\tfor imu_sens in imu_sensors:\n\t imu_angular_positions_measure[ct,:] = imu_sens.angular_position_vec()\n\t imu_angular_velocities_measure[ct, :] = imu_sens.angular_velocity()\n\t imu_linear_acceleration_measure[ct,:] = imu_sens.linear_acceleration()\n\t ct += 1\n\t\n\t```', 'RGB_SENSOR_PYTHON': '\t```python\n\t# a nested array (w*h*3) of the last image taken can be retrieved\n\trgb_image = camera.image()\n\t```', 'RGB_SENSOR_MEASURE_PYTHON': '\t```python\n\t# we can also save them to png\n\trd.gui.save_png_image("camera-small.png", rgb_image)\n\t# convert an rgb image to grayscale (useful in some cases)\n\tgray_image = rd.gui.convert_rgb_to_grayscale(rgb_image)\n\trd.gui.save_png_image("camera-gray.png", gray_image)\n\t```', 'RGB_D_SENSOR_PYTHON': '\t```python\n\t# get the depth image from a camera\n\t# with a version for visualization or bigger differences in the output\n\trgb_d_image = camera.depth_image()\n\t# and the raw values that can be used along with the camera parameters to transform the image to point-cloud\n\trgb_d_image_raw = camera.raw_depth_image()\n\t```', 'RGB_D_SENSOR_MEASURE_PYTHON': '\t```python\n\trd.gui.save_png_image("camera-depth.png", rgb_d_image)\n\trd.gui.save_png_image("camera-depth-raw.png", rgb_d_image_raw)\n\t```', 'FRANKA_PYTHON': '\t```python\n\trobot = rd.Franka()\n\t```', 'PD_CONTROL_PYTHON': '\t```python\n\t# add a PD-controller to the arm\n\t# set desired positions\n\tctrl = [0., np.pi / 4., 0., -np.pi / 4., 0., np.pi / 2., 0., 0.]\n\t\n\t# add the controller to the robot\n\tcontroller = rd.PDControl(ctrl)\n\trobot.add_controller(controller)\n\tcontroller.set_pd(300., 50.)\n\t```', 'TALOS_PYTHON': '\t```python\n\trobot = rd.Talos()\n\t```', 'KINEMATICS_PYTHON': '\t```python\n\t# Get Joint Positions(Angles)\n\tjoint_positions = robot.positions()\n\t\n\t# Get Joint Velocities\n\tjoint_vels = robot.velocities()\n\t\n\t# Get Joint Accelerations\n\tjoint_accs = robot.accelerations()\n\t\n\t# Get link_name(str) Transformation matrix with respect to the world frame.\n\teef_tf = robot.body_pose(link_name)\n\t\n\t# Get translation vector from transformation matrix\n\teef_pos = eef_tf.translation()\n\t\n\t# Get rotation matrix from tranformation matrix\n\teef_rot = eef_tf.rotation()\n\t\n\t# Get link_name 6d pose vector [logmap(eef_tf.linear()), eef_tf.translation()]\n\teef_pose_vec = robot.body_pose_vec(link_name)\n\t\n\t# Get link_name 6d velocity vector [angular, cartesian]\n\teef_vel = robot.body_velocity(link_name)\n\t\n\t# Get link_name 6d acceleration vector [angular, cartesian]\n\teef_acc = robot.body_acceleration(link_name)\n\t\n\t# Jacobian targeting the origin of link_name(str)\n\tjacobian = robot.jacobian(link_name)\n\t\n\t# Jacobian time derivative\n\tjacobian_deriv = robot.jacobian_deriv(link_name)\n\t\n\t# Center of Mass Jacobian\n\tcom_jacobian = robot.com_jacobian()\n\t\n\t# Center of Mass Jacobian Time Derivative\n\tcom_jacobian_deriv = robot.com_jacobian_deriv()\n\t```', 'DYNAMICS_PYTHON': "\t```python\n\t# Get Joint Forces\n\tjoint_forces = robot.forces()\n\t\n\t# Get link's mass\n\teef_mass = robot.body_mass(link_name)\n\t\n\t# Mass Matrix of robot\n\tmass_matrix = robot.mass_matrix()\n\t\n\t# Inverse of Mass Matrix\n\tinv_mass_matrix = robot.inv_mass_matrix()\n\t\n\t# Augmented Mass matrix\n\taug_mass_matrix = robot.aug_mass_matrix()\n\t\n\t# Inverse of Augmented Mass matrix\n\tinv_aug_mass_matrix = robot.inv_aug_mass_matrix()\n\t\n\t# Coriolis Force vector\n\tcoriolis = robot.coriolis_forces()\n\t\n\t# Gravity Force vector\n\tgravity = robot.gravity_forces()\n\t\n\t# Combined vector of Coriolis Force and Gravity Force\n\tcoriolis_gravity = robot.coriolis_gravity_forces()\n\t\n\t# NOT IMPLEMENTED\n\t# # Constraint Force Vector\n\t# constraint_forces = robot.constraint_forces()\n\t\n\t```", 'ADD_NEW_CAMERA_PYTHON': '\t```python\n\t# Add camera\n\tcamera = rd.sensor.Camera(graphics.magnum_app(), 32, 32)\n\t```', 'MANIPULATE_CAM_SEP_PYTHON': '\t```python\n\tcamera.camera().set_far_plane(5.)\n\tcamera.camera().set_near_plane(0.01)\n\tcamera.camera().set_fov(60.0)\n\t```', 'MANIPULATE_CAM_PYTHON': '\t```python\n\tcamera.camera().set_camera_params(5., # far plane\n\t 0.01, # near plane\n\t 60.0, # field of view\n\t 600, # width\n\t 400) # height\n\t```', 'RECORD_VIDEO_CAMERA_PYTHON': '\t```python\n\t\n\t# cameras can also record video\n\tcamera.record_video("video-camera.mp4")\n\t```', 'CAM_POSITION_PYTHON': '\t```python\n\t# set the position of the camera, and the position where the main camera is looking at\n\tcam_pos = [-0.5, -3., 0.75]\n\tcam_looks_at = [0.5, 0., 0.2]\n\tcamera.look_at(cam_pos, cam_looks_at)\n\t```', 'CAM_ATTACH_PYTHON': '\t```python\n\ttf = dartpy.math.Isometry3()\n\trot = dartpy.math.AngleAxis(3.14, [1., 0., 0.])\n\trot = rot.multiply(dartpy.math.AngleAxis(1.57, [0., 0., 1.])).to_rotation_matrix()\n\ttf.set_translation([0., 0., 0.1])\n\ttf.set_rotation(rot)\n\tcamera.attach_to_body(robot.body_node("iiwa_link_ee"), tf) # cameras are looking towards -z by default\n\t```', 'HELLO_WORLD_INCLUDE_PYTHON': '\t```python\n\timport RobotDART as rd\n\t```', 'HELLO_WORLD_ROBOT_CREATION_PYTHON': '\t```python\n\trobot = rd.Robot("pexod.urdf");\n\t```', 'HELLO_WORLD_ROBOT_PLACING_PYTHON': '\t```python\n\t# pose is a 6D vector (first 3D orientation in angle-axis and last 3D translation)\n\trobot.set_base_pose([0., 0., 0., 0., 0., 0.2])\n\t```', 'HELLO_WORLD_ROBOT_SIMU_PYTHON': '\t```python\n\tsimu = rd.RobotDARTSimu(0.001); # dt=0.001, 1KHz simulation\n\tsimu.add_floor();\n\tsimu.add_robot(robot);\n\t```', 'HELLO_WORLD_ROBOT_GRAPHIC_PYTHON': '\t```python\n\tgraphics = rd.gui.Graphics()\n\tsimu.set_graphics(graphics)\n\tgraphics.look_at([0.5, 3., 0.75], [0.5, 0., 0.2])\n\t```', 'HELLO_WORLD_ROBOT_RUN_PYTHON': '\t```python\n\tsimu.run(10.)\n\t```'} + variables = {'TALOS_FAST': '\t```cpp\n\t// load talos fast\n\tauto robot = std::make_shared();\n\t```', 'A1': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'A1_PRINT_IMU': '\t```cpp\n\tstd::cout << "Angular Position: " << robot->imu().angular_position_vec().transpose().format(fmt) << std::endl;\n\tstd::cout << "Angular Velocity: " << robot->imu().angular_velocity().transpose().format(fmt) << std::endl;\n\tstd::cout << "Linear Acceleration: " << robot->imu().linear_acceleration().transpose().format(fmt) << std::endl;\n\tstd::cout << "=================================" << std::endl;\n\t```', 'FRANKA': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'PD_CONTROL': '\t```cpp\n\t// add a PD-controller to the arm\n\t// set desired positions\n\tEigen::VectorXd ctrl = robot_dart::make_vector({0., M_PI / 4., 0., -M_PI / 4., 0., M_PI / 2., 0., 0.});\n\t\n\t// add the controller to the robot\n\tauto controller = std::make_shared(ctrl);\n\trobot->add_controller(controller);\n\tcontroller->set_pd(300., 50.);\n\t```', 'TIAGO': '\t```cpp\n\tauto robot = std::make_shared(freq);\n\t```', 'IIWA': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'ROBOT_GHOST': '\t```cpp\n\t// Add a ghost robot; only visuals, no dynamics, no collision\n\tauto ghost = robot->clone_ghost();\n\tsimu.add_robot(ghost);\n\t```', 'CAMERAS_PARALLEL': '\t```cpp\n\t// Load robot from URDF\n\tauto global_robot = std::make_shared();\n\t\n\tstd::vector workers;\n\t\n\t// Set maximum number of parallel GL contexts (this is GPU-dependent)\n\trobot_dart::gui::magnum::GlobalData::instance()->set_max_contexts(4);\n\t\n\t// We want 15 parallel simulations with different GL context each\n\tsize_t N_workers = 15;\n\tstd::mutex mutex;\n\tsize_t id = 0;\n\t// Launch the workers\n\tfor (size_t i = 0; i < N_workers; i++) {\n\t workers.push_back(std::thread([&] {\n\t mutex.lock();\n\t size_t index = id++;\n\t mutex.unlock();\n\t\n\t // Get the GL context -- this is a blocking call\n\t // will wait until one GL context is available\n\t // get_gl_context(gl_context); // this call will not sleep between failed queries\n\t get_gl_context_with_sleep(gl_context, 20); // this call will sleep 20ms between each failed query\n\t\n\t // Do the simulation\n\t auto robot = global_robot->clone();\n\t\n\t robot_dart::RobotDARTSimu simu(0.001);\n\t\n\t Eigen::VectorXd ctrl = robot_dart::make_vector({0., M_PI / 3., 0., -M_PI / 4., 0., 0., 0.});\n\t\n\t auto controller = std::make_shared(ctrl);\n\t robot->add_controller(controller);\n\t controller->set_pd(300., 50.);\n\t\n\t // Magnum graphics\n\t robot_dart::gui::magnum::GraphicsConfiguration configuration = robot_dart::gui::magnum::WindowlessGraphics::default_configuration();\n\t\n\t configuration.width = 1024;\n\t configuration.height = 768;\n\t auto graphics = std::make_shared(configuration);\n\t simu.set_graphics(graphics);\n\t // Position the camera differently for each thread to visualize the difference\n\t graphics->look_at({0.4 * index, 3.5 - index * 0.1, 2.}, {0., 0., 0.25});\n\t // record images from main camera/graphics\n\t // graphics->set_recording(true); // WindowlessGLApplication records images by default\n\t\n\t simu.add_robot(robot);\n\t simu.run(6);\n\t\n\t // Save the image for verification\n\t robot_dart::gui::save_png_image("camera_" + std::to_string(index) + ".png",\n\t graphics->image());\n\t\n\t // Release the GL context for another thread to use\n\t release_gl_context(gl_context);\n\t }));\n\t}\n\t\n\t// Wait for all the workers\n\tfor (size_t i = 0; i < workers.size(); i++) {\n\t workers[i].join();\n\t}\n\t```', 'INIT_SIMU': '\t```cpp\n\t// choose time step of 0.001 seconds\n\trobot_dart::RobotDARTSimu simu(0.001);\n\t```', 'MODIFY_SIMU_DT': '\t```cpp\n\t// set timestep to 0.005 and update control frequency(bool)\n\tsimu.set_timestep(0.005, true);\n\t```', 'SIMU_GRAVITY': '\t```cpp\n\t// Set gravitational force of mars\n\tEigen::Vector3d mars_gravity = {0., 0., -3.721};\n\tsimu.set_gravity(mars_gravity);\n\t```', 'GRAPHICS_PARAMS': '\t```cpp\n\trobot_dart::gui::magnum::GraphicsConfiguration configuration;\n\t// We can change the width/height of the window (or camera image dimensions)\n\tconfiguration.width = 1280;\n\tconfiguration.height = 960;\n\tconfiguration.title = "Graphics Tutorial"; // We can set a title for our window\n\t\n\t// We can change the configuration for shadows\n\tconfiguration.shadowed = true;\n\tconfiguration.transparent_shadows = true;\n\tconfiguration.shadow_map_size = 1024;\n\t\n\t// We can also alter some specifications for the lighting\n\tconfiguration.max_lights = 3; // maximum number of lights for our scene [default=3]\n\tconfiguration.specular_strength = 0.25; // strength of the specular component\n\t\n\t// Some extra configuration for the main camera\n\tconfiguration.draw_main_camera = true;\n\tconfiguration.draw_debug = true;\n\tconfiguration.draw_text = true;\n\t\n\t// We can also change the background color [default=black]\n\tconfiguration.bg_color = Eigen::Vector4d{1.0, 1.0, 1.0, 1.0};\n\t\n\t// Create the graphics object with the configuration as parameter\n\tauto graphics = std::make_shared(configuration);\n\t```', 'SHADOWS_GRAPHICS': '\t```cpp\n\t// Disable shadows\n\tgraphics->enable_shadows(false, false);\n\tsimu.run(1.);\n\t// Enable shadows only for non-transparent objects\n\tgraphics->enable_shadows(true, false);\n\tsimu.run(1.);\n\t// Enable shadows for transparent objects as well\n\tgraphics->enable_shadows(true, true);\n\tsimu.run(1.);\n\t```', 'CLR_LIGHT': '\t```cpp\n\t// Clear Lights\n\tgraphics->clear_lights();\n\t```', 'LIGHT_MATERIAL': '\t```cpp\n\t// Create Light material\n\tMagnum::Float shininess = 1000.f;\n\tMagnum::Color4 white = {1.f, 1.f, 1.f, 1.f};\n\t\n\t// ambient, diffuse, specular\n\tauto custom_material = robot_dart::gui::magnum::gs::Material(white, white, white, shininess);\n\t```', 'POINT_LIGHT': '\t```cpp\n\t// Create point light\n\tMagnum::Vector3 position = {0.f, 0.f, 2.f};\n\tMagnum::Float intensity = 1.f;\n\tMagnum::Vector3 attenuation_terms = {1.f, 0.f, 0.f};\n\tauto point_light = robot_dart::gui::magnum::gs::create_point_light(position, custom_material, intensity, attenuation_terms);\n\tgraphics->add_light(point_light);\n\t```', 'DIRECTIONAL_LIGHT': '\t```cpp\n\t// Create directional light\n\tMagnum::Vector3 direction = {-1.f, -1.f, -1.f};\n\tauto directional_light = robot_dart::gui::magnum::gs::create_directional_light(direction, custom_material);\n\tgraphics->add_light(directional_light);\n\t```', 'SPOT_LIGHT': '\t```cpp\n\t// Create spot light\n\tMagnum::Vector3 position = {0.f, 0.f, 1.f};\n\tMagnum::Vector3 direction = {-1.f, -1.f, -1.f};\n\tMagnum::Float intensity = 1.f;\n\tMagnum::Vector3 attenuation_terms = {1.f, 0.f, 0.f};\n\tMagnum::Float spot_exponent = M_PI;\n\tMagnum::Float spot_cut_off = M_PI / 8;\n\tauto spot_light = robot_dart::gui::magnum::gs::create_spot_light(position, custom_material, direction, spot_exponent, spot_cut_off, intensity, attenuation_terms);\n\tgraphics->add_light(spot_light);\n\t```', 'ADD_NEW_CAMERA': '\t```cpp\n\t// Add camera\n\tauto camera = std::make_shared(graphics->magnum_app(), 256, 256);\n\t```', 'MANIPULATE_CAM_SEP': '\t```cpp\n\tcamera->camera().set_far_plane(5.f);\n\tcamera->camera().set_near_plane(0.01f);\n\tcamera->camera().set_fov(60.0f);\n\t```', 'MANIPULATE_CAM': '\t```cpp\n\tcamera->camera().set_camera_params(5., // far plane\n\t 0.01f, // near plane\n\t 60.0f, // field of view\n\t 600, // width\n\t 400 // height\n\t);\n\t```', 'RECORD_VIDEO_CAMERA': '\t```cpp\n\t// cameras can also record video\n\tcamera->record_video("video-camera.mp4");\n\t```', 'CAM_POSITION': '\t```cpp\n\t// set the position of the camera, and the position where the main camera is looking at\n\tEigen::Vector3d cam_pos = {-0.5, -3., 0.75};\n\tEigen::Vector3d cam_looks_at = {0.5, 0., 0.2};\n\tcamera->look_at(cam_pos, cam_looks_at);\n\t```', 'CAM_ATTACH': '\t```cpp\n\tEigen::Isometry3d tf;\n\ttf = Eigen::AngleAxisd(3.14, Eigen::Vector3d{1., 0., 0.});\n\ttf *= Eigen::AngleAxisd(1.57, Eigen::Vector3d{0., 0., 1.});\n\ttf.translation() = Eigen::Vector3d(0., 0., 0.1);\n\tcamera->attach_to_body(robot->body_node("iiwa_link_ee"), tf); // cameras are looking towards -z by default\n\t```', 'ROBOT_POOL_INCLUDE': '\t```cpp\n\t#include \n\t```', 'ROBOT_POOL_GLOBAL_NAMESPACE': '\t```cpp\n\tnamespace pool {\n\t // This function should load one robot: here we load Talos\n\t inline std::shared_ptr robot_creator()\n\t {\n\t return std::make_shared();\n\t }\n\t\n\t // To create the object we need to pass the robot_creator function and the number of maximum parallel threads\n\t robot_dart::RobotPool robot_pool(robot_creator, NUM_THREADS);\n\t} // namespace pool\n\t```', 'ROBOT_POOL_EVAL': '\t```cpp\n\tinline void eval_robot(int i)\n\t{\n\t // We get one available robot\n\t auto robot = pool::robot_pool.get_robot();\n\t std::cout << "Robot " << i << " got [" << robot->skeleton() << "]" << std::endl;\n\t\n\t /// --- some robot_dart code ---\n\t simulate_robot(robot);\n\t // --- do something with the result\n\t\n\t std::cout << "End of simulation " << i << std::endl;\n\t\n\t // CRITICAL : free your robot !\n\t pool::robot_pool.free_robot(robot);\n\t\n\t std::cout << "Robot " << i << " freed!" << std::endl;\n\t}\n\t```', 'ROBOT_POOL_CREATE_THREADS': '\t```cpp\n\t// for the example, we run NUM_THREADS threads of eval_robot()\n\tstd::vector threads(NUM_THREADS * 2); // *2 to see some reuse\n\tfor (size_t i = 0; i < threads.size(); ++i)\n\t threads[i] = std::thread(eval_robot, i); // eval_robot is the function that uses the robot\n\t```', 'TALOS': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'RECORD_VIDEO_ROBOT_GRAPHICS_PARAMS': '\t```cpp\n\tgraphics->record_video("talos_dancing.mp4");\n\t```', 'HELLO_WORLD_INCLUDE': '\t```cpp\n\t#include \n\t\n\t#ifdef GRAPHIC\n\t#include \n\t#endif\n\t```', 'HELLO_WORLD_ROBOT_CREATION': '\t```cpp\n\tauto robot = std::make_shared("pexod.urdf");\n\t```', 'HELLO_WORLD_ROBOT_PLACING': '\t```cpp\n\trobot->set_base_pose(robot_dart::make_tf({0., 0., 0.2}));\n\t```', 'HELLO_WORLD_ROBOT_SIMU': '\t```cpp\n\trobot_dart::RobotDARTSimu simu(0.001); // dt=0.001, 1KHz simulation\n\tsimu.add_floor();\n\tsimu.add_robot(robot);\n\t```', 'HELLO_WORLD_ROBOT_GRAPHIC': '\t```cpp\n\tauto graphics = std::make_shared();\n\tsimu.set_graphics(graphics);\n\tgraphics->look_at({0.5, 3., 0.75}, {0.5, 0., 0.2});\n\t```', 'HELLO_WORLD_ROBOT_RUN': '\t```cpp\n\tsimu.run(10.);\n\t```', 'LOAD_IICUB': '\t```cpp\n\tauto robot = std::make_shared();\n\t// Set actuator types to VELOCITY motors so that they stay in position without any controller\n\trobot->set_actuator_types("velocity");\n\trobot_dart::RobotDARTSimu simu(0.001);\n\tsimu.set_collision_detector("fcl");\n\t```', 'ICUB_PRINT_IMU': '\t```cpp\n\tstd::cout << "Angular Position: " << robot->imu().angular_position_vec().transpose().format(fmt) << std::endl;\n\tstd::cout << "Angular Velocity: " << robot->imu().angular_velocity().transpose().format(fmt) << std::endl;\n\tstd::cout << "Linear Acceleration: " << robot->imu().linear_acceleration().transpose().format(fmt) << std::endl;\n\tstd::cout << "=================================" << std::endl;\n\t```', 'ICUB_PRINT_FT': '\t```cpp\n\tstd::cout << "FT ( force): " << robot->ft_foot_left().force().transpose().format(fmt) << std::endl;\n\tstd::cout << "FT (torque): " << robot->ft_foot_left().torque().transpose().format(fmt) << std::endl;\n\tstd::cout << "=================================" << std::endl;\n\t```', 'SIMPLE_CONTROL': '\t```cpp\n\tauto controller1 = std::make_shared(ctrl);\n\t// add the controller to the robot, with a default weight of 1.0\n\trobot->add_controller(controller1);\n\t```', 'ROBOT_CONTROL': '\t```cpp\n\tclass MyController : public robot_dart::control::RobotControl {\n\tpublic:\n\t MyController() : robot_dart::control::RobotControl() {}\n\t\n\t MyController(const Eigen::VectorXd& ctrl, bool full_control) : robot_dart::control::RobotControl(ctrl, full_control) {}\n\t MyController(const Eigen::VectorXd& ctrl, const std::vector& dof_names) : robot_dart::control::RobotControl(ctrl, dof_names) {}\n\t\n\t void configure() override\n\t {\n\t _active = true;\n\t }\n\t\n\t Eigen::VectorXd calculate(double) override\n\t {\n\t auto robot = _robot.lock();\n\t Eigen::VectorXd cmd = 100. * (_ctrl - robot->positions(_controllable_dofs));\n\t return cmd;\n\t }\n\t std::shared_ptr clone() const override\n\t {\n\t return std::make_shared(*this);\n\t }\n\t};\n\t```', 'SIMPLE_ARM': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'KINEMATICS': '\t```cpp\n\t// Get Joint Positions(Angles)\n\tauto joint_positions = robot->positions();\n\t\n\t// Get Joint Velocities\n\tauto joint_vels = robot->velocities();\n\t\n\t// Get Joint Accelerations\n\tauto joint_accs = robot->accelerations();\n\t\n\t// Get link_name(str) Transformation matrix with respect to the world frame.\n\tauto eef_tf = robot->body_pose(link_name);\n\t\n\t// Get translation vector from transformation matrix\n\tauto eef_pos = eef_tf.translation();\n\t\n\t// Get rotation matrix from tranformation matrix\n\tauto eef_rot = eef_tf.rotation();\n\t\n\t// Get link_name 6d pose vector [logmap(eef_tf.linear()), eef_tf.translation()]\n\tauto eef_pose_vec = robot->body_pose_vec(link_name);\n\t\n\t// Get link_name 6d velocity vector [angular, cartesian]\n\tauto eef_vel = robot->body_velocity(link_name);\n\t\n\t// Get link_name 6d acceleration vector [angular, cartesian]\n\tauto eef_acc = robot->body_acceleration(link_name);\n\t\n\t// Jacobian targeting the origin of link_name(str)\n\tauto jacobian = robot->jacobian(link_name);\n\t\n\t// Jacobian time derivative\n\tauto jacobian_deriv = robot->jacobian_deriv(link_name);\n\t\n\t// Center of Mass Jacobian\n\tauto com_jacobian = robot->com_jacobian();\n\t\n\t// Center of Mass Jacobian Time Derivative\n\tauto com_jacobian_deriv = robot->com_jacobian_deriv();\n\t```', 'DYNAMICS': "\t```cpp\n\t// Get Joint Forces\n\tauto joint_forces = robot->forces();\n\t\n\t// Get link's mass\n\tauto eef_mass = robot->body_mass(link_name);\n\t\n\t// Mass Matrix of robot\n\tauto mass_matrix = robot->mass_matrix();\n\t\n\t// Inverse of Mass Matrix\n\tauto inv_mass_matrix = robot->inv_mass_matrix();\n\t\n\t// Augmented Mass matrix\n\tauto aug_mass_matrix = robot->aug_mass_matrix();\n\t\n\t// Inverse of Augmented Mass matrix\n\tauto inv_aug_mass_matrix = robot->inv_aug_mass_matrix();\n\t\n\t// Coriolis Force vector\n\tauto coriolis = robot->coriolis_forces();\n\t\n\t// Gravity Force vector\n\tauto gravity = robot->gravity_forces();\n\t\n\t// Combined vector of Coriolis Force and Gravity Force\n\tauto coriolis_gravity = robot->coriolis_gravity_forces();\n\t\n\t// Constraint Force Vector\n\tauto constraint_forces = robot->constraint_forces();\n\t```", 'CAMERA_SENSOR_RGBD_RECORD_DEPTH': '\t```cpp\n\tcamera->camera().record(true, true); // cameras are recording color images by default, enable depth images as well for this example\n\t```', 'TORQUE_SENSOR': '\t```cpp\n\t// Add torque sensors to the robot\n\tint ct = 0;\n\tstd::vector> tq_sensors(robot->num_dofs());\n\tfor (const auto& joint : robot->dof_names())\n\t tq_sensors[ct++] = simu.add_sensor(robot, joint, 1000);\n\t```', 'FORCE_TORQUE_SENSOR': '\t```cpp\n\t// Add force-torque sensors to the robot\n\tct = 0;\n\tstd::vector> f_tq_sensors(robot->num_dofs());\n\tfor (const auto& joint : robot->dof_names())\n\t f_tq_sensors[ct++] = simu.add_sensor(robot, joint, 1000, "parent_to_child");\n\t```', 'IMU_SENSOR': '\t```cpp\n\t// Add IMU sensors to the robot\n\tct = 0;\n\tstd::vector> imu_sensors(robot->num_bodies());\n\tfor (const auto& body_node : robot->body_names()) {\n\t // _imu(std::make_shared(sensor::IMUConfig(body_node("head"), frequency))),\n\t imu_sensors[ct++] = simu.add_sensor(robot_dart::sensor::IMUConfig(robot->body_node(body_node), 1000));\n\t}\n\t```', 'TORQUE_MEASUREMENT': '\t```cpp\n\t// vector that contains the torque measurement for every joint (scalar)\n\tEigen::VectorXd torques_measure(robot->num_dofs());\n\tfor (const auto& tq_sens : tq_sensors)\n\t torques_measure.block<1, 1>(ct++, 0) = tq_sens->torques();\n\t```', 'FORCE_TORQUE_MEASUREMENT': '\t```cpp\n\t// matrix that contains the torque measurement for every joint (3d vector)\n\tEigen::MatrixXd ft_torques_measure(robot->num_dofs(), 3);\n\t// matrix that contains the force measurement for every joint (3d vector)\n\tEigen::MatrixXd ft_forces_measure(robot->num_dofs(), 3);\n\t// matrix that contains the wrench measurement for every joint (6d vector)[torque, force]\n\tEigen::MatrixXd ft_wrench_measure(robot->num_dofs(), 6);\n\tct = 0;\n\tfor (const auto& f_tq_sens : f_tq_sensors) {\n\t ft_torques_measure.block<1, 3>(ct, 0) = f_tq_sens->torque();\n\t ft_forces_measure.block<1, 3>(ct, 0) = f_tq_sens->force();\n\t ft_wrench_measure.block<1, 6>(ct, 0) = f_tq_sens->wrench();\n\t ct++;\n\t}\n\t```', 'IMU_MEASUREMENT': '\t```cpp\n\tEigen::MatrixXd imu_angular_positions_measure(robot->num_bodies(), 3);\n\tEigen::MatrixXd imu_angular_velocities_measure(robot->num_bodies(), 3);\n\tEigen::MatrixXd imu_linear_acceleration_measure(robot->num_bodies(), 3);\n\tct = 0;\n\tfor (const auto& imu_sens : imu_sensors) {\n\t imu_angular_positions_measure.block<1, 3>(ct, 0) = imu_sens->angular_position_vec();\n\t imu_angular_velocities_measure.block<1, 3>(ct, 0) = imu_sens->angular_velocity();\n\t imu_linear_acceleration_measure.block<1, 3>(ct, 0) = imu_sens->linear_acceleration();\n\t ct++;\n\t}\n\t```', 'RGB_SENSOR': '\t```cpp\n\t// a nested std::vector (w*h*3) of the last image taken can be retrieved\n\tauto rgb_image = camera->image();\n\t```', 'RGB_SENSOR_MEASURE': '\t```cpp\n\t// we can also save them to png\n\trobot_dart::gui::save_png_image("camera-small.png", rgb_image);\n\t// convert an rgb image to grayscale (useful in some cases)\n\tauto gray_image = robot_dart::gui::convert_rgb_to_grayscale(rgb_image);\n\trobot_dart::gui::save_png_image("camera-gray.png", gray_image);\n\t```', 'RGB_D_SENSOR': '\t```cpp\n\t// get the depth image from a camera\n\t// with a version for visualization or bigger differences in the output\n\tauto rgb_d_image = camera->depth_image();\n\t// and the raw values that can be used along with the camera parameters to transform the image to point-cloud\n\tauto rgb_d_image_raw = camera->raw_depth_image();\n\t```', 'RGB_D_SENSOR_MEASURE': '\t```cpp\n\trobot_dart::gui::save_png_image("camera-depth.png", rgb_d_image);\n\trobot_dart::gui::save_png_image("camera-depth-raw.png", rgb_d_image_raw);\n\t```', 'SET_ACTUATOR': '\t```cpp\n\t// Set all DoFs to same actuator\n\trobot->set_actuator_types("servo"); // actuator types can be "servo", "torque", "velocity", "passive", "locked", "mimic"\n\t// You can also set actuator types separately\n\trobot->set_actuator_type("torque", "iiwa_joint_5");\n\t```', 'POSITIONS_ENFORCED': '\t```cpp\n\t// Εnforce joint position and velocity limits\n\trobot->set_position_enforced(true);\n\t```', 'MODIFY_LIMITS': '\t```cpp\n\t// Modify Position Limits\n\tEigen::VectorXd pos_upper_lims(7);\n\tpos_upper_lims << 2.096, 2.096, 2.096, 2.096, 2.096, 2.096, 2.096;\n\trobot->set_position_upper_limits(pos_upper_lims, dof_names);\n\trobot->set_position_lower_limits(-pos_upper_lims, dof_names);\n\t\n\t// Modify Velocity Limits\n\t\n\tEigen::VectorXd vel_upper_lims(7);\n\tvel_upper_lims << 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5;\n\trobot->set_velocity_upper_limits(vel_upper_lims, dof_names);\n\trobot->set_velocity_lower_limits(-vel_upper_lims, dof_names);\n\t\n\t// Modify Force Limits\n\t\n\tEigen::VectorXd force_upper_lims(7);\n\tforce_upper_lims << 150, 150, 150, 150, 150, 150, 150;\n\trobot->set_force_upper_limits(force_upper_lims, dof_names);\n\trobot->set_force_lower_limits(-force_upper_lims, dof_names);\n\t\n\t// Modify Acceleration Limits\n\tEigen::VectorXd acc_upper_lims(7);\n\tacc_upper_lims << 1500, 1500, 1500, 1500, 1500, 1500, 1500;\n\trobot->set_acceleration_upper_limits(acc_upper_lims, dof_names);\n\trobot->set_acceleration_lower_limits(-acc_upper_lims, dof_names);\n\t```', 'MODIFY_COEFFS': '\t```cpp\n\t// Modify Damping Coefficients\n\tstd::vector damps = {0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4};\n\trobot->set_damping_coeffs(damps, dof_names);\n\t\n\t// Modify Coulomb Frictions\n\tstd::vector cfrictions = {0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001};\n\trobot->set_coulomb_coeffs(cfrictions, dof_names);\n\t\n\t// Modify Spring Stiffness\n\tstd::vector stiffnesses = {0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001};\n\trobot->set_spring_stiffnesses(stiffnesses, dof_names);\n\t```', 'SET_COLLISION_DETECTOR': '\t```cpp\n\tsimu.set_collision_detector("fcl"); // collision_detector can be "dart", "fcl", "ode" or "bullet" (case does not matter)\n\t```', 'SELF_COLLISIONS': '\t```cpp\n\tif (!robot->self_colliding()) {\n\t std::cout << "Self collision is not enabled" << std::endl;\n\t // set self collisions to true and adjacent collisions to false\n\t robot->set_self_collision(true, false);\n\t}\n\t```', 'HEXAPOD': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'VX300': '\t```cpp\n\tauto robot = std::make_shared();\n\t```', 'HEXAPOD_PYTHON': '\t```python\n\trobot = rd.Hexapod()\n\t```', 'SET_COLLISION_DETECTOR_PYTHON': '\t```python\n\tsimu.set_collision_detector("fcl") # collision_detector can be "dart", "fcl", "ode" or "bullet" (case does not matter)\n\t```', 'SELF_COLLISIONS_PYTHON': '\t```python\n\tif(not robot.self_colliding()):\n\t print("Self collision is not enabled")\n\t # set self collisions to true and adjacent collisions to false\n\t robot.set_self_collision(True, False)\n\t```', 'FRANKA_PYTHON': '\t```python\n\trobot = rd.Franka()\n\t```', 'PD_CONTROL_PYTHON': '\t```python\n\t# add a PD-controller to the arm\n\t# set desired positions\n\tctrl = [0., np.pi / 4., 0., -np.pi / 4., 0., np.pi / 2., 0., 0.]\n\t\n\t# add the controller to the robot\n\tcontroller = rd.PDControl(ctrl)\n\trobot.add_controller(controller)\n\tcontroller.set_pd(300., 50.)\n\t```', 'TIAGO_PYTHON': '\t```python\n\trobot = rd.Tiago()\n\t```', 'SIMPLE_ARM_PYTHON': '\t```python\n\trobot = rd.Arm()\n\t```', 'TALOS_PYTHON': '\t```python\n\trobot = rd.Talos()\n\t```', 'RECORD_VIDEO_ROBOT_GRAPHICS_PARAMS_PYTHON': '\t```python\n\tgraphics.record_video("talos_fast.mp4")\n\t```', 'CAMERAS_PARALLEL_PYTHON': '\t```python\n\trobot = rd.Robot("arm.urdf", "arm", False)\n\trobot.fix_to_world()\n\t\n\tdef test():\n\t pid = os.getpid()\n\t ii = pid%15\n\t\n\t # create the controller\n\t pdcontrol = rd.PDControl([0.0, 1.0, -1.5, 1.0], False)\n\t\n\t # clone the robot\n\t grobot = robot.clone()\n\t\n\t # add the controller to the robot\n\t grobot.add_controller(pdcontrol, 1.)\n\t pdcontrol.set_pd(200., 20.)\n\t\n\t # create the simulation object\n\t simu = rd.RobotDARTSimu(0.001)\n\t\n\t # set the graphics\n\t graphics = rd.gui.WindowlessGraphics()\n\t simu.set_graphics(graphics)\n\t\n\t graphics.look_at([0.4 * ii, 3.5 - ii * 0.1, 2.], [0., 0., 0.25], [0., 0., 1.])\n\t\n\t # add the robot and the floor\n\t simu.add_robot(grobot)\n\t simu.add_checkerboard_floor()\n\t\n\t # run\n\t simu.run(20.)\n\t\n\t # save last frame for visualization purposes\n\t img = graphics.image()\n\t rd.gui.save_png_image(\'camera-\' + str(ii) + \'.png\', img)\n\t\n\t# helper function to run in parallel\n\tdef runInParallel(N):\n\t proc = []\n\t for i in range(N):\n\t # rd.gui.run_with_gl_context accepts 2 parameters:\n\t # (func, wait_time_in_ms)\n\t # the func needs to be of the following format: void(), aka no return, no arguments\n\t p = Process(target=rd.gui.run_with_gl_context, args=(test, 20))\n\t p.start()\n\t proc.append(p)\n\t for p in proc:\n\t p.join()\n\t\n\tprint(\'Running parallel evaluations\')\n\tN = 15\n\tstart = timer()\n\trunInParallel(N)\n\tend = timer()\n\tprint(\'Time:\', end-start)\n\t```', 'HELLO_WORLD_INCLUDE_PYTHON': '\t```python\n\timport RobotDART as rd\n\t```', 'HELLO_WORLD_ROBOT_CREATION_PYTHON': '\t```python\n\trobot = rd.Robot("pexod.urdf");\n\t```', 'HELLO_WORLD_ROBOT_PLACING_PYTHON': '\t```python\n\t# pose is a 6D vector (first 3D orientation in angle-axis and last 3D translation)\n\trobot.set_base_pose([0., 0., 0., 0., 0., 0.2])\n\t```', 'HELLO_WORLD_ROBOT_SIMU_PYTHON': '\t```python\n\tsimu = rd.RobotDARTSimu(0.001); # dt=0.001, 1KHz simulation\n\tsimu.add_floor();\n\tsimu.add_robot(robot);\n\t```', 'HELLO_WORLD_ROBOT_GRAPHIC_PYTHON': '\t```python\n\tgraphics = rd.gui.Graphics()\n\tsimu.set_graphics(graphics)\n\tgraphics.look_at([0.5, 3., 0.75], [0.5, 0., 0.2])\n\t```', 'HELLO_WORLD_ROBOT_RUN_PYTHON': '\t```python\n\tsimu.run(10.)\n\t```', 'SET_ACTUATOR_PYTHON': '\t```python\n\t# Set all DoFs to same actuator\n\t# actuator types can be "servo", "torque", "velocity", "passive", "locked", "mimic"\n\trobot.set_actuator_types("servo")\n\t# You can also set actuator types separately\n\trobot.set_actuator_type("torque", "iiwa_joint_5")\n\t```', 'POSITIONS_ENFORCED_PYTHON': '\t```python\n\t# Εnforce joint position and velocity limits\n\trobot.set_position_enforced(True)\n\t```', 'MODIFY_LIMITS_PYTHON': '\t```python\n\t# Modify Position Limits\n\tpos_upper_lims = np.array([2.096, 2.096, 2.096, 2.096, 2.096, 2.096, 2.096])\n\trobot.set_position_upper_limits(pos_upper_lims, dof_names)\n\trobot.set_position_lower_limits(-1*pos_upper_lims, dof_names)\n\t\n\t# Modify Velocity Limits\n\tvel_upper_lims = np.array([1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5])\n\t\n\trobot.set_velocity_upper_limits(vel_upper_lims, dof_names)\n\trobot.set_velocity_lower_limits(-1*vel_upper_lims, dof_names)\n\t\n\t# Modify Force Limits\n\tforce_upper_lims = np.array([150, 150, 150, 150, 150, 150, 150])\n\trobot.set_force_upper_limits(force_upper_lims, dof_names)\n\trobot.set_force_lower_limits(-1*force_upper_lims, dof_names)\n\t\n\t# Modify Acceleration Limits\n\tacc_upper_lims = np.array([1500, 1500, 1500, 1500, 1500, 1500, 1500])\n\trobot.set_acceleration_upper_limits(acc_upper_lims, dof_names)\n\trobot.set_acceleration_lower_limits(-1*acc_upper_lims, dof_names)\n\t```', 'MODIFY_COEFFS_PYTHON': '\t```python\n\t# Modify Damping Coefficients\n\tdamps = [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]\n\trobot.set_damping_coeffs(damps, dof_names)\n\t\n\t# Modify Coulomb Frictions\n\tcfrictions = [0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001]\n\trobot.set_coulomb_coeffs(cfrictions, dof_names)\n\t\n\t# Modify Spring Stiffness\n\tstiffnesses = [0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001]\n\trobot.set_spring_stiffnesses(stiffnesses, dof_names)\n\t```', 'CAMERA_SENSOR_RGBD_RECORD_DEPTH_PYTHON': '\t```python\n\t# cameras are recording color images by default, enable depth images as well for this example\n\tcamera.camera().record(True, True)\n\t```', 'TORQUE_SENSOR_PYTHON': '\t```python\n\t# Add torque sensors to the robot\n\ttq_sensors = np.empty(robot.num_dofs(), dtype=rd.sensor.Torque)\n\tct = 0\n\tfor joint in robot.dof_names():\n\t simu.add_sensor(rd.sensor.Torque(robot, joint, 1000))\n\t tq_sensors[ct] = simu.sensors()[-1]\n\t ct += 1\n\t```', 'FORCE_TORQUE_SENSOR_PYTHON': '\t```python\n\t# Add force-torque sensors to the robot\n\tf_tq_sensors = np.empty(robot.num_dofs(), dtype=rd.sensor.ForceTorque)\n\tct = 0\n\tfor joint in robot.dof_names():\n\t simu.add_sensor(rd.sensor.ForceTorque(\n\t robot, joint, 1000, "parent_to_child"))\n\t f_tq_sensors[ct] = simu.sensors()[-1]\n\t print(f_tq_sensors)\n\t ct += 1\n\t```', 'IMU_SENSOR_PYTHON': '\t```python\n\t# Add IMU sensors to the robot\n\tct = 0\n\timu_sensors = np.empty(robot.num_bodies(), dtype=rd.sensor.IMU)\n\tfor body_node in robot.body_names():\n\t simu.add_sensor(rd.sensor.IMU(\n\t rd.sensor.IMUConfig(robot.body_node(body_node), 1000)))\n\t imu_sensors[ct] = simu.sensors()[-1]\n\t ct += 1\n\t```', 'TORQUE_MEASUREMENT_PYTHON': '\t```python\n\t# vector that contains the torque measurement for every joint (scalar)\n\ttorques_measure = np.empty(robot.num_dofs())\n\tct = 0\n\tfor tq_sens in tq_sensors:\n\t torques_measure[ct] = tq_sens.torques()\n\t ct += 1\n\t```', 'FORCE_TORQUE_MEASUREMENT_PYTHON': '\t```python\n\t# matrix that contains the torque measurement for every joint (3d vector)\n\tft_torques_measure = np.empty([robot.num_dofs(), 3])\n\t# matrix that contains the force measurement for every joint (3d vector)\n\tft_forces_measure = np.empty([robot.num_dofs(), 3])\n\t# matrix that contains the wrench measurement for every joint (6d vector)[torque, force]\n\tft_wrench_measure = np.empty([robot.num_dofs(), 6])\n\tct = 0\n\tfor f_tq_sens in f_tq_sensors:\n\t ft_torques_measure[ct, :] = f_tq_sens.torque()\n\t ft_forces_measure[ct, :] = f_tq_sens.force()\n\t ft_wrench_measure[ct, :] = f_tq_sens.wrench()\n\t ct += 1\n\t\n\t```', 'IMU_MEASUREMENT_PYTHON': '\t```python\n\timu_angular_positions_measure = np.empty([robot.num_bodies(), 3])\n\timu_angular_velocities_measure = np.empty([robot.num_bodies(), 3])\n\timu_linear_acceleration_measure = np.empty([robot.num_bodies(), 3])\n\tct = 0\n\tfor imu_sens in imu_sensors:\n\t imu_angular_positions_measure[ct,:] = imu_sens.angular_position_vec()\n\t imu_angular_velocities_measure[ct, :] = imu_sens.angular_velocity()\n\t imu_linear_acceleration_measure[ct,:] = imu_sens.linear_acceleration()\n\t ct += 1\n\t\n\t```', 'RGB_SENSOR_PYTHON': '\t```python\n\t# a nested array (w*h*3) of the last image taken can be retrieved\n\trgb_image = camera.image()\n\t```', 'RGB_SENSOR_MEASURE_PYTHON': '\t```python\n\t# we can also save them to png\n\trd.gui.save_png_image("camera-small.png", rgb_image)\n\t# convert an rgb image to grayscale (useful in some cases)\n\tgray_image = rd.gui.convert_rgb_to_grayscale(rgb_image)\n\trd.gui.save_png_image("camera-gray.png", gray_image)\n\t```', 'RGB_D_SENSOR_PYTHON': '\t```python\n\t# get the depth image from a camera\n\t# with a version for visualization or bigger differences in the output\n\trgb_d_image = camera.depth_image()\n\t# and the raw values that can be used along with the camera parameters to transform the image to point-cloud\n\trgb_d_image_raw = camera.raw_depth_image()\n\t```', 'RGB_D_SENSOR_MEASURE_PYTHON': '\t```python\n\trd.gui.save_png_image("camera-depth.png", rgb_d_image)\n\trd.gui.save_png_image("camera-depth-raw.png", rgb_d_image_raw)\n\t```', 'A1_PYTHON': '\t```python\n\trobot = rd.A1()\n\t```', 'A1_PRINT_IMU_PYTHON': '\t```python\n\tprint( "Angular Position: ", robot.imu().angular_position_vec().transpose())\n\tprint( "Angular Velocity: ", robot.imu().angular_velocity().transpose())\n\tprint( "Linear Acceleration: ", robot.imu().linear_acceleration().transpose())\n\tprint( "=================================")\n\t```', 'SIMPLE_CONTROL_PYTHON': '\t```python\n\tcontroller1 = rd.SimpleControl(ctrl)\n\t# add the controller to the robot, with a default weight of 1.0\n\trobot.add_controller(controller1)\n\t```', 'INIT_SIMU_PYTHON': '\t```python\n\t# choose time step of 0.001 seconds\n\tsimu = rd.RobotDARTSimu(0.001)\n\t```', 'MODIFY_SIMU_DT_PYTHON': '\t```python\n\t# set timestep to 0.005 and update control frequency(bool)\n\tsimu.set_timestep(0.005, True)\n\t```', 'SIMU_GRAVITY_PYTHON': '\t```python\n\t# set gravitational force of mars\n\tmars_gravity = [0., 0., -3.721]\n\tsimu.set_gravity(mars_gravity)\n\t```', 'GRAPHICS_PARAMS_PYTHON': '\t```python\n\tconfiguration = rd.gui.GraphicsConfiguration()\n\t# We can change the width/height of the window (or camera, dimensions)\n\tconfiguration.width = 1280\n\tconfiguration.height = 960\n\tconfiguration.title = "Graphics Tutorial" # We can set a title for our window\n\t\n\t# We can change the configuration for shadows\n\tconfiguration.shadowed = True\n\tconfiguration.transparent_shadows = True\n\tconfiguration.shadow_map_size = 1024\n\t\n\t# We can also alter some specifications for the lighting\n\tconfiguration.max_lights = 3 # maximum number of lights for our scene\n\tconfiguration.specular_strength = 0.25 # strength og the specular component\n\t\n\t# Some extra configuration for the main camera\n\tconfiguration.draw_main_camera = True\n\tconfiguration.draw_debug = True\n\tconfiguration.draw_text = True\n\t\n\t# We can also change the background color [default = black]\n\tconfiguration.bg_color = [1., 1., 1., 1.]\n\t\n\t# create the graphics object with the configuration as a parameter\n\tgraphics = rd.gui.Graphics(configuration)\n\t```', 'SHADOWS_GRAPHICS_PYTHON': '\t```python\n\t# Disable shadows\n\tgraphics.enable_shadows(False, False)\n\tsimu.run(1.)\n\t# Enable shadows only for non-transparent objects\n\tgraphics.enable_shadows(True, False)\n\tsimu.run(1.)\n\t# Enable shadows for transparent objects as well\n\tgraphics.enable_shadows(True, True)\n\tsimu.run(1.)\n\t```', 'CLR_LIGHT_PYTHON': '\t```python\n\t# Clear Lights\n\tgraphics.clear_lights()\n\t```', 'LIGHT_MATERIAL_PYTHON': '\t```python\n\t# Clear Light material\n\tshininess = 1000.\n\twhite = magnum.Color4(1., 1., 1., 1.)\n\t\n\t# ambient, diffuse, specular\n\tcustom_material = rd.gui.Material(white, white, white, shininess)\n\t```', 'POINT_LIGHT_PYTHON': '\t```python\n\t# Create point light\n\tposition = magnum.Vector3(0., 0., 2.)\n\tintensity = 1.\n\tattenuation_terms = magnum.Vector3(1., 0., 0.)\n\tpoint_light = rd.gui.create_point_light(position, custom_material, intensity, attenuation_terms)\n\tgraphics.add_light(point_light)\n\t```', 'DIRECTIONAL_LIGHT_PYTHON': '\t```python\n\t# Create directional light\n\tdirection = magnum.Vector3(-1, -1, -1)\n\tdirectional_light = rd.gui.create_directional_light(direction, custom_material)\n\tgraphics.add_light(directional_light)\n\t```', 'SPOT_LIGHT_PYTHON': '\t```python\n\t# Create spot light\n\tposition = magnum.Vector3(0., 0., 1.)\n\tdirection = magnum.Vector3(-1, -1, -1)\n\tintensity = 1.\n\tattenuation_terms = magnum.Vector3(1., 0., 0.)\n\tspot_exponent = np.pi\n\tspot_cut_off = np.pi / 8\n\tspot_light = rd.gui.create_spot_light(position, custom_material, direction, spot_exponent, spot_cut_off, intensity, attenuation_terms)\n\tgraphics.add_light(spot_light)\n\t```', 'LOAD_IICUB_PYTHON': '\t```python\n\trobot = rd.ICub()\n\t\n\t# Set actuator types to VELOCITY motors so that they stay in position without any controller\n\trobot.set_actuator_types("velocity")\n\tsimu = rd.RobotDARTSimu(0.001)\n\tsimu.set_collision_detector("fcl")\n\t```', 'ICUB_PRINT_IMU_PYTHON': '\t```python\n\tprint("Angular Position: ", robot.imu().angular_position_vec().transpose())\n\tprint("Angular Velocity: ", robot.imu().angular_velocity().transpose())\n\tprint("Linear Acceleration: ", robot.imu().linear_acceleration().transpose())\n\tprint("=================================" )\n\t```', 'ICUB_PRINT_FT_PYTHON': '\t```python\n\tprint("FT ( force): ", robot.ft_foot_left().force().transpose())\n\tprint("FT (torque): ", robot.ft_foot_left().torque().transpose())\n\tprint("=================================")\n\t```', 'ADD_NEW_CAMERA_PYTHON': '\t```python\n\t# Add camera\n\tcamera = rd.sensor.Camera(graphics.magnum_app(), 32, 32)\n\t```', 'MANIPULATE_CAM_SEP_PYTHON': '\t```python\n\tcamera.camera().set_far_plane(5.)\n\tcamera.camera().set_near_plane(0.01)\n\tcamera.camera().set_fov(60.0)\n\t```', 'MANIPULATE_CAM_PYTHON': '\t```python\n\tcamera.camera().set_camera_params(5., # far plane\n\t 0.01, # near plane\n\t 60.0, # field of view\n\t 600, # width\n\t 400) # height\n\t```', 'RECORD_VIDEO_CAMERA_PYTHON': '\t```python\n\t\n\t# cameras can also record video\n\tcamera.record_video("video-camera.mp4")\n\t```', 'CAM_POSITION_PYTHON': '\t```python\n\t# set the position of the camera, and the position where the main camera is looking at\n\tcam_pos = [-0.5, -3., 0.75]\n\tcam_looks_at = [0.5, 0., 0.2]\n\tcamera.look_at(cam_pos, cam_looks_at)\n\t```', 'CAM_ATTACH_PYTHON': '\t```python\n\ttf = dartpy.math.Isometry3()\n\trot = dartpy.math.AngleAxis(3.14, [1., 0., 0.])\n\trot = rot.multiply(dartpy.math.AngleAxis(1.57, [0., 0., 1.])).to_rotation_matrix()\n\ttf.set_translation([0., 0., 0.1])\n\ttf.set_rotation(rot)\n\tcamera.attach_to_body(robot.body_node("iiwa_link_ee"), tf) # cameras are looking towards -z by default\n\t```', 'TALOS_FAST_PYTHON': '\t```python\n\trobot = rd.TalosFastCollision()\n\t```', 'KINEMATICS_PYTHON': '\t```python\n\t# Get Joint Positions(Angles)\n\tjoint_positions = robot.positions()\n\t\n\t# Get Joint Velocities\n\tjoint_vels = robot.velocities()\n\t\n\t# Get Joint Accelerations\n\tjoint_accs = robot.accelerations()\n\t\n\t# Get link_name(str) Transformation matrix with respect to the world frame.\n\teef_tf = robot.body_pose(link_name)\n\t\n\t# Get translation vector from transformation matrix\n\teef_pos = eef_tf.translation()\n\t\n\t# Get rotation matrix from tranformation matrix\n\teef_rot = eef_tf.rotation()\n\t\n\t# Get link_name 6d pose vector [logmap(eef_tf.linear()), eef_tf.translation()]\n\teef_pose_vec = robot.body_pose_vec(link_name)\n\t\n\t# Get link_name 6d velocity vector [angular, cartesian]\n\teef_vel = robot.body_velocity(link_name)\n\t\n\t# Get link_name 6d acceleration vector [angular, cartesian]\n\teef_acc = robot.body_acceleration(link_name)\n\t\n\t# Jacobian targeting the origin of link_name(str)\n\tjacobian = robot.jacobian(link_name)\n\t\n\t# Jacobian time derivative\n\tjacobian_deriv = robot.jacobian_deriv(link_name)\n\t\n\t# Center of Mass Jacobian\n\tcom_jacobian = robot.com_jacobian()\n\t\n\t# Center of Mass Jacobian Time Derivative\n\tcom_jacobian_deriv = robot.com_jacobian_deriv()\n\t```', 'DYNAMICS_PYTHON': "\t```python\n\t# Get Joint Forces\n\tjoint_forces = robot.forces()\n\t\n\t# Get link's mass\n\teef_mass = robot.body_mass(link_name)\n\t\n\t# Mass Matrix of robot\n\tmass_matrix = robot.mass_matrix()\n\t\n\t# Inverse of Mass Matrix\n\tinv_mass_matrix = robot.inv_mass_matrix()\n\t\n\t# Augmented Mass matrix\n\taug_mass_matrix = robot.aug_mass_matrix()\n\t\n\t# Inverse of Augmented Mass matrix\n\tinv_aug_mass_matrix = robot.inv_aug_mass_matrix()\n\t\n\t# Coriolis Force vector\n\tcoriolis = robot.coriolis_forces()\n\t\n\t# Gravity Force vector\n\tgravity = robot.gravity_forces()\n\t\n\t# Combined vector of Coriolis Force and Gravity Force\n\tcoriolis_gravity = robot.coriolis_gravity_forces()\n\t\n\t# NOT IMPLEMENTED\n\t# # Constraint Force Vector\n\t# constraint_forces = robot.constraint_forces()\n\t\n\t```", 'VX300_PYTHON': '\t```python\n\trobot = rd.Vx300()\n\t```', 'ROBOT_CONTROL_PYTHON': '\t```python\n\tclass MyController(rd.RobotControl):\n\t def __init__(self, ctrl, full_control):\n\t rd.RobotControl.__init__(self, ctrl, full_control)\n\t\n\t def __init__(self, ctrl, controllable_dofs):\n\t rd.RobotControl.__init__(self, ctrl, controllable_dofs)\n\t\n\t def configure(self):\n\t self._active = True\n\t\n\t def calculate(self, t):\n\t target = np.array([self._ctrl])\n\t cmd = 100*(target-self.robot().positions(self._controllable_dofs))\n\t return cmd[0]\n\t\n\t # TO-DO: This is NOT working at the moment!\n\t def clone(self):\n\t return MyController(self._ctrl, self._controllable_dofs)\n\t```', 'IIWA_PYTHON': '\t```python\n\trobot = rd.Iiwa()\n\t```', 'ROBOT_GHOST_PYTHON': '\t```python\n\t# Add a ghost robot; only visuals, no dynamics, no collision\n\tghost = robot.clone_ghost()\n\tsimu.add_robot(ghost)\n\t```'} for v in variables.items(): env.variables[v[0]] = variables[v[0]]