Main Page   Compound List   File List   Compound Members   File Members  

ppdev_motion.c File Reference

Motion control for stages driven by unintelligent stepper motors. More...

#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <linux/ppdev.h>
#include <linux/parport.h>
#include "logerr.h"
#include "motion.h"

Compounds

struct  Axismapping
 Logical to physical axis mapping. More...

struct  Devicestate
 The bit pattern currently applied to the parallel port data register. More...

struct  Stagecontrol
 Grouping of definitions for one parallel port and all its dependent axes. More...

struct  Stagelocation
 Coordinates representing a position along multiple axes. More...

struct  Translation
 Everything needed to control a translational stage axis. More...


Typedefs

typedef const char * stagelabelp_t
 All the stage axis labels are immutable strings.

typedef const unsigned char axistates_t
 Representation of bit patterns controlling the stepper motor phases.


Functions

axismappingp_t newaxismapping (const unsigned int axes)
 Make a new logical to physical axis mapping table.

void disposeaxismapping (axismappingp_t themap)
 Destroy a logical to physical axis mapping table.

void setaxismapping (axismappingp_t themap, const unsigned int logical, const axismapentry_t physical)
 Change an entry in a logical to physical axis mapping table.

stagelocationp_t newstagelocation (unsigned int axes)
 Make a new generalized stage coordinate vector.

void disposestagelocation (stagelocationp_t theloc)
 Destroy a generalized stage coordinate vector.

void setstagelocation (stagelocationp_t theloc, const unsigned int axisn, const coord_t newval)
 Change one coordinate in a generalized stage coordinate vector.

coord_t getstagelocation (const stagelocationp_t theloc, const unsigned int axisn)
 Access one coordinate in a generalized stage coordinate vector.

stagecontrolp_t newstage (const axismappingp_t themap)
 Initialize the data structures representing a stage (including the axes).

void disposestage (stagecontrolp_t stage)
 Destroy a stage data structure (without checking to see if it is in use).

int openstage (stagecontrolp_t stage, const char *path, const int flags)
 Connect to the physical port controlling the stage.

int closestage (stagecontrolp_t stage)
 Halt control of the stage, without de-allocating all data structures.

int movestage (stagecontrolp_t stage, const stagelocationp_t motn)
 Issue a request that the stage move to a particular position.

int findstage (stagecontrolp_t stage, stagelocationp_t posn)
 Copy the various axis positions into a coordinate structure.

int stageactive (stagecontrolp_t stage)
 Examine the stage to find if it is active.


Detailed Description

Motion control for stages driven by unintelligent stepper motors.

Some stages rely on the controlling computer to handle the low-level details of the motors that drive them, in contrast to those that dedicate an intelligent controller to these tasks, with which the controlling computer can communicate using some high-level protocol over something like a serial interface.

This particular implementation is for stages driven by stepper motors connected directly to parallel ports. Individual phases on the motor are either active or inactive depending on whether a particular bit on a parallel interface is asserted or not. The software can rotate the motor only by suppling a sequence of bit patterns that will cause the motor phases to activate and de-activate in the correct order. Apart from possibly microswitches that change input bits on the parallel interface when the stage reaches a home position, only a count of the steps moved by each motor gives any indication of the actual stage position. Individual motors drive each axis of the stage, but more than one motor may share a single port, provided we can assign each a distinct group of bits within the port.

We have based the low-level parallel port control on the ppdev driver, which exposes the necessary details of the port to user-level programs under Linux. Unlike the Solaris version of the motion control code, this means we do not have to provide a custom-written kernel module; documentation for ppdev is included as part of the Linux kernel source, and Tim Waugh (one of the original authors) provides a manual at http://people.redhat.com/twaugh/parport/html/parportguide.html for the Linux 2.4 kernel version. We rely on a Posix Threads implementation for two important aspects of the stage motion control: a distinct thread becomes responsible for handling each axis of the stage, and variations in the timeouts as the threads wait on condition variables determine the variations in the motor speed.

Author:
University of Arizona Digital Image Analysis Lab
Date:
2003
Version:
$Id$

Define Documentation

#define resting_condition  
 

Value:

((a->pos == a->goalpos) && \
                      (a->delay >= a->maxdelay) && \
                      ((a->delta < 0) == (a->backlash == 0)) && \
                      ((a->delta > 0) == (a->backlash == a->maxlash)))


Function Documentation

int closestage stagecontrolp_t    stage
 

Halt control of the stage, without de-allocating all data structures.

This is the inverse of openstage(), returning to a state similar to that when the stage data structures were allocated but unused. We wait for stage activity to cease, cancel the controlling threads for each axis, place the port in a quiescent state, then close it.

Parameters:
stage  the open stage to be closed.
Returns:
an error code on failure, zero on success.
See also:
disposestage() , openstage()

void disposeaxismapping axismappingp_t    themap
 

Destroy a logical to physical axis mapping table.

Parameters:
themap  the map to destroy.
See also:
newaxismapping()

void disposestage stagecontrolp_t    stage
 

Destroy a stage data structure (without checking to see if it is in use).

Parameters:
stage  the stage to destroy.
See also:
newstage() , closestage()

void disposestagelocation stagelocationp_t    theloc
 

Destroy a generalized stage coordinate vector.

Parameters:
theloc  the stage coordinates to destroy.
See also:
newstagelocation()

int findstage stagecontrolp_t    stage,
stagelocationp_t    posn
 

Copy the various axis positions into a coordinate structure.

If the stage is at rest, this finds its current position; however if the axes are in motion the stage may have moved from the recorded position before this returns.

Parameters:
stage  the stage whose position will be found.
posn  where to record the coordinates.
Returns:
an error code on failure, zero on success.

coord_t getstagelocation const stagelocationp_t    theloc,
const unsigned int    axisn
 

Access one coordinate in a generalized stage coordinate vector.

Parameters:
theloc  the coordinate vector to examine.
axisn  selects the logical axis number.
Returns:
the current position ascribed to this axis.
See also:
setstagelocation()

int movestage stagecontrolp_t    stage,
const stagelocationp_t    motn
 

Issue a request that the stage move to a particular position.

Parameters:
stage  the stage to move.
motn  the requested position.
Returns:
an error code on failure, zero on success.

axismappingp_t newaxismapping const unsigned int    axes
 

Make a new logical to physical axis mapping table.

The logical axes are numbered from 0 to axes - 1, and the physical axes are initially assigned the same numbers.

Parameters:
axes  the number of axes in the mapping.
Returns:
the newly-allocated mapping.
See also:
disposeaxismapping() , setaxismapping()

stagecontrolp_t newstage const axismappingp_t    themap
 

Initialize the data structures representing a stage (including the axes).

The new stage is defined in terms of a logical to physical axis mapping, and we construct it by allocating not only the stage structure, but the structures that represent the physical port and the individual axes. However we leave to openstage() the task of opening the physical port and starting the threads responsible for controlling each axis.

Parameters:
themap  the logical to physical axis mapping.
Returns:
the newly-allocated stage structure.
See also:
openstage() , disposestage()

stagelocationp_t newstagelocation unsigned int    axes
 

Make a new generalized stage coordinate vector.

Parameters:
axes  the number of axes requiring positions.
Returns:
the newly-allocated position information.
See also:
disposestagelocation() , setstagelocation() , getstagelocation()

int openstage stagecontrolp_t    stage,
const char *    path,
const int    flags
 

Connect to the physical port controlling the stage.

We need a stage data structure previously allocated by newstage() and a path that defines the physical port controlling the stage hardware (something like /dev/parportN). We attempt to open the port, then perform some initialization on it (e.g., setting up control registers and making sure it is in a quiescent state), then start the detached threads controlling each axis.

Parameters:
stage  the previously allocated stage control structure.
path  the device port path.
flags  additional flags specifying attributes for the stage.
Returns:
an error code on failure, zero on success.
See also:
newstage() , closestage()

void setaxismapping axismappingp_t    themap,
const unsigned int    logical,
const axismapentry_t    physical
 

Change an entry in a logical to physical axis mapping table.

Parameters:
themap  the map to modify.
logical  the logical axis number.
physical  the new corresponding physical number.

void setstagelocation stagelocationp_t    theloc,
const unsigned int    axisn,
const coord_t    newval
 

Change one coordinate in a generalized stage coordinate vector.

Parameters:
theloc  the coordinate vector to modify.
axisn  selects the logical axis number.
newval  the new position ascribed to this axis.
See also:
getstagelocation()

int stageactive stagecontrolp_t    stage
 

Examine the stage to find if it is active.

We try to acquire all the locks on the stage structures, and immediately determine that the stage is busy if we can't acquire a lock, without examining the others. As soon as we find a locked axis that's not in its resting state we also immediately determine the stage must be busy. However we release all locks before returning, so it's quite possible that the stage is busy again by the time this returns, if no other conditions are imposed.

Parameters:
stage  the stage to examine.
Returns:
a non-zero code if the stage is active, zero if it is not.


Generated on Tue Jun 22 14:32:09 2004 for trees by doxygen1.2.18