Skip to content

Commit

Permalink
Merge pull request #3 from rpiRobotics/sphinx
Browse files Browse the repository at this point in the history
Add readthedocs and sphinx documentation
  • Loading branch information
johnwason committed Dec 27, 2022
2 parents efe9093 + 5614514 commit 04e36c9
Show file tree
Hide file tree
Showing 17 changed files with 998 additions and 61 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,6 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
#.idea/

docs/readme.md
13 changes: 13 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2

sphinx:
configuration: docs/conf.py

build:
os: ubuntu-22.04
tools:
python: "3.10"

python:
install:
- requirements: docs/requirements.txt
43 changes: 42 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,44 @@
# abb_robot_client

Python package to access ABB robots using Robot Web Services and EGM.
[![Python](https://img.shields.io/badge/python-3.6+-blue.svg)](https://github.com/rpiRobotics/abb_robot_client)
![PyPI](https://img.shields.io/pypi/v/abb-robot-client)

Python package providing clients for ABB robots using RWS (Robot Web Services) and Externally Guided Motion (EGM).
This package currently supports IRC5 controllers running RobotWare 6.xx. It does not support RobotWare 7+.

This package is typically used with [abb-motion-program-exec](https://pypi.org/project/abb-motion-program-exec/),
which provides a higher level interface to generate motion programs. `abb-motion-program-exec` includes the ability
to initialize EGM operations, using this package to communicate with EGM.

`abb_robot_client` includes three modules: `rws`, `rws_aio`, and `egm`. `rws` provides a synhronous client for Robot
Web Services (RWS) using HTTP REST, and the ability to create subscriptions using websockets. `rws_aio` provides
identical functionality to `rws`, but uses asyncio, with each method being `async`. `egm` provides an Externally
Guided Motion (EGM) client.

Documentation can be found at: https://abb_robot_client.readthedocs.org

## Installation

`abb-robot-client` is avaliable on PyPi. Use the `[aio]` option to include support for asyncio:

```
pip install abb-robot-client[aio]
```

## Examples

See the `examples/` directory for examples using the modules.

## License

Apache 2.0

## Acknowledgment

This work was supported in part by Subaward No. ARM-TEC-21-02-F19 from the Advanced Robotics for Manufacturing ("ARM") Institute under Agreement Number W911NF-17-3-0004 sponsored by the Office of the Secretary of Defense. ARM Project Management was provided by Christopher Adams. The views and conclusions contained in this document are those of the authors and should not be interpreted as representing the official policies, either expressed or implied, of either ARM or the Office of the Secretary of Defense of the U.S. Government. The U.S. Government is authorized to reproduce and distribute reprints for Government purposes, notwithstanding any copyright notation herein.

This work was supported in part by the New York State Empire State Development Division of Science, Technology and Innovation (NYSTAR) under contract C160142.

![](docs/figures/arm_logo.jpg) ![](docs/figures/nys_logo.jpg)


20 changes: 20 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
9 changes: 9 additions & 0 deletions docs/abb_robot_client/api/egm.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
EGM (Externally Guided Motion)
==============================

abb_robot_client.egm
--------------------

.. automodule:: abb_robot_client.egm
:members:

9 changes: 9 additions & 0 deletions docs/abb_robot_client/api/rws.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
RWS (Robot Web Services)
========================

abb_robot_client.rws
--------------------

.. automodule:: abb_robot_client.rws
:members:

11 changes: 11 additions & 0 deletions docs/abb_robot_client/api/rws_aio.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
RWS (Robot Web Services) AsyncIO
================================

abb_robot_client.rws_aio
------------------------

The `rws_aio` module implements asyncio methods. To use, the `abb_robot_client[aio]` option must be installed with pip.

.. automodule:: abb_robot_client.rws_aio
:members:

9 changes: 9 additions & 0 deletions docs/abb_robot_client/api_reference.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
API Reference
================

.. toctree::
:maxdepth: 2

api/rws
api/rws_aio
api/egm
68 changes: 68 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = 'abb_robot_client'
copyright = '2022, Wason Technology, LLC'
author = 'John Wason'

import abb_robot_client

# The short X.Y version.
# version = abb_robot_client.__version__
# The full version, including alpha/beta/rc tags.
# release = abb_robot_client.__version__

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = [
"sphinx.ext.autodoc",
"sphinx_autodoc_typehints",
"recommonmark"
]

source_suffix = [".rst", ".md"]

templates_path = ['_templates']
exclude_patterns = []



# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_theme = "sphinx_rtd_theme"
html_static_path = ['_static']

# https://www.lieret.net/2021/05/20/include-readme-sphinx/
import pathlib

# The readme that already exists
readme_path = pathlib.Path(__file__).parent.resolve().parent / "README.md"
# We copy a modified version here
readme_target = pathlib.Path(__file__).parent / "readme.md"

with readme_target.open("w") as outf:
# Change the title to "Readme"
outf.write(
"\n".join(
[
"Readme",
"======",
]
)
)
lines = []
for line in readme_path.read_text().split("\n"):
if line.startswith("# "):
# Skip title, because we now use "Readme"
# Could also simply exclude first line for the same effect
continue
line = line.replace("docs/figures/", "figures/")
lines.append(line)
outf.write("\n".join(lines))
Binary file added docs/figures/arm_logo.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/figures/nys_logo.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.. abb_robot_client documentation master file, created by
sphinx-quickstart on Tue Dec 27 02:14:13 2022.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to abb_robot_client's documentation!
============================================

.. toctree::
:maxdepth: 2
:caption: Contents:

readme
abb_robot_client/api_reference

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
35 changes: 35 additions & 0 deletions docs/make.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@ECHO OFF

pushd %~dp0..\

REM Command file for Sphinx documentation

if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=docs
set BUILDDIR=build

%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)

if "%1" == "" goto help

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end

:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

:end
popd
9 changes: 9 additions & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
sphinx_autodoc_typehints
recommonmark
setuptools
requests
numpy
protobuf
websocket-client
httpx
websockets
53 changes: 50 additions & 3 deletions src/abb_robot_client/egm.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,31 @@
from typing import Tuple, NamedTuple, Any

class EGMRobotState(NamedTuple):
"""
State information returned from robot through EGM
"""
joint_angles: np.array
"""Joint angles of robot in radians. Length is 6 or 7 depending on robot"""
rapid_running: bool
"""True if RAPID program is running on controller"""
motors_on: bool
"""True if motors are on"""
robot_message: Any
"""Full message returned from robot"""
cartesian: Tuple[np.array,np.array]
"""Cartesian position of robots, in ([x,y,z],[w,x,y,z]) format"""



class EGM(object):
"""
ABB EGM (Externally Guided Motion) client. EGM provides a real-time streaming connection to the robot using
UDP, typically at a rate of 250 Hz. The robot controller initiates the connection. The IP address and port of the
client must be configured on the robot controller side. The EGM client will send commands to the port it receives
packets from.
:param port: The port to receive UDP packets. Defaults to 6510
"""

def __init__(self, port : int=6510):

Expand All @@ -26,7 +42,13 @@ def __init__(self, port : int=6510):
self.count=0

def receive_from_robot(self, timeout : float=0) -> Tuple[bool,EGMRobotState]:
"""
Receive feedback from the robot. Specify an optional timeout. Returns a tuple with success and the current
robot state.
:param timeout: Timeout in seconds. May be zero to immediately return if there is no new data.
:return: Success and robot state as a tuple
"""
s=self.socket
s_list=[s]
try:
Expand Down Expand Up @@ -72,6 +94,13 @@ def receive_from_robot(self, timeout : float=0) -> Tuple[bool,EGMRobotState]:
return True, EGMRobotState(joint_angles, rapid_running, motors_on, robot_message, cartesian)

def send_to_robot(self, joint_angles: np.array) -> bool:
"""
Send a joint command to robot. Returns False if no data has been received from the robot yet. The EGM
operation must have been started with EGMActJoint and EGMRunJoint.
:param joint_angles: Joint angle command in radians
:return: True if successful, False if no data received from robot yet
"""

if not self.egm_addr:
return False
Expand Down Expand Up @@ -100,7 +129,16 @@ def send_to_robot(self, joint_angles: np.array) -> bool:

return True

def send_to_robot_cart(self, pos, orient):
def send_to_robot_cart(self, pos: np.ndarray, orient: np.ndarray):
"""
Send a cartesian command to robot. Returns False if no data has been received from the robot yet. The pose
is relative to the tool, workobject, and frame specified when the EGM operation is initialized. The EGM
operation must have been started with EGMActPose and EGMRunPose.
:param pos: The position of the TCP in millimeters [x,y,z]
:param orient: The orientation of the TCP in quaternions [w,x,y,z]
:return: True if successful, False if no data received from robot yet
"""
if not self.egm_addr:
return False

Expand Down Expand Up @@ -137,8 +175,17 @@ def send_to_robot_cart(self, pos, orient):

return True

def send_to_robot_path_corr(self, pos, age=1):

def send_to_robot_path_corr(self, pos: np.ndarray, age: float=1):
"""
Send a path correction command. Returns False if no data has been received from the robot yet. The path
correction is a displacement [x,y,z] in millimeters in **path coordinates**. The displacement uses
"path coordinates", which relate the direction of movement of the end effector. See `CorrConn` command in
*Technical reference manual RAPID Instructions, Functions and Data types* for a detailed description of path
coordinates. The EGM operation must have been started with EGMActMove, and use EGMMoveL and EGMMoveC commands.
:param pos: The displacement in path coordinates in millimeters [x,y,z]
:return: True if successful, False if no data received from robot yet
"""

self.send_sequence_number+=1
sensorMessage=egm_pb2.EgmSensorPathCorr()
Expand Down
Loading

0 comments on commit 04e36c9

Please sign in to comment.