14 Commits

Author SHA1 Message Date
75a1ff060d Added speed algorithm description 2024-08-06 16:30:44 -05:00
f85ae07d2b Update README.md
Missed a ' mark
2024-08-06 15:21:25 -05:00
3ecb9676c0 Update README.md
Clearer explanations
2024-08-06 12:54:43 -05:00
03a93101c1 Update README.md
Fixed some markdown formatting
2024-08-06 11:09:15 -05:00
95c227a553 Update README.md
Gave example IOC usage and described more about the process of initializing motors
2024-08-06 11:07:09 -05:00
3614a806ea Removed build status from readme. 2024-08-05 12:05:38 -05:00
b25f608e98 Removed old continuous integration scripts. 2024-08-05 11:58:21 -05:00
BScatterplot
841b6f5b41 Merge pull request #5 from Binary-Coalescence/Speed-conversion-update
Fixed speed conversions
2024-08-05 11:01:22 -05:00
2379c90d90 Fixed speed conversions
Fixed speed conversions based on testing data.
2024-08-05 10:56:31 -05:00
cf26f426df Revert "Updated speed conversions"
This reverts commit c1025d711b.
2024-08-02 16:37:24 -05:00
c1025d711b Updated speed conversions
Updated speed conversions based on test data.
2024-08-02 16:31:31 -05:00
8fc33fa14d Merge branch 'dev' 2024-07-05 09:11:27 -05:00
05a223bd17 Updated release doc with ACS -> DSM updates. 2024-07-05 09:10:48 -05:00
5d706d4879 Reverted release doc to undo rename clobbering. 2024-07-05 08:54:43 -05:00
16 changed files with 153 additions and 625 deletions

1
.ci

Submodule .ci deleted from 5764601630

View File

@@ -1,3 +0,0 @@
BASE=3.14
include modules

View File

@@ -1,3 +0,0 @@
BASE=3.15
include modules

View File

@@ -1,3 +0,0 @@
BASE=7.0
include modules

View File

@@ -1,70 +0,0 @@
#!/usr/bin/env python
import os
import shutil
import re
# Setup ANSI Colors (copied from cue.py)
ANSI_RED = "\033[31;1m"
ANSI_GREEN = "\033[32;1m"
ANSI_YELLOW = "\033[33;1m"
ANSI_BLUE = "\033[34;1m"
ANSI_MAGENTA = "\033[35;1m"
ANSI_CYAN = "\033[36;1m"
ANSI_RESET = "\033[0m"
ANSI_CLEAR = "\033[0K"
def cat(filename):
'''
Print the contents of a file
'''
with open(filename, 'r') as fh:
for line in fh:
print(line.strip())
def sanity_check(filename):
'''
Include the contents of a file in the github-actions log
'''
print("{}Contents of {}{}".format(ANSI_BLUE, filename, ANSI_RESET))
cat(filename)
print("{}End of {}{}".format(ANSI_BLUE, filename, ANSI_RESET))
if 'HOME' in os.environ:
# Linux & OS X
cache_dir = os.path.join(os.environ['HOME'], ".cache")
else:
# Windows
cache_dir = os.path.join(os.environ['HOMEDRIVE'], os.environ['HOMEPATH'], ".cache")
module_dir = os.getenv('GITHUB_WORKSPACE')
# Copy the github-actions RELEASE.local to the configure dir
filename = "configure/RELEASE.local"
shutil.copy("{}/RELEASE.local".format(cache_dir), filename)
# Get the variable from the example release file
example = "configure/EXAMPLE_RELEASE.local"
fh = open(example, "r")
lines = fh.readlines()
fh.close()
pObj = re.compile('(MOTOR_[^=]+)')
module_var = None
for line in lines:
mObj = pObj.match(line)
if mObj != None:
module_var = mObj.group()
break
# Add the path to the driver module to the RELEASE.local file, since it is needed by the example IOC
fh = open(filename, "a")
fh.write("{}={}\n".format(module_var, module_dir))
fh.close()
sanity_check(filename)
# Enable the building of example IOCs
filename = "configure/CONFIG_SITE.local"
fh = open(filename, 'w')
fh.write("BUILD_IOCS = YES")
fh.close()
sanity_check(filename)

View File

@@ -1,9 +0,0 @@
#!/usr/bin/env python
import os
import pprint
pprint.pprint(dict(os.environ), width = 1)
#!print("{}", breakmehere)

View File

@@ -1,9 +0,0 @@
MODULES="sncseq ipac asyn autosave busy motor"
SNCSEQ=R2-2-9
IPAC=master
ASYN=R4-42
AUTOSAVE=R5-10-2
BUSY=R1-7-3
MOTOR=master
MOTOR_RECURSIVE=NO

View File

@@ -1,43 +0,0 @@
#!/usr/bin/env python
import os
import shutil
# ugly hack: copy cue.py so that it can be imported
shutil.copy('.ci/cue.py', '.ci-local/travis')
from cue import *
def cat(filename):
'''
Print the contents of a file
'''
with open(filename, 'r') as fh:
for line in fh:
print(line.strip())
def sanity_check(filename):
'''
Include the contents of a file in the travis log
'''
print("{}Contents of {}{}".format(ANSI_BLUE, filename, ANSI_RESET))
cat(filename)
print("{}End of {}{}".format(ANSI_BLUE, filename, ANSI_RESET))
# Add the path to the driver module to the RELEASE.local file, since it is needed by the example IOC
update_release_local('MOTOR_DSM', os.getenv('TRAVIS_BUILD_DIR'))
# Copy the travis RELEASE.local to the configure dir
filename = "configure/RELEASE.local"
shutil.copy("{}/RELEASE.local".format(cachedir), filename)
sanity_check(filename)
# Enable the building of example IOCs
filename = "configure/CONFIG_SITE.local"
fh = open(filename, 'w')
fh.write("BUILD_IOCS = YES")
fh.close()
sanity_check(filename)
# Remove cue.py
os.remove('.ci-local/travis/cue.py')
os.remove('.ci-local/travis/cue.pyc')

View File

@@ -1,211 +0,0 @@
# .github/workflows/ci-scripts-build.yml for use with EPICS Base ci-scripts
# (see: https://github.com/epics-base/ci-scripts)
# This is YAML - indentation levels are crucial
# Set the 'name:' properties to values that work for you (MYMODULE)
name: "GHA full build"
# Only run manually
on:
workflow_dispatch
env:
SETUP_PATH: .ci-local:.ci
# For the sequencer on Linux/Windows/MacOS
APT: re2c
CHOCO: re2c
BREW: re2c
jobs:
build-base:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
# Set environment variables from matrix parameters
env:
CMP: ${{ matrix.cmp }}
BCFG: ${{ matrix.configuration }}
BASE: ${{ matrix.base }}
WINE: ${{ matrix.wine }}
RTEMS: ${{ matrix.rtems }}
RTEMS_TARGET: ${{ matrix.rtems_target }}
EXTRA: ${{ matrix.extra }}
TEST: ${{ matrix.test }}
SET: ${{ matrix.set }}
strategy:
fail-fast: false
matrix:
# Job names also name artifacts, character limitations apply
include:
- os: ubuntu-20.04
cmp: gcc
configuration: default
wine: "64"
base: "7.0"
set: modules
name: "Ub-20 gcc-9 + MinGW"
- os: ubuntu-20.04
cmp: gcc
configuration: static
wine: "64"
base: "7.0"
set: modules
name: "Ub-20 gcc-9 + MinGW, static"
- os: ubuntu-20.04
cmp: gcc
configuration: static
extra: "CMD_CXXFLAGS=-std=c++11"
base: "7.0"
set: modules
name: "Ub-20 gcc-9 C++11, static"
- os: ubuntu-20.04
cmp: clang
configuration: default
extra: "CMD_CXXFLAGS=-std=c++11"
base: "7.0"
set: modules
name: "Ub-20 clang-10 C++11"
### fails building autosave
#!- os: ubuntu-20.04
#! cmp: gcc
#! configuration: default
#! rtems: "4.10"
#! base: "7.0"
#! set: modules
#! name: "Ub-20 gcc-9 + RT-4.10"
- os: ubuntu-20.04
cmp: gcc
configuration: default
rtems: "4.9"
base: "7.0"
set: modules
name: "Ub-20 gcc-9 + RT-4.9"
### fails building asyn
#!- os: ubuntu-20.04
#! cmp: gcc
#! configuration: default
#! rtems: "5"
#! rtems_target: RTEMS-pc686-qemu
#! base: "7.0"
#! set: modules
#! name: "Ub-20 gcc-9 + RT-5.1 pc686"
### fails building autosave
#!- os: ubuntu-20.04
#! cmp: gcc
#! configuration: default
#! rtems: "5"
#! rtems_target: RTEMS-beatnik
#! test: NO
#! base: "7.0"
#! set: modules
#! name: "Ub-20 gcc-9 + RT-5.1 beatnik"
- os: ubuntu-18.04
cmp: gcc
configuration: default
base: "7.0"
set: modules
name: "Ub-18 gcc-7"
### g++-8 not found
#!- os: ubuntu-18.04
#! cmp: gcc-8
#! utoolchain: true
#! configuration: default
#! base: "7.0"
#! set: modules
#! name: "Ub-18 gcc-8"
#!- os: ubuntu-20.04
#! cmp: gcc-8
#! utoolchain: true
#! configuration: default
#! base: "7.0"
#! set: modules
#! name: "Ub-20 gcc-8"
- os: ubuntu-20.04
cmp: clang
configuration: default
base: "7.0"
set: modules
name: "Ub-20 clang-10"
- os: macos-latest
cmp: clang
configuration: default
base: "7.0"
set: modules
name: "MacOS clang-12"
- os: windows-2019
cmp: gcc
configuration: default
base: "7.0"
set: modules
name: "Win2019 MinGW"
- os: windows-2019
cmp: gcc
configuration: static
base: "7.0"
set: modules
name: "Win2019 MinGW, static"
- os: windows-2019
cmp: vs2019
configuration: default
base: "7.0"
set: modules
name: "Win2019 MSC-19"
- os: windows-2019
cmp: vs2019
configuration: static
base: "7.0"
set: modules
name: "Win2019 MSC-19, static"
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Automatic core dumper analysis
uses: mdavidsaver/ci-core-dumper@master
- name: "apt-get install"
run: |
sudo apt-get update
sudo apt-get -y install qemu-system-x86 g++-mingw-w64-x86-64 gdb
if: runner.os == 'Linux'
- name: "apt-get install ${{ matrix.cmp }}"
run: |
sudo apt-get -y install software-properties-common
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get -y install ${{ matrix.cmp }}
if: matrix.utoolchain
- name: Sanity Check
run: python .ci-local/github-actions/sanity-check.py
- name: Prepare and compile dependencies
run: python .ci/cue.py prepare
- name: Patch main module
run: python .ci-local/github-actions/post-prepare.py
- name: Build main module
run: python .ci/cue.py build
- name: Run main module tests
run: python .ci/cue.py test
- name: Upload tapfiles Artifact
uses: actions/upload-artifact@v2
with:
name: tapfiles ${{ matrix.name }}
path: '**/O.*/*.tap'
- name: Collect and show test results
run: python .ci/cue.py test-results

View File

@@ -1,109 +0,0 @@
# .github/workflows/ci-scripts-build.yml for use with EPICS Base ci-scripts
# (see: https://github.com/epics-base/ci-scripts)
# This is YAML - indentation levels are crucial
# Set the 'name:' properties to values that work for you (MYMODULE)
name: "GHA build"
# Trigger on pushes to the master branch and PRs
on:
push:
paths-ignore:
- 'documentation/*'
- '**/*.html'
- '**/*.md'
- '.github/workflows/ci-scripts-build-full.yml'
branches:
- master
pull_request:
paths-ignore:
- 'documentation/*'
- '**/*.html'
- '**/*.md'
- '.github/workflows/ci-scripts-build-full.yml'
env:
SETUP_PATH: .ci-local:.ci
# For the sequencer on Linux/Windows/MacOS
APT: re2c
CHOCO: re2c
BREW: re2c
jobs:
build-base:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
# Set environment variables from matrix parameters
env:
CMP: ${{ matrix.cmp }}
BCFG: ${{ matrix.configuration }}
BASE: ${{ matrix.base }}
WINE: ${{ matrix.wine }}
RTEMS: ${{ matrix.rtems }}
RTEMS_TARGET: ${{ matrix.rtems_target }}
EXTRA: ${{ matrix.extra }}
TEST: ${{ matrix.test }}
SET: ${{ matrix.set }}
strategy:
fail-fast: false
matrix:
# Job names also name artifacts, character limitations apply
include:
- os: ubuntu-20.04
cmp: gcc
configuration: default
base: "7.0"
set: modules
name: "7.0 Ub-20 gcc-9"
- os: macos-latest
cmp: clang
configuration: default
base: "3.15"
set: modules
name: "3.15 MacOS clang-12"
- os: windows-2019
cmp: vs2019
configuration: static
base: "3.15"
set: modules
name: "3.15 Win VS2019, static"
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Automatic core dumper analysis
uses: mdavidsaver/ci-core-dumper@master
- name: "apt-get install"
run: |
sudo apt-get update
sudo apt-get -y install qemu-system-x86 g++-mingw-w64-x86-64 gdb
if: runner.os == 'Linux'
- name: "apt-get install ${{ matrix.cmp }}"
run: |
sudo apt-get -y install software-properties-common
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get -y install ${{ matrix.cmp }}
if: matrix.utoolchain
- name: Sanity Check
run: python .ci-local/github-actions/sanity-check.py
- name: Prepare and compile dependencies
run: python .ci/cue.py prepare
- name: Patch main module
run: python .ci-local/github-actions/post-prepare.py
- name: Build main module
run: python .ci/cue.py build
- name: Run main module tests
run: python .ci/cue.py test
- name: Upload tapfiles Artifact
uses: actions/upload-artifact@v2
with:
name: tapfiles ${{ matrix.name }}
path: '**/O.*/*.tap'
- name: Collect and show test results
run: python .ci/cue.py test-results

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule ".ci"]
path = .ci
url = https://github.com/epics-base/ci-scripts

View File

@@ -1,143 +0,0 @@
# .travis.xml for use with EPICS Base ci-scripts
# (see: https://github.com/epics-base/ci-scripts)
language: cpp
compiler: gcc
dist: xenial
cache:
directories:
- $HOME/.cache
env:
global:
- SETUP_PATH=.ci-local:.ci
# for the sequencer on Windows
- CHOCO=re2c
addons:
apt:
packages:
# for all EPICS builds
- libreadline6-dev
- libncurses5-dev
- perl
# for clang compiler
- clang
# for mingw builds (32bit and 64bit)
- g++-mingw-w64-i686
- g++-mingw-w64-x86-64
# for RTEMS cross builds
- qemu-system-x86
homebrew:
packages:
# for the sequencer
- re2c
update: true
install:
- python .ci/cue.py prepare
# ugly hacks go here:
- python .ci-local/travis/post-prepare.py
script:
- python .ci/cue.py build
- python .ci/cue.py test
- python .ci/cue.py test-results
# If you need to do more during install and build,
# add a local directory to your module and do e.g.
# - ./.ci-local/travis/install-extras.sh
# Define build jobs
# Well-known variables to use
# SET source setup file
# EXTRA content will be added to make command line
# STATIC set to YES for static build (default: NO)
# TEST set to NO to skip running the tests (default: YES)
# VV set to make build scripts verbose (default: unset)
# Usually from setup files, but may be specified or overridden
# on a job line
# MODULES list of dependency modules
# BASE branch or release tag name of the EPICS Base to use
# <MODULE> branch or release tag for a specific module
# ... see README for setup file syntax description
jobs:
include:
# Older Base releases
- env: SET=base3-14
- env: SET=base3-14 BCFG=static
- env: SET=base3-15
- env: SET=base3-15 BCFG=static
# Default gcc, static build
- env: SET=base7-0
- env: SET=base7-0 BCFG=static
# Default clang build
- env: SET=base7-0
compiler: clang
- env: SET=base7-0 EXTRA="CMD_CXXFLAGS=-std=c++11"
compiler: clang
# Trusty: compiler versions very close to RHEL 7
- env: SET=base7-0
dist: trusty
- env: SET=base7-0 BCFG=debug
dist: trusty
# Other gcc versions (added as an extra package)
- env: SET=base7-0
compiler: gcc-6
addons: { apt: { packages: ["g++-6"], sources: ["ubuntu-toolchain-r-test"] } }
- env: SET=base7-0
compiler: gcc-7
addons: { apt: { packages: ["g++-7"], sources: ["ubuntu-toolchain-r-test"] } }
# Cross-compilations to Windows using MinGW and WINE
- env: SET=base7-0 WINE=32 TEST=NO BCFG=static
- env: SET=base7-0 WINE=64 TEST=NO
# Windows builds
- env: SET=base7-0
os: windows
compiler: vs2017
- env: SET=base7-0 BCFG=static
os: windows
compiler: vs2017
- env: SET=base7-0 BCFG=debug
os: windows
compiler: vs2017
# MacOS build
- env: SET=base7-0
os: osx
compiler: clang
# Cross-compilation to RTEMS
- env: SET=base7-0 RTEMS=4.9
- env: SET=base7-0 RTEMS=4.10

127
README.md
View File

@@ -3,23 +3,93 @@ motorDSM
EPICS motor drivers for the following [Dynamic Structures and Materials](https://www.dynamic-structures.com/) motor controllers: MD-90 EPICS motor drivers for the following [Dynamic Structures and Materials](https://www.dynamic-structures.com/) motor controllers: MD-90
[![Build Status](https://github.com/Binary-Coalescence/motorDSM/actions/workflows/ci-scripts-build.yml/badge.svg)](https://github.com/Binary-Coalescence/motorDSM/actions/workflows/ci-scripts-build.yml)
motorDSM is a submodule of [motor](https://github.com/epics-modules/motor). When motorDSM is built in the ``motor/modules`` directory, no manual configuration is needed. motorDSM is a submodule of [motor](https://github.com/epics-modules/motor). When motorDSM is built in the ``motor/modules`` directory, no manual configuration is needed.
motorDSM can also be built outside of motor by copying it's ``configure/EXAMPLE_RELEASE.local`` file to ``RELEASE.local`` and defining the paths to ``EPICS_BASE``, ``MOTOR``, and itself. motorDSM can also be built outside of motor by copying it's ``configure/EXAMPLE_RELEASE.local`` file to ``RELEASE.local`` and defining the paths to ``EPICS_BASE``, ``MOTOR``, and itself.
motorDSM contains an example IOC that is built if ``configure/CONFIG_SITE.local`` sets ``BUILD_IOCS = YES``. The example IOC can be built outside of the driver module. Copy ``iocs/dsmIOC/configure/EXAMPLE_RELEASE.local`` to ``RELEASE.local`` and uncomment and set the paths for the appropriate lines depending on whether motorDSM was built inside the motor module or independently. motorDSM contains an example IOC that is built if ``configure/CONFIG_SITE.local`` sets ``BUILD_IOCS = YES``. The example IOC can be built outside of the driver module. Copy ``iocs/dsmIOC/configure/EXAMPLE_RELEASE.local`` to ``RELEASE.local`` and uncomment and set the paths for the appropriate lines depending on whether motorDSM was built inside the motor module or independently.
To run the example IOC, in the ``iocs/dsmIOC/iocBoot/iocDsm`` directory, run # Running an example IOC
To run the example IOC, build the packages listed below, then:
1. Follow the steps in "Configuring the system for attached controllers" below.
2. Set the "EPICS_CA_ADDR_LIST" environment variable to include the IP address of the server.
If it's running on the same computer, you can use the loopback IP address.
`export EPICS_CA_ADDR_LIST='127.0.0.1'`
3. In the ``iocs/dsmIOC/iocBoot/iocDsm`` directory, run
```
$ ../../bin/linux-x86_64/dsm st.cmd.md90 $ ../../bin/linux-x86_64/dsm st.cmd.md90
```
for one attached MD-90 controller, or for one attached MD-90 controller, or
```
$ ../../bin/linux-x86_64/dsm st.cmd.md90.multi $ ../../bin/linux-x86_64/dsm st.cmd.md90.multi
```
for eight attached MD-90 controllers. Edit this file to use more than one unit; simply comment out the ones you don't need.
for eight attached MD-90 controllers. You may need to change the path(s) for the serial port(s) in ``st.cmd.md90`` or ``st.cmd.md90.multi`` if the MD-90 is not attached at ``/dev/ttyUSB0``. 4. Test using the `caget` and `caput` arguments as described in the "Example usage" section below.
# Configuring the system for attached controllers
-------------------------------------------------
The following steps must be used in either st.cmd.md90 (for a single unit) or in st.cmd.md90.multiple (for multiple units).
st.cmd.md90.multiple includes 8 motors predefined on /dev/ttyUSB0 through /dev/ttyUSB7. Comment out all motors you don't need.
**1. Define a new serial port named "serial0" and set the location of the physical port**
`drvAsynSerialPortConfigure([serial name], [device location], 0, 0, 0)`
*e.g., `drvAsynSerialPortConfigure("serial0", "/dev/ttyUSB0", 0, 0, 0)`*
**2. Configure the port**
- Baud = 115200
- Bits = 8
- Parity = none
- Stop bits = 1
- Input end of message: "\r"
- Output end of message: "\r"
- Trace IO mask: 2
```
asynSetOption([serial name], 0, "baud", "115200")
asynSetOption([serial name], 0, "bits", "8")
asynSetOption([serial name], 0, "parity", "none")
asynSetOption([serial name], 0, "stop", "1")
asynOctetSetInputEos("serial0", 0, "\r")
asynOctetSetOutputEos("serial0", 0, "\r")
asynSetTraceIOMask("serial0", 0, 2)
```
where `[serial name]` is the name you assigned in step 1, surrounded by double quotes.
**3. Set initial parameters**
- Power supply enabled (`EPS` command)
- Deadband = 10 nm (`SDB 10` command)
```
asynOctetConnect("initConnection", [serial name], 0)
asynOctetWrite("initConnection", "EPS")
asynOctetWrite("initConnection", "SDB 10")
asynOctetDisconnect('initConnection')
```
**4. Create MD90 Controller object**
`MD90CreateController([controller name], [serial name], 1, 100, 5000)`
where `[controller name]` is the name of the motor to assign. Convention is to use "MD90n", starting with n=0.
**5. Intialize the IOC**
After the call to `iocInit` (still in the st.cmd.md90[.multiple] file), issue the following commands for each motor. The example below uses `DSM:m0` but it should be run for each line described in motor.substitutions.md90 (or motor.substitutions.md90.multiple).
````
dbpf("DSM:m0.RTRY", "0") #sets retries to 0; this is automatic on the MD90
dbpf("DSM:m0.TWV", "0.1") #Tweak distance
dbpf("DSM:m0.VMAX", "1.0") #Sets max velocity to 1 mm/s
dbpf("DSM:m0.HVEL", "1.0") #Sets max velocity to 1 mm/s
````
**6. Update the substitutions file**
Save and close the st.cmd file you've been configuring, then open the motor substitutions file (motor.substitutions.md90[.multiple]).
Ensure the values in the `pattern` block's `PORT` field match the names used in the std.cmd file.
Note that, despite this field being called "Port", they use the names of the MD90 Controller object defined above (by default, MD900, MD901, etc.
Do __not__ use the direct serial port names (by default, serial0, serial1, etc.).
# Compiling motorDSM
------------------------ ------------------------
@@ -110,3 +180,50 @@ In ``motorDSM/iocs/dsmIOC/configure``, copy ``EXAMPLE_RELEASE.local`` to ``RELEA
$ cd $SUPPORT/motorDSM $ cd $SUPPORT/motorDSM
$ make distclean $ make distclean
$ make $ make
------------------------
# Example usage
After building, run the example IOC described at the top of this section in one terminal window.
Open another terminal window and navigate to [EPICS install directory]/epics-base/bin/linux-x86_64/ (or wherever you built EPICS base.
Use the commands `caput` and `caget` to set and read process variables.
For example, to get the current position, use `./caget DSM:m0.REP`. This reads the REP variable, which is the "Raw Encoder Position". Set m0 to m1, m2, etc. for multiple motors.
Other examples
-------------------------
Homing the motor (must be done before you can issue position commands):
`./caput DSM:m0.HOMF 1 #Begins homing sequence in the forward direction`
`./caput DSM:m0.HOMR 1 #Begins homing sequence in the reverse direction`
Moving to a position target:
`./caput DSM:m0.VAL 2.345 #Moves to 2.345 mm`
Setting a velocity target:
`./caput DSM:m0.VELO 0.5 #Sets velocity target to 0.5 mm/s`
(Note that velocity targets are appropriate only. They adjust the step rate of the motor and are not guaranteed to be exact.)
A note aboue velocity targets
-----------------------------
The I-20 motor driven by the MD-90 is a closed loop "step and repeat" motor that takes full steps towards its position target until it is
close, then will perform linear extensions to close the loop on the target position. This is handled internally on the MD-90, not by
EPICS.
The Velocity target parameter sets the step frequency
at which the motor operates on its way to the target position. The speed is not closed loop, and will depend on external loads, environmental
conditions, etc. A speed target of 1 mm/s will generate a roughly 1 mm/s motion, but it is not guaranteed.
Additionally, due to the way EPICS operates, setting VELO will not immediately send a command to the MD90. Instead, EPICS remembers the last value you set, and will set this new
velocity target when it sends the next move command. **However, the motor must not be in servo mode to accept a new velocity target.**
The motor enters servo mode when you send a new position target, and stays in servo mode until you issue a Stop command
(by setting the `DSM:m0.STOP` parameter to 1).
If you do not disable servo prior to issuing a Move command at the new velocity, then VELO will become out of sync with the actual motor
velocity, and EPICS will return error 3 "Cannot execute while moving" in its console each time you issue a Move command.
This is because each Move command internally sends a "Set step frequenc" command, which will error if you do not Stop the motor first.
Reading the VELO parameter at this point will return the wrong value- it returns the value you requested, not the actual speed setting
on the motor.
To fix this, you must Stop the motor, then send a new Move command. At

View File

@@ -1,4 +1,23 @@
# motorDsm Releases # motorDSM Releases
## __v0.9.0-alpha__
### Changes since motorAcs R1-1-1
#### New features
* Global rename Acs -> DSM and MCB-4B -> MD-90
* Updated motor controller and axis methods to work with the DSM MD-90 controller
* Updated example IOC startup scripts for the MD-90
#### Modifications to existing features
* Removed Acs controller interface
#### Bug fixes
* None
# motorAcs Releases
## __R1-1-1 (2023-04-11)__ ## __R1-1-1 (2023-04-11)__
R1-1-1 is a release based on the master branch. R1-1-1 is a release based on the master branch.
@@ -27,22 +46,22 @@ R1-1 is a release based on the master branch.
* None * None
#### Modifications to existing features #### Modifications to existing features
* Commit [1bd580a](https://github.com/epics-motor/motorDsm/commit/1bd580a87869fb140939978c0b06856917282da9): ``iocsh`` dir moved into ``dsmApp`` dir; ``DSM_MD90.iocsh`` is now installed at build time * Commit [1bd580a](https://github.com/epics-motor/motorAcs/commit/1bd580a87869fb140939978c0b06856917282da9): ``iocsh`` dir moved into ``acsApp`` dir; ``ACS_MCB4B.iocsh`` is now installed at build time
#### Bug fixes #### Bug fixes
* Commit [5ab502c](https://github.com/epics-motor/motorDsm/commit/5ab502c53ac81885e2a511ade95f22d0a0db4f43): Include ``$(MOTOR)/modules/RELEASE.$(EPICS_HOST_ARCH).local`` instead of ``$(MOTOR)/configure/RELEASE`` * Commit [5ab502c](https://github.com/epics-motor/motorAcs/commit/5ab502c53ac81885e2a511ade95f22d0a0db4f43): Include ``$(MOTOR)/modules/RELEASE.$(EPICS_HOST_ARCH).local`` instead of ``$(MOTOR)/configure/RELEASE``
* Pull request [#1](https://github.com/epics-motor/motorDsm/pull/1): Eliminated compiler warnings * Pull request [#1](https://github.com/epics-motor/motorAcs/pull/1): Eliminated compiler warnings
## __R1-0 (2019-04-18)__ ## __R1-0 (2019-04-18)__
R1-0 is a release based on the master branch. R1-0 is a release based on the master branch.
### Changes since motor-6-11 ### Changes since motor-6-11
motorDsm is now a standalone module, as well as a submodule of [motor](https://github.com/epics-modules/motor) motorAcs is now a standalone module, as well as a submodule of [motor](https://github.com/epics-modules/motor)
#### New features #### New features
* motorDsm can be built outside of the motor directory * motorAcs can be built outside of the motor directory
* motorDsm has a dedicated example IOC that can be built outside of motorDsm * motorAcs has a dedicated example IOC that can be built outside of motorAcs
#### Modifications to existing features #### Modifications to existing features
* None * None

View File

@@ -185,7 +185,7 @@ asynStatus MD90Axis::sendAccelAndVelocity(double acceleration, double velocity)
// Velocity provided in steps/sec // Velocity provided in steps/sec
// Our unit step size of the encoder is 10 nm, but the motor moves in steps approx. 5 micrometers. // Our unit step size of the encoder is 10 nm, but the motor moves in steps approx. 5 micrometers.
// Motor controller accepts step frequency in Hz. // Motor controller accepts step frequency in Hz.
freq = NINT(fabs(velocity / 500.)); freq = NINT(fabs(velocity / COUNTS_PER_STEP));
sprintf(pC_->outString_, "SSF %d", freq); sprintf(pC_->outString_, "SSF %d", freq);
status = pC_->writeReadController(); status = pC_->writeReadController();
if (!status) { if (!status) {
@@ -446,7 +446,7 @@ asynStatus MD90Axis::poll(bool *moving)
if (comStatus) goto skip; if (comStatus) goto skip;
// The response string is of the form "0: Current step frequency: 100" // The response string is of the form "0: Current step frequency: 100"
sscanf(pC_->inString_, "%d: %[^:]: %d", &replyStatus, replyString, &replyValue); sscanf(pC_->inString_, "%d: %[^:]: %d", &replyStatus, replyString, &replyValue);
velocity = replyValue * 500.0; velocity = replyValue * COUNTS_PER_STEP;
setDoubleParam(pC_->motorVelocity_, velocity); setDoubleParam(pC_->motorVelocity_, velocity);
// Read the current motor integral gain (range 1-1000) // Read the current motor integral gain (range 1-1000)

View File

@@ -2,9 +2,6 @@
FILENAME... MD90Driver.h FILENAME... MD90Driver.h
USAGE... Motor driver support for the DSM MD-90 controller. USAGE... Motor driver support for the DSM MD-90 controller.
Mark Rivers
March 1, 2012
*/ */
#include "asynMotorController.h" #include "asynMotorController.h"
@@ -15,6 +12,8 @@ March 1, 2012
// No controller-specific parameters yet // No controller-specific parameters yet
#define NUM_MD90_PARAMS 0 #define NUM_MD90_PARAMS 0
#define COUNTS_PER_STEP 1000.0 //Number of encoder counts per motor step (measured by testing)
class epicsShareClass MD90Axis : public asynMotorAxis class epicsShareClass MD90Axis : public asynMotorAxis
{ {
public: public: