NEESgrid logo

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

Revision 1.2

Revision 1.3

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:
  1. Windows (2000 or XP) PC, Pentium 4 or better, at least 512MB of memory
  2. National Instruments DAQ card (or other supported DAQ device, e.g. Firewire, SCXI, etc)
  3. LabVIEW 6.1 or newer with NI-DAQ installed
  4. National Instruments stepper control board, PCI 7342 or similar, with Value or FlexMotion drivers installed
  5. LabVIEW Internet toolkit installed
  6. Zip program (WinZip or similar) to unpack the distribution
  7. 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:
  1. LoadCell (Units: Newtons)
  2. StrainGage (Units: microstrain)
  3. 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
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:
  1. 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.
  2. 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.
  3. 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
    1. 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)
    2. FTP uploads the datum file if 'ftp upload' is selected on the front panel
    3. Updates the master data file with the latest datum
  4. 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:

Control daemon screenshot

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 daemon - hidden settings

Control Program (in mini-most.llb)

Control program

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)

DAQ program

Working from the top of the window:

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):
seismograph trace
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!