Running the Mini-MOST LabVIEW Code
Revision 1.0 Nov 6, 2003
Revision 1.1 Feb 23, 2004
Revision 1.2 May 29, 2004
Revision 1.3 Nov 19, 2004
Paul Hubbard hubbard@sdsc.edu
Purpose
This document is for people needing to run the LabVIEW components of
the Mini-MOST demonstration. It covers getting a current copy of the
code, and the steps required to run it. It does not cover running NTCP
and the LabVIEW plugin therein. Questions should be directed to the
author's email address above.
Revision History
Revision 1.1
- removed the CVS information (downloads are now from official
releases),
- fixed the device number of the PCI motor controller
- Corrected the VI library names to match the code
- Added Prerequisites section
- Corrected some spelling errors
- Added 'Other programs' section
Revision 1.2
- Added note about 'feedback channel'
- Added note about start of data (expected results)
- Added a note on program startup order
- Added a note about streaming data and server daemon
Revision 1.3
- Updated my address
- Removed 'invalid channel' errors since code now validates same
- Removed 'stepper init' as code now does that as well
Overview and Background
This code contains the necessary programs and routines required to
implement a LabVIEW-based control system driven by the NEESGrid
Teleoperations Control Protocol, or NTCP. This includes a daemon to
handle the NTCP connection, thread-safe queuing and communications
routines, and all of the supporting code required. There are several
example and test programs included, as well as two complete control
systems for different hardware.
Prerequisites to Run the Mini-MOST
You need to have the following to run the DAQ and control programs:
- Windows (2000 or XP) PC, Pentium 4 or better, at least 512MB of
memory
- National Instruments DAQ card (or other supported DAQ device,
e.g. Firewire, SCXI, etc)
- LabVIEW 6.1 or newer with NI-DAQ installed
- National Instruments stepper control board, PCI 7342 or similar,
with Value or FlexMotion drivers installed
- LabVIEW Internet toolkit installed
- Zip program (WinZip or similar) to unpack the distribution
- PDF reader (Adobe Acrobat or compatible) to view the documentation
NI's 'Measurement and Automation Explorer' (MAX) must be installed,
with the following DAQ channels defined and valid:
- LoadCell (Units: Newtons)
- StrainGage (Units: microstrain)
- LVDT (Units: meters)
These should already be setup before you run any of the Mini-MOST code!
Note that the names must match exactly,
as LabVIEW is case-sensitive.
For the motor controller, you need to put the stepper on axis 2, with
the LVDT wired into ADC 1. The 'Mini-MOST Wiring' PDF has more details
and pictures for sensor and motor wiring.
Getting the Code
The latest release of the NEESGrid code can be found at http://www.neesgrid.org/software/
I will use version 2.1 in this example.
(If you need to get the absolute newest code, it's always available
via CVS, in the 'lv-programs' package. See also the CVS instructions for
more information.)
Select 'DAQ distribution', and save it to your desktop.
Using your unzip program, unpack the distribution onto your desktop.
This wil result in a new folder on your desktop, named something like
'neesgrid 2.1 DAQ'.
Inside this folder are the LabVIEW libraries containing the NEESGrid
code. You should see
- daemon-programs.llb
- daq-example.llb
- daq-testing.llb
- mini-most.llb
- MOST-programs.llb
- ntcp-examples.llb
- ntcp-subroutines.llb
- ntcp-testing.llb
- Subroutines.llb
Double-click on 'mini-most.llb'.
This is a library
containing the three top-level components: DAQ program, control
program, and sensor test application. You will also need to open 'daemon-programs.llb' - it has the
network server programs that manage communications with the NTCP
(control) and streaming data servers.
Components and Theory of Operation
There are three components in the code, and one optional:
- Control daemon. This initializes the various threadsafe queues,
TCP port, response semaphore, and logfile. This must be running for
NTCP to communicate with the control program. You should usually run it
first. Note that you need not restart this if the plugin restarts - it
has its own logic to handle TCP errors.
- Control program. This handles the control hardware, writes the
actuators.ini file that defines the control point, and responds to
getControlPoint requests. When it is run, it first moves the motor to
the zero position, measures the force on the load cell, and then saves
that reading as the load cell offset which it subtracts from all
subsequent readings. Note that the control program does not move the
motors when ntcp connects, opens or closes a session, however stopping
and restarting it will re-zero the motor.
- DAQ program. This handles all of the DAQ channels. Upon receipt
of a inter-program event from the control program (sent at the end of
each move), this
- Writes a datum to the disk in a single file (For SAMBA or FTP
export, only if 'save to disk is selected on the front panel)
- FTP uploads the datum file if 'ftp upload' is selected on the
front panel
- Updates the master data file with the latest datum
- Server daemon (NSDS). This handles streaming numeric data to Chef
and any other clients. It is not required, and the DAQ code will run
fine without it. If it is running, and any client subscribes, the DAQ
will automatically stream the requested channels.
There are a couple of techniques used in the code that are of interest
- the persistant storage of the control point, and the inter-program
communications. When the control program first runs, it writes a data
file called actuators.ini in LabVIEW's home directory (thus the
requirement for admin privledges), which has one section for each
actuator in knows. Each one has a set of limits, units, geometry type,
parameter type, description and so forth. When a propose request
arrives, the control daemon reads this file, searches for an entry with
the correct geometry (e.g. 'displacement on X axis'), and then, if an
actuator is found, compares the proposed setting with the limits in the
file. While this defines a rectilinear convex space, it is easily
changed and works well for simple fixed limits. Changes to this would
be put in the 'cmd handler - propose.vi' code.
Consequently, the control program must be run before a propose arrives,
otherwise the propose may be accepted based on outdated information in
a stale file!
The communications between programs are mostly handled by LabVIEW's
thread safe queues. For example, the control daemon takes bytes from
the TCP connection, parses them into commands and parameters, and then
puts them into a 'pending commands' queue. A separate thread in the
control daemon reads these, dispatches those it can handled unaided
(proposals, open and close-session, get and set parameter, syntax
errors), and puts the others into their own queues. For example,
execute requests are moved into the 'pending positions' queue, where
they will be read and used by the control program. Responses from
proposals, executes, and getControlPoint are returned from different
threads, so the outgoing TCP connection is protected by a semaphore
initialized by the control program. The net effects are that the
various components run at their own pace, CPU usage is minimized, and
the various pieces are easily replaced. For examples of this, see how
the Mini-MOST control program the software-PID-driven 'ANCO control
program' differ.
Front Panel Settings and Configuration
Most of the code will load from disk with the correct defaults; what
follows is a brief explanation of what the various settings are for and
why you might wish to change them.
Control Daemon (in daemon-programs.llb)
There are a couple of things you might want to change. On the front
panel, you can change the location of the command log, a text file
containing all commands and responses sent from and to the ntcp plugin:

The other parameters are normally not visible, but if you scroll down
you can see the TCP listen port, queue depth (used in the threadsafe
queues as explained above) and the TCP listen timeout. None of these
should need to be changed.

Control Program (in mini-most.llb)

On the left are the startup settings, where we define the actuator
(used to validate propose requests): Name, description, range,
geometry, name/type, units and status. Note the scale factor - this is
used to convert from the units into motor steps. (In this case, the
units are meters, the above shows limits of +- 5cm deflection.
Just below that are display fields (gray color) showing when the
control program was started, and various messages (status, work in
progress, etc).
On the upper right, we define the motor control parameters - the 'Board
ID' is used to select which motor controller to use (we only have one
in the machine, so the ID is just one), the axis on that board (We are
using two, because we initially suspected a fault on axis one; there
was no fault be we never reverted to axis one), and the position mode
used (absolute or relative, we use absolute). Just to right are three
display fields that display motor status, as reported to this program.
Below the motor parameters are the NTCP settings - stiffness is
returned to getParameter as the f=kx stiffness of the beam, the
'feedback channel name' is reported back to getControlPoint as force
after subtracting the offset value. The offset value is determined at
startup - the program moves the motor to zero, and saves the value of
the feedback channel at that point. Since we are in the linear regime
and have a linear model, superposition applies and we can correct for a
non-zero force at zero by simply subtracting this value from all
readings. The corrected value is displayed in the 'feedback value'
display field.
The 'feedback channel' needs to be set to the DAQ channel measuring the load cell, normally
called 'LoadCell'. If you have a different channel name, you'll get a dialog
telling you that the channel name is invalid.
Note that this is the dialog you'll see any time you have a bad channel name. Correct it,
then right-click in the window and select 'Data operations/Save as default' then save the VI. This will
prevent it occurring in the future.
The large graph shows motor positions, in motor steps. To its left are
the transaction data, mostly for debugging purposes. Also displayed are
the number of positions received; this is the number that have been
approved and been executed.
DAQ Program (in mini-most.llb)

Working from the top of the window:
- The FTP parameters are used if you want to upload single-sample
datum files to the repository via FTP. If you do not need this, ignore
these fields and set 'Save to FTP?' to false. (As it is in the picture)
- DAQ device is only used if you have more than one DAQ card in the
machine; we do not.
- DAQ channels is a list defining which channels are sampled and
saved to disk. As with the control programs, invalid channels names will yield
a dialog box that explains the error and stops the program.
- SAMBA shared directory and data file name: If 'Save to disk?' is
on, this saves datum files ('data-276.txt') to this directory for the
repository scraper to grab. Note that, if the scraper is not running,
Windows gets peevish when more than a thousand or so files are in the
same directory, so be sure and clean it out as required. The data file
name is where the complete data record (all steps) will be written.
- Initial sequence number - this is for restarting. The code writes
datum files in the format of name-sequence.txt, where sequence normally
starts at zero. You can start it at whatever you want if necessary.
- Time since last sample - when was the last trigger we got? (More
below)
- Last sample timestamp - ISO8601 time of last sample
- Samples taken - how many triggers have we seen since we began?
- The graph shows the channels selected in 'DAQ channels', in the
same order.
Program startup order
The control program, DAQ, server daemon and control daemon can be started in any order. I usually
start the control program and DAQ first, on the theory that its best to see if I have any
configuration errors (DAQ channel names especially) before I open the machine to remote
control and data streaming.
Once the control daemon is running, it waits for a connection from the NTCP container. This
happens when the NTCP client or simulation coordinator sends 'openSession'. This is a feature, actually.
In the current code revision, the connection is maintained until the NTCP shuts down; this will
change such that the connection is dropped when closeSession is called.
Expected results: What should you see when its working?
The normal test is to run the simulation coordinator for, say, ten steps and see if it crashes,
increase the number of steps, and repeat.
The acceleration looks like this (100 steps per second):
From this, you can see that the first few tens of steps will not show much if any displacement. Don't panic.
Also, max displacement doesn't occur until after 1000 steps. Also note that this plot is acceleration,
and the motors want displacement (double integration) so the motor plot will look different.
Other Programs
In the 'ntcp-testing.llb'
library are a couple of useful test applications you can use that
simulate the NTCP server and client. Single-step and sine wave sweeps
are both available, and make good tests of the local configuration.
Notes
Triggering is done by a LabVIEW mechanism called 'Occurrences.' These
are simple boolean semaphores that are set by the control program and
caught by the DAQ program. The occurrence is saved as a global
variable, and initialized by the control program. Generalized external
triggering is a work item for next year; this is an expedient
same-machine solution with minimal CPU and complexity requirements.
The repository must be monitoring the directory we export to (via FTP
or SAMBA) for Chef to see real-time data!