A Python3, ROS-integrated, PyBullet-based Robot Simulator Foundation.
If you want to use Cairo Simulator with ROS, you need to enable Python3 ROS development and source the ROS environment scripts.
Using ROS is optional and the below steps are not strictly necessary.
sudo apt-get install python3-pip python3-yaml
pip3 install --user rospkg catkin_pkg
source /opt/ros/melodic/setup.bash
After sourcing the ROS environment scripts:
pip3 install --user -r requirements.txt
pip3 install -r requirements.txt
and then from the top level cairo-simulator directory:
pip3 install -e ./
Note that for some versions of Python, the igraph install will need to be compiled. You might have to install the below system dependencies:
sudo apt install build-essential python-dev libxml2 libxml2-dev zlib1g-dev bison flex automake autoconf
Clone the repo: https://github.com/cairo-robotics/planning_core_rust
This repostiory is installable as a Python package, however you will need the rust compiler installed on your computer: https://www.rust-lang.org/tools/install
With you virtual environment activated, run:
pip3 install <path_to_planning_core_rust_repo>
Unlike Gazebo, this is not a standalone executable program but rather is a foundation upon which a simulator can be created. The sawyer_test.py file contains a fairly minimal example showing how to use this package, initializing the simulator, a robot, and an object in the world.
The simulator uses 3 primary components:
- Simulator: A singleton class that wraps the PyBullet physics simulation environment and keeps track of all simulation objects.
- Robot: A class that exposes common functionality relevant to robot control, including setting up ROS topics for joint position control and for broadcasting state.
- SimObject: A class that facilitates loading passive objects into the simulation, with functions for managing position and orientation.
The initial version of this simulator only includes support for Manipulator arms, created by extending the Manipulator
class. (See the Sawyer class in Manipulators.py for an example)
Manipulator arms expose functionality to:
publish_state
(typically the configuration vector for all joint/gripper positions)get_current_joint_states
which returns a configuration vectormove_to_joint_pos
which commands the arm to a given configurationmove_to_joint_pos_with_vel
which moves to a target configuration with per-joint velocity specificationscheck_if_at_position
which returns whether the configuration of the manipulator is within some epsilon of a target configurationexecute_trajectory
which moves the arm through a sequence of configuration waypoints at specific timestamps.solve_inverse_kinematics
which returns a configuration (list of joint positions) given a target position (and optional orientation) for the robot's end effector.