Skip to content

Commit

Permalink
[doc] Content update
Browse files Browse the repository at this point in the history
  • Loading branch information
Tigul committed Jul 23, 2024
1 parent 818da26 commit 05677f6
Show file tree
Hide file tree
Showing 13 changed files with 335 additions and 162 deletions.
24 changes: 16 additions & 8 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,24 @@ the instructions below.
## Building the documentation


The documentation uses sphinx as engine.
Building sphinx based documentations requires `pandoc <https://pandoc.org/installing.html>`_
to be installed. Pandoc can be installed via the Ubunutu package manager:
The documentation uses jupyter-book as engine. Building the documentation requires Python 3.9 or higher to avoid
dependency conflicts. On Ubuntu 20.04 you can install Python 3.9 with the following commands.
~~~
sudo apt install pandoc
apt-get install python3.9
~~~
After installing pandoc, install sphinx on your device.

It is recommended to create a virtual environment to avoid conflicts with the system python interpreter.
~~~
sudo apt install python3-sphinx
apt-get install python3.9-virtualenv
virtualenv -p python3.9 --system-site-packages build-doc
~~~

Activate the virtual environment.
~~~
source build-doc/bin/activate
~~~


Install the requirements in your python interpreter.

~~~
Expand All @@ -26,10 +33,11 @@ pip install -r requirements.txt
Run pycram and build the docs.

~~~
make html
cd doc/source
jupyter-book build .
~~~
Show the index.

~~~
firefox build/html/index.html
firefox _build/html/index.html
~~~
10 changes: 5 additions & 5 deletions doc/source/designators.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,17 @@ Creating your own Designator
============================
Creating your own designator is fairly easy, you only need to extend the base class of the respective description.
- :mod:`~pycram.designators.action_designator.ActionDesignatorDescription`
- :mod:`~pycram.designators.object_designator.ObjectDesignatorDescription`
- :mod:`~pycram.designators.location_designator.LocationDesignatorDescription`
- :mod:`~pycram.designators.motion_designator.MotionDesignatorDescription`
- :mod:`~pycram.designator.ActionDesignatorDescription`
- :mod:`~pycram.designator.ObjectDesignatorDescription`
- :mod:`~pycram.designator.LocationDesignatorDescription`
- :mod:`~pycram.designator.BaseMotion`
Afterwards you need to implement your own ``ground`` method which is the default resolver and for location and object
designator it makes sense to also implement a ``__iter__`` method. The ``ground`` and ``__iter__`` methods should return
the designator sub-class so you also need to implement these with the parameter your designator needs.
The sub-class can already contain some parameters, this is usually the case if the parameter is the same for every designator
of this type. For example, :meth:`~pycram.designator.LocationDesignatorDescription.Location`
of this type. For example, :class:`~pycram.designator.LocationDesignatorDescription.Location`
contains a ``pose`` parameter since every location designator contains a resolved pose.
For action and motion designator the sub-class is also the place where the ``perform`` method is written which contains
Expand Down
14 changes: 14 additions & 0 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,20 @@ The code for this plan can be seen below.
world.exit()
Citing PyCRAM
=============

If you want to cite PyCRAM in your work, you can use the following bibtex entry:

.. code-block:: bibtex
@software{dech2024pycram,
author = {Dech, Jonas},
title = {PyCRAM: A Python framework for cognition-enbabled robtics},
url = {https://github.com/cram2/pycram},
version = {0.2.0},
}
Indices and tables
Expand Down
21 changes: 11 additions & 10 deletions doc/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -145,20 +145,21 @@ IK solver.
Building the documentation
==========================

The documentation uses sphinx as engine.
Building sphinx based documentations requires pandoc
to be installed. Pandoc can be installed via the package manager of Ubuntu.
The documentation uses jupyter-book as engine.
Building the documentation requires Python 3.9 to avoid dependency conflicts.
To install Python 3.9 on Ubuntu 20.04, use the following commands:

.. code-block:: shell
sudo apt install pandoc
sudo apt install python3.9
After installing pandoc, install sphinx on your device.
It is recommended to use a virtual environment to avoid conflicts with the system Python.

.. code-block:: shell
sudo apt install python3-sphinx
apt-get install python3-virtualenv
virtualenv -p python3.9 --system-site-packages build-doc
source build-doc/bin/activate
Install the requirements in your python interpreter.

Expand All @@ -173,14 +174,14 @@ Run pycram and build the docs.
cd ~/workspace/ros
roslaunch pycram ik_and_description.launch
cd src/pycram/doc
make html
cd src/pycram/doc/source
jupyter-book build .
Show the index.

.. code-block::
firefox build/html/index.html
firefox _build/html/index.html
Expand Down
3 changes: 0 additions & 3 deletions doc/source/orm.rst

This file was deleted.

12 changes: 12 additions & 0 deletions doc/source/troubleshooting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,15 @@ real_robot environments. This is also explained in the `Action Designator Exampl
with simulated_robot:
NavigateAction([Pose()]).resolve().perform()
Missing pr2_arm_kinematics
==========================

Aptitudes autoremove likes to also remove the arm kinematics. Reinstall the missing libraries with

.. code-block:: shell
sudo apt-get install ros-noetic-moveit
Then rebuild your workspace.


8 changes: 4 additions & 4 deletions examples/bullet_world.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ around:
* Press the middle mouse button (scroll wheel) and move the mouse up or down to zoom

At the moment the BulletWorld only contains a floor, this is spawned by default when creating the BulletWorld.
Furthermore, the gravity is set to 9.8 m^2, which is the same gravitation as the one on earth.
Furthermore, the gravity is set to 9.8 $m^2$, which is the same gravitation as the one on earth.

To spawn new things in the BulletWorld we need to import the Object class and create and instance of it.

Expand All @@ -46,7 +46,7 @@ milk = Object("milk", ObjectType.MILK, "milk.stl", pose=Pose([0, 0, 1]))

<!-- #region -->
As you can see this spawns a milk floating in the air. What we did here was create a new Object which has the name "
milk" as well as the type ```ObjectType.MILK ``` , is spawned from the file "milk.stl" and is at the position [0, 0, 1].
milk" as well as the type {attr}`~pycram.datastructures.enums.ObjectType.MILK`, is spawned from the file "milk.stl" and is at the position [0, 0, 1].

The type of an Object can either be from the enum ObjectType or a string. However, it is recommended to use the enum
since this would make for a more consistent naming of types which makes it easier to work with types. But since the
Expand Down Expand Up @@ -154,8 +154,8 @@ print(f"New Joint state: {pr2.get_joint_position('torso_lift_joint')}")

## Misc Methods

There are a few methods that don't fit any category but could be helpful anyway. The first two are ```get_color```
and ```set_color```, as the name implies they can be used to get or set the color for specific links or the whole
There are a few methods that don't fit any category but could be helpful anyway. The first two are {meth}`~pycram.description.Link.get_color`
and {meth}`~pycram.description.Link.set_color`, as the name implies they can be used to get or set the color for specific links or the whole
Object.

```python
Expand Down
97 changes: 65 additions & 32 deletions examples/interface_examples/giskard.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,42 @@ jupyter:
---

# Giskard interface in PyCRAM
This notebook should provide you with an example on how to use the Giskard interface. This includes how to use the interface, how it actually works and how to extend it.

We start by installing and launching Giskard. For the installation please follow the instructions [here](https://github.com/SemRoCo/giskardpy).
After you finish the installation you should be able to launch Giskard by calling:
This notebook should provide you with an example on how to use the Giskard interface. This includes how to use the
interface, how it actually works and how to extend it.

We start by installing and launching Giskard. For the installation please follow the
instructions [here](https://github.com/SemRoCo/giskardpy).
After you finish the installation you should be able to launch Giskard by calling:

```
roslaunch giskardpy giskardpy_pr2_standalone.launch
```

This way you can launch Giskard for any robot that is supported:

```
roslaunch giskardpy giskardpy_hsr_standalone.launch
```
"Standalone" means that Giskard only uses a simulated robot and does not look for a real robot. If you want to use Giskard with a real robot you have to switch out "standalone" with "iai", e.g:

"Standalone" means that Giskard only uses a simulated robot and does not look for a real robot. If you want to use
Giskard with a real robot you have to switch out "standalone" with "iai", e.g:

```
roslaunch giskardpy giskardpy_hsr_iai.launch
```

To see what Giskard is doing you can start RViz, there should already be a MarkerArray when starting otherwise you have to add this manually.
To see what Giskard is doing you can start RViz, there should already be a MarkerArray when starting otherwise you have
to add this manually.

## How to use the Giskard interface

## How to use the Giskard interface
Everything related to the Giskard interface is located in ```pycram.external_interfaces.giskard```.
Everything related to the Giskard interface is located in {class}`pycram.external_interfaces.giskard`.
The content of the file can be roughly divided into three parts:
1. Methods to manage the belief states between PyCRAM and Giskard
2. Motion goals that should be sent to Giskard for execution
3. Helper methods to construct ROS messages
1. Methods to manage the belief states between PyCRAM and Giskard
2. Motion goals that should be sent to Giskard for execution
3. Helper methods to construct ROS messages

The most useful methods are the ones for sending and executing Motion goals. These are the ones we will mostly look at.

We will now start by setting up PyCRAM and then try to send some simple motion goals.
Expand All @@ -52,19 +61,23 @@ world = BulletWorld()
pr2 = Object("pr2", ObjectType.ROBOT, "pr2.urdf")
```

When you are working on the real robot you also need to initialize the RobotStateUpdater, this module updates the robot in the BulletWorld with the pose and joint state of the real robot.
When you are working on the real robot you also need to initialize the RobotStateUpdater, this module updates the robot
in the BulletWorld with the pose and joint state of the real robot.

You might need to change to topic names to fit the topic names as published by your robot.
You might need to change to topic names to fit the topic names as published by your robot.

```python
from pycram.ros.robot_state_updater import RobotStateUpdater

r = RobotStateUpdater("/tf", "/joint_states")
```

Now we have a PyCRAM belief state set up, belief state in this case just refers to the BulletWorld since the BulletWorld represents what we believe the world to look like.
Now we have a PyCRAM belief state set up, belief state in this case just refers to the BulletWorld since the BulletWorld
represents what we believe the world to look like.

The next step will be to send a simple motion goal. The motion goal we will be sending is moving the torso up. For this we just need to move one joint, so we can use the ```achive_joint_goal```. This method takes a dictionary with the joints that should be moved and the target value for the joints.
The next step will be to send a simple motion goal. The motion goal we will be sending is moving the torso up. For this
we just need to move one joint, so we can use the ```achive_joint_goal```. This method takes a dictionary with the
joints that should be moved and the target value for the joints.

Look at RViz to see the robot move, since we call Giskard for movement the robot in the BulletWorld will not move.

Expand All @@ -74,11 +87,16 @@ from pycram.external_interfaces import giskard
giskard.achieve_joint_goal({"torso_lift_joint": 0.28})
```

For Giskard everything is connected by joints (this is called a [World Tree](https://github.com/SemRoCo/giskardpy/wiki/World-Tree) by Giskard) therefore we can move the robot's base by using motion goals between the map origin and the robot base. (e.g. by sending a "base_link" goal in the "map" frame).
For Giskard everything is connected by joints (this is called
a [World Tree](https://github.com/SemRoCo/giskardpy/wiki/World-Tree) by Giskard) therefore we can move the robot's base
by using motion goals between the map origin and the robot base. (e.g. by sending a "base_link" goal in the "map"
frame).

In the example below we use a cartesian goal, meaning we give Giskard a goal pose, a root link and a tip link and Giskard tries to move all joints between root link and tip link such that the tip link is at the goal pose.
In the example below we use a cartesian goal, meaning we give Giskard a goal pose, a root link and a tip link and
Giskard tries to move all joints between root link and tip link such that the tip link is at the goal pose.

This sort of movement is fine for short distances, but keep in mind that Giskard has no collision avoidance for longer journeys. So using MoveBase for longer distances is a better idea.
This sort of movement is fine for short distances, but keep in mind that Giskard has no collision avoidance for longer
journeys. So using MoveBase for longer distances is a better idea.

```python
from pycram.external_interfaces import giskard
Expand All @@ -87,9 +105,11 @@ from pycram.pose import Pose
giskard.achieve_cartesian_goal(Pose([1, 0, 0]), "base_link", "map")
```

Now for the last example: we will move the gripper using full body motion control.
Now for the last example: we will move the gripper using full body motion control.

We will again use the cartesian goal, but now between "map" and "r_gripper_tool_frame" frames. This will not only move the robot (because the kinematic chain between "map" and "base_link" as used in the previous example is also part of this chain) but also move the arm of the robot such that it reaches the goal pose.
We will again use the cartesian goal, but now between "map" and "r_gripper_tool_frame" frames. This will not only move
the robot (because the kinematic chain between "map" and "base_link" as used in the previous example is also part of
this chain) but also move the arm of the robot such that it reaches the goal pose.

```python
from pycram.external_interfaces import giskard
Expand All @@ -104,21 +124,34 @@ That concludes this example you can now close the BulletWorld by using the "exit
world.exit()
```

## How the Giskard interface works
The PyCRAM interface to Giskard mostly relies on the Python interface that Giskard already provides ([tutorial](https://github.com/SemRoCo/giskardpy/wiki/Python-Interface) and the [source code](https://github.com/SemRoCo/giskardpy/blob/master/src/giskardpy/python_interface.py)). This interface provides methods to achieve motion goals and load things into the Giskard believe state.
## How the Giskard interface works

What PyCRAM does with this, is: Synchronize the belief state of Giskard with the one of PyCRAM by loading the environment URDF in Giskard, this is done before any motion goal is sent. Furthermore, the motion goals are wrapped in methods that use PyCRAM data types.
The PyCRAM interface to Giskard mostly relies on the Python interface that Giskard already
provides ([tutorial](https://github.com/SemRoCo/giskardpy/wiki/Python-Interface) and
the [source code](https://github.com/SemRoCo/giskardpy/blob/master/src/giskardpy/python_interface.py)). This interface
provides methods to achieve motion goals and load things into the Giskard believe state.

You can also set collisions between different groups of links. By default, Giskard avoids all collisions but for things like grasping an object you want to allow collisions of the gripper. The interface also supports the following collision modes:
* avoid_all_collisions
* allow_self_collision
* allow_gripper_collision
The collision mode can be set by calling the respective method, after calling the method the collision mode is valid for the next motion goal. Afterwards, it defaults back to avoid_all_collisions.
What PyCRAM does with this, is: Synchronize the belief state of Giskard with the one of PyCRAM by loading the
environment URDF in Giskard, this is done before any motion goal is sent. Furthermore, the motion goals are wrapped in
methods that use PyCRAM data types.

There is a ```init_giskard_interface``` method which can be used as a decorator. This decorator should be used on all methods that access the giskard_wrapper, since it assures that the interface is working and checks if Giskard died or the imports for the giskard_msgs failed.
You can also set collisions between different groups of links. By default, Giskard avoids all collisions but for things
like grasping an object you want to allow collisions of the gripper. The interface also supports the following collision
modes:
* avoid_all_collisions
* allow_self_collision
* allow_gripper_collision
The collision mode can be set by calling the respective method, after calling the method the collision mode is valid for
the next motion goal. Afterwards, it defaults back to avoid_all_collisions.

There is a ```init_giskard_interface``` method which can be used as a decorator. This decorator should be used on all
methods that access the giskard_wrapper, since it assures that the interface is working and checks if Giskard died or
the imports for the giskard_msgs failed.

## Extend the Giskard interface
At the moment the PyCRAM Giskard interface is mostly a wrapper around the Python interface provided by Giskard. If you want to extend the interface there are two ways:
* Wrap more motion goals which are provided by the Python interface
* Design new Higher-Level motion goals by combining the motion goals already provided

At the moment the PyCRAM Giskard interface is mostly a wrapper around the Python interface provided by Giskard. If you
want to extend the interface there are two ways:

* Wrap more motion goals which are provided by the Python interface
* Design new Higher-Level motion goals by combining the motion goals already provided
Loading

0 comments on commit 05677f6

Please sign in to comment.