Skip to content

Commit

Permalink
documentation ready
Browse files Browse the repository at this point in the history
  • Loading branch information
prjemian committed May 18, 2015
1 parent 8bcdf1c commit 92ada23
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 49 deletions.
97 changes: 97 additions & 0 deletions docs/source/clients/joystick.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,103 @@
.. index:: joystick
.. index:: EPICS clients; joystick

.. _joystick:

============================================
Joystick - IOC support (not really a client)
============================================

The joystick is an operator interface.
Controls for this interface have been implemented here within the IOC.

Keenan Lang, APS BCDA group, had developed an HMI (human-machine interface)
module to allow human-machine
interface devices such as mice, keyboards, and joysticks (and other) to
communicate directly into an EPICS IOC. In a few hours, he added that
support to the robot IOC project so that a particular joystick can be used
to control the robot arm directly within the IOC.

With added joystick control in the IOC, it is not necessary to require a
KVM GUI (video screen + keyboard + mouse) to operate the robot.


.. figure:: ../graphics/joystick-controls.png
:width: 12cm

This is the joystick we will use.
(model: Logitech Extreme 3D Pro)
It is right-handed and has a twist action (vertical axis).
We'll use that for the base rotation.


======== ================================================================
button action
======== ================================================================
trigger close grip
thumb open grip
twist rotate base in same direction
lever turns on/off base rotation (useful when trying to grasp objects)
joystick shoulder axis: forward=down, back=up
elbow two buttons, forward and back
wrist knob, forward=down, back=up
======== ================================================================

The joystick buttons are described in file:

* ``edgeRoboArmIOC/support/usb-1-0/usbApp/Db/LogitechExtreme3DPro.in``

The actions are mapped to buttons in a database file:

* ``edgeRoboArmIOC/support/xxx-5-6/xxxApp/Db/roboArm.db``
* (includes all of ``edgeRoboArmIOC/support/ip-2-13/ipApp/Db/roboArm.db``)


.. compound::

.. rubric:: EPICS IOC startup commands to support the joystick.

.. code-block:: c
:linenos:
usbCreateDriver("JOYSTICK", "$(USB)/usbApp/Db/LogitechExtreme3DPro.in")
usbConnectDevice("JOYSTICK", 0, 0x046D, 0xC215)
dbLoadRecords("../../xxxApp/Db/roboArm.db", "P=xxx:, A=A1:, INPORT=JOYSTICK, OUTPORT=USB1")
The database provides the mapping between EPICS records and joystick buttons.

.. compound::

.. rubric:: The joystick grip buttons are mapped in a *calcout* record.

.. code-block:: c
:linenos:
record(calcout, "$(P)$(A)grip_calc")
{
field(INPA, "$(P)$(A)Trigger_State.VAL NPP")
field(INPB, "$(P)$(A)LButton_State.VAL NPP")
field(CALC, "2 * B + A")
field(OUT, "$(P)$(A)grip_move PP")
}
record(bi, "$(P)$(A)Trigger_State")
{
field(DTYP, "asynInt32")
field(SCAN, "I/O Intr")
field(INP, "@asyn($(INPORT), 0, 0)TRIGGER_PRESSED")
field(FLNK, "$(P)$(A)grip_calc")
}
record(bi, "$(P)$(A)LButton_State")
{
field(DTYP, "asynInt32")
field(SCAN, "I/O Intr")
field(INP, "@asyn($(INPORT), 0, 0)LBUTTON_PRESSED")
field(FLNK, "$(P)$(A)grip_calc")
}
.. note:: To use a different joystick, you'll need to create
a new file todescribe the buttons on the joystick and the values
used by USB communications: ``$(USB)/usbApp/Db/<new_joystick>.in``

Then, you'll need to modify the ``../../xxxApp/Db/roboArm.db`` file
for the names of the new buttons. You might also need to update the
calculation logic in the database to match your new joystick.
40 changes: 40 additions & 0 deletions docs/source/clients/python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,43 @@
=================================
Python - PyEpics and PyQt4 client
=================================

A Python Graphical User Interface client (using PyEpics and PyQt4)
was created to provide a button interface to the robot controls.
This was especially useful since the hand-held controller broke.

.. figure:: ../graphics/python-gui.png
:width: 12cm

The Python Graphical User Interface.

The GUI screen is rather basic, it provides buttons for all robot arm actions.
Additional keyboard equivalents were assigned. With the key press bindings,
it was then possible to control more than one axis of the robot arm at the same time.
The success of any multitouch interface to this robot is limited by available battery power.

The control is provided in two Python modules:

:robot.py: interfaces with EPICS, converts move commands to PVs, provides basic workout, no GUI
:gui_robot.py: interfaces with *robot* module, provides the GUI

source code documentation
-------------------------

Source code of the Python client is provided below.

gui_robot
+++++++++

.. automodule:: gui_robot
:members:
:undoc-members:
:show-inheritance:

robot
+++++

.. automodule:: robot
:members:
:undoc-members:
:show-inheritance:
2 changes: 2 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath(os.path.join('..', '..', 'python_client')))

# -- General configuration -----------------------------------------------------

Expand All @@ -27,6 +28,7 @@
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.mathjax',
'sphinx.ext.viewcode']
extensions.append('sphinx.ext.autodoc')

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
Expand Down
2 changes: 1 addition & 1 deletion docs/source/examples/11bm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ APS 11-BM: A real automation robot

The Advanced Photon Source beam line 11-BM sample change robot is
an example of a real automation robot for X-ray science. This robot
has more motorized axes, positione encoders, and limit switches.
has more motorized axes, position encoders, and limit switches.
The mechanical system has much lower backlash and higher lifting strength.

Also, the system has a bar code reader to identify samples before they
Expand Down
6 changes: 6 additions & 0 deletions docs/source/examples/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
Examples
========

There are two examples to demonstrate the EPICS control of the OWI Edge Robotic Arm.
For comparison, an additional example shows the sample changing robot at
Advanced Photon Source beam line 11-BM. That robot, also under EPICS control,
is several axes in common with the OWI Edge Robotic Arm.
But, the 11-BM robot is far more advanced, including more
rotation axes such as wrist twist.

.. toctree::
:maxdepth: 1
Expand Down
43 changes: 12 additions & 31 deletions docs/source/examples/marble-tree.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ A great example of the robot would be to place a ball
in a maze, pick it up at the end and repeat. With that
in mind, a marble tree (wooden musical instrument and
coffee table amusement) is ideal. The marble tree shown
in the pictures was purchased in Berea, KY.
in the pictures was purchased in Berea, KY. [#]_

Example
-------
Expand All @@ -26,34 +26,16 @@ the marble from the bin at the bottom.

System for marble tree example

Controls
++++++++

.. figure:: ../graphics/joystick-controls.png
:width: 12cm

This is the joystick we will use.
It is right-handed and has a twist action (vertical axis).
We'll use that for the base rotation.


======== ================================================================
button action
======== ================================================================
trigger close grip
thumb open grip
twist rotate base in same direction
lever turns on/off base rotation (useful when trying to grasp objects)
joystick shoulder axis: forward=down, back=up
elbow two buttons, forward and back
wrist knob, forward=down, back=up
======== ================================================================

The joystick buttons are described in file:
``edgeRoboArmIOC/support/usb-1-0/usbApp/Db/LogitechExtreme3DPro.in``
The actions are mapped to buttons in file:
``edgeRoboArmIOC/support/xxx-5-6/xxxApp/Db/roboArm.db``
See the section :ref:`joystick` for details about the
mapping of controls on the joystick.

Once the Raspberry Pi has been connected to the joystick and robot arm
and the Linux system is started up, the EPICS IOC should start
within two minutes. (Otherwise something is wrong. Check all the connections.)
Keep in mind that the Raspberry Pi is very sensitive to changes in electrical
power demand. It is best to plug everything in **before** plugging in the electrical
power to the Raspberry Pi.

Pulse the LED button to ensure the IOC is operating.

Step 1
Expand All @@ -68,8 +50,7 @@ Step 1
.. figure:: ../graphics/SANY0005.JPG
:width: 12cm

Move arm into place to pick up marble.
Be sure to clear all the wooden leaves!
Address the ball. [#]_

Step 2
++++++
Expand Down Expand Up @@ -124,8 +105,8 @@ Step 6
Listen as the ball moves downward.



-------------------

.. [#] marble tree: http://www.berea.com/appalachian-fireside-gallery/
.. [#] http://www.barryrhodes.com/2012/01/addressing-ball.html
2 changes: 1 addition & 1 deletion docs/source/examples/sequence.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Programmable Sequence
In preparation for the 2012 Argonne National Laboratory Energy Showcase
(an open house for the community [#]_),
the BCDA group [#] created linux-based
the BCDA group [#]_ created linux-based
EPICS controls [#]_ for the robot arm
to simulate how robots install samples into X-ray detectors at
several of the APS experiment area beamlines. The robots allow for faster sample loading
Expand Down
Binary file added docs/source/graphics/python-gui.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 2 additions & 9 deletions docs/source/ioc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
EPICS IOC
=========

The IOC must be run as root. EPICS base 3.1412.1 (or higher) is required.
The IOC must be run as root. EPICS base 3.14.12.1 (or higher) is required.
The support is provided by modifying synApps v5.6 [#]_,
removing modules that are not used, and adding support where appropriate.

Expand Down Expand Up @@ -186,14 +186,7 @@ From this keyboard binding interface, a true multitouch capability was added.
Joystick support
----------------

Keenan Lang, APS BCDA group, had developed an HMI module to allow human-machine
interface devices such as mice, keyboards, and joysticks (and other) to
communicate directly into an EPICS IOC. In a few hours, he added that
support to the robot IOC project so that a particular joystick can be used
to control the robot arm directly within the IOC.

With added joystick control in the IOC, it is not necessary to require a
KVM GUI (video screen + keyboard + mouse) to operate the robot.
See the section :ref:`joystick` for more details.

Now, the LED feature on the robot arm becomes useful!
Verify the IOC is running by pulsing the LED with the programmed button on the joystick.
Expand Down
17 changes: 10 additions & 7 deletions python_client/gui_robot.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
#!/usr/bin/env python

import sys
from time import sleep
try:
from PyQt4 import QtCore, QtGui
pyqtSignal = QtCore.pyqtSignal
except:
from PySide import QtCore, QtGui
pyqtSignal = QtCore.Signal
from PyQt4 import QtCore, QtGui
pyqtSignal = QtCore.pyqtSignal
import robot


class Axis(QtGui.QWidget):
'''GUI controls for motorized axes'''

def __init__(self, parent = None):
QtGui.QWidget.__init__(self, None)
Expand Down Expand Up @@ -57,6 +53,7 @@ def onRelease(self, event=None):


class Led(Axis):
'''GUI controls for the LED'''

def __init__(self, parent = None):
Axis.__init__(self, None)
Expand Down Expand Up @@ -90,6 +87,7 @@ def onRelease(self, event=None):


class MainWindow(QtGui.QWidget):
'''main GUI'''

# allow to move motors by keypresses (could move more than one motor at once!)
movekeyPressed = pyqtSignal(QtCore.QEvent)
Expand Down Expand Up @@ -162,19 +160,23 @@ def __init__(self):
self.setLayout(layout)

def onLedKeyPressed(self, event):
'''turn on the LED'''
robot.led_on()

def onLedKeyReleased(self, event):
'''turn off the LED'''
robot.led_off()

def onMoveKeyPressed(self, event):
'''send a move command when key is pressed'''
movement = robot.MOVE_DIRECTION[event.key() in self.positive_keys]
axis = self.keydict[event.key()]
if self.axis_states[axis] == robot.STOP_MOVE:
robot.AXES[axis].put(movement)
self.axis_states[axis] = movement

def onMoveKeyReleased(self, event):
'''send a STOP when key is released'''
movement = robot.MOVE_DIRECTION[event.key() in self.positive_keys]
axis = self.keydict[event.key()]
if self.axis_states[axis] == movement:
Expand Down Expand Up @@ -207,6 +209,7 @@ def eventFilter(self, watched, event):


def main():
'''GUI starts here'''
app = QtGui.QApplication(sys.argv)
w = MainWindow()
w.show()
Expand Down

0 comments on commit 92ada23

Please sign in to comment.