EPICS IOC

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 [1], removing modules that are not used, and adding support where appropriate.

[1]synApps: http://www.aps.anl.gov/bcda/synApps/

USB

The Linux host must provide a libusb support library. USB communications must be performed by root, so the IOC must run as root.

uses:drvAsynUSBPort.c : Asyn device support using local usb interface

asyn configuration of USB communications in IOC’s st.cmd file

1
2
drvAsynUSBPortConfigure("USB1", "Robotic Arm", 0x1267, 0, 0, 0, 0, 1)
asynOctetConnect("USB1", "USB1")

Databases

All actions of the robot are provided through a single EPICS database: edgeRoboArmIOC/support/ip-2-13/ipApp/Db/roboArm.db

The USB communication is controlled by asyn through a single PV:

USB communication through asyn

1
2
3
4
5
record(stringout, "$(P)$(A)send_cmd_str") {
  field(DESC, "send the motion command string")
  field(DTYP, "asyn robo stringParm")
  field(OUT, "@asyn($(PORT))")
}

The bit position of each motion axis is encoded in the database, such as:

bit command of each axis is encoded: elbow UP=16, DOWN=32, STOP=0

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
record(mbbo,  "$(P)$(A)elbow_move") {
  field(DESC, "elbow motion")
  field(DTYP, "Raw Soft Channel")
  field(ZRST, "STOP")
  field(ZRVL, "0")
  field(ONST, "UP")
  field(ONVL, "16")
  field(TWST, "DOWN")
  field(TWVL, "32")
  field(FLNK, "$(P)$(A)send_cmd.PROC  PP MS")
}

Commands for all axes are aggregated in these two records:

USB command assembled in two records

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
record(calc,  "$(P)$(A)send_cmd") {
  field(DESC, "send the motion command")
  field(INPA, "$(P)$(A)grip_move.RVAL      NPP NMS")
  field(INPB, "$(P)$(A)wrist_move.RVAL     NPP NMS")
  field(INPC, "$(P)$(A)elbow_move.RVAL     NPP NMS")
  field(INPD, "$(P)$(A)shoulder_move.RVAL  NPP NMS")
  field(CALC, "A+B+C+D")
  field(FLNK, "$(P)$(A)send_cmd_2.PROC      PP  MS")
}

record(scalcout, "$(P)$(A)send_cmd_2") {
  field(DESC, "send the motion command")
  field(INPA, "$(P)$(A)send_cmd.VAL        NPP NMS")
  field(INPB, "$(P)$(A)base_move.RVAL      NPP NMS")
  field(INPC, "$(P)$(A)led_onoff.VAL       NPP NMS")
  field(CALC, "STR(A)+' '+STR(B)+' '+STR(C)")
  field(OUT,  "$(P)$(A)send_cmd_str.VAL     PP  MS")
}

IOC startup

A standard xxx IOC from synApps was used to create the IOC for the robot. All configuration details are provided in the st.cmd and related scripts. The IOC is started by running the bash script edgeRoboArmIOC/support/xxx-5-6/iocBoot/iocLinux/run. An additional script is provided to run the IOC in a detached screen session: in-screen.sh.

cron task

A bash script was created to be run as a periodic (once a minute) cron task, checking to see if the IOC is not running. If not running, it checks if the robot’s USB connection is detected and then tries to start the IOC. With this task running, the EPICS IOC starts automatically after the Linux OS is booted and the robot arm is connected by USB. The file is stored in the startup directory: edgeRoboArmIOC/support/xxx-5-6/iocBoot/iocLinux/restart_ioc_check.sh

restart_ioc_check.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/bin/bash

# restart_ioc_check.sh
# must run as root to use USB support

# run by  crontab -e
#     * * * * *  /root/restart_ioc_check.sh 2>&1 /dev/null
#              field          allowed values
#              -----          --------------
#              minute         0-59
#              hour           0-23
#              day of month   1-31
#              month          1-12 (or names, see below)
#          day of week    0-7 (0 or 7 is Sun, or use names)
#
#  # auto-start the robotic arm IOC
#  * * * * *  /root/restart_ioc_check.sh 2>&1 /dev/null
#
#------------
#
# also, as root (do these steps BEFORE enabling the cron job):
#  cd /root
#  ln -s ${ST_CMD_DIR} ./ioc
#  ln -s ioc/restart_ioc_check.sh ./
#  ln -s ioc/is_ioc_up.py ./
 

export EPICS_HOST_ARCH=`/usr/local/epics/base/startup/EpicsHostArch`
export EPICS_BASE_BIN=/usr/local/epics/base/bin/${EPICS_HOST_ARCH}
export ROBOT_DIR=/usr/local/epics/epicsEdgeRoboArm
export IOC_TOP=${ROBOT_DIR}/edgeRoboArmIOC/support/xxx-5-6
export ST_CMD_DIR=${IOC_TOP}/iocBoot/iocLinux


# ID 1267:0000 Logic3 / SpectraVideo plc
export usb_connect=`lsusb | grep  "ID 1267:0000 Logic3 / SpectraVideo plc"`

if [ "${usb_connect}" != "" ]; then
  #echo "<${usb_connect}>"
  export ioc_off=`/root/is_ioc_up.py`
  if [ "${ioc_off}" != "" ]; then
    #echo "IOC is not running"
    ${EPICS_BASE_BIN}/caRepeater &

    cd  ${ST_CMD_DIR}
    ./in-screen.sh
  fi
fi

SNL state program (optional)

In an attempt to automate the actions of the robot arm in a programmed sequence, Jeff Gebhardt wrote a state notation language sequence program (and accompanying database). The automation allows for move sequences up to five steps. This support can be found in:

  • edgeRoboArmIOC/support/ip-2-13/ipApp/Db/roboArmSeq.db
  • edgeRoboArmIOC/support/ip-2-13/ipApp/Db/roboArmSeq_settings.req
  • edgeRoboArmIOC/support/ip-2-13/ipApp/src/RoboArm.st

A movie was created showing the robot locating, grasping, and lifting a toy block, then dropping it into a nearby coffee cup.

To accomplish this, the batteries were new and the robot, block, and coffee cup were placed in a known starting position.

Moves were programmed based on elapsed time. Due to lack of feedback encoding, backlash and windup of the motor gears, and unreliable positioning based on battery power available for a given time of movement, it is not realistic to program any sequence of more than 5 waypoints.

In short, we were lucky to get a good video. Took some careful work to be that lucky.

GUI support

Initial user interfaces created were:

  • CSS BOY
  • MEDM

Screens are provided for each.

Interesting to note the first “user” at the 2012 ANL Energy Showcase was a six-year old child who wanted to press the CSS BOY screen button directly with her finger, completely ignoring the offered mouse interface to the GUI.

(Now, with touch-screen laptops, the CSS BOY interface can be tested for multi-touch compatibility.)

Later, a Python GUI was created to work on the Raspberry Pi. This interface allowed the use of keyboard bindings to each of the GUI buttons. From this keyboard binding interface, a true multitouch capability was added.

Joystick support

See the section Joystick - IOC support (not really a client) 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. Once that works, the joystick is now ready to be used.