\section{ppdev\_\-motion.c File Reference}
\label{ppdev__motion_8c}\index{ppdev_motion.c@{ppdev\_\-motion.c}}
Motion control for stages driven by unintelligent stepper motors. 

{\tt \#include $<$unistd.h$>$}\par
{\tt \#include $<$errno.h$>$}\par
{\tt \#include $<$stdlib.h$>$}\par
{\tt \#include $<$sys/time.h$>$}\par
{\tt \#include $<$fcntl.h$>$}\par
{\tt \#include $<$sys/ioctl.h$>$}\par
{\tt \#include $<$pthread.h$>$}\par
{\tt \#include $<$linux/ppdev.h$>$}\par
{\tt \#include $<$linux/parport.h$>$}\par
{\tt \#include \char`\"{}logerr.h\char`\"{}}\par
{\tt \#include \char`\"{}motion.h\char`\"{}}\par
\subsection*{Classes}
\begin{CompactItemize}
\item 
struct {\bf Devicestate}
\begin{CompactList}\small\item\em The bit pattern currently applied to the parallel port data register. \item\end{CompactList}\item 
struct {\bf Axismapping}
\begin{CompactList}\small\item\em Logical to physical axis mapping. \item\end{CompactList}\item 
struct {\bf Stagelocation}
\begin{CompactList}\small\item\em Coordinates representing a position along multiple axes. \item\end{CompactList}\item 
struct {\bf Stagecontrol}
\begin{CompactList}\small\item\em Grouping of definitions for one parallel port and all its dependent axes. \item\end{CompactList}\item 
struct {\bf Translation}
\begin{CompactList}\small\item\em Everything needed to control a translational stage axis. \item\end{CompactList}\end{CompactItemize}
\subsection*{Defines}
\begin{CompactItemize}
\item 
\#define {\bf resting\_\-condition}(a)
\end{CompactItemize}
\subsection*{Typedefs}
\begin{CompactItemize}
\item 
typedef const char $\ast$ {\bf stagelabelp\_\-t}\label{ppdev__motion_8c_a1}

\begin{CompactList}\small\item\em All the stage axis labels are immutable strings. \item\end{CompactList}\item 
typedef const unsigned char {\bf axistates\_\-t}\label{ppdev__motion_8c_a5}

\begin{CompactList}\small\item\em Representation of bit patterns controlling the stepper motor phases. \item\end{CompactList}\end{CompactItemize}
\subsection*{Enumerations}
\begin{CompactItemize}
\item 
enum {\bf stagecommandflags} \{ {\bf STAGE\_\-DEAD} =  0, 
{\bf STAGE\_\-LIVE} =  1, 
{\bf STAGE\_\-COMMANDABLE} =  1$<$$<$1, 
{\bf STAGE\_\-WATCHABLE} =  1$<$$<$2
 \}
\begin{CompactList}\small\item\em Stage status flags. \item\end{CompactList}\end{CompactItemize}
\subsection*{Functions}
\begin{CompactItemize}
\item 
{\bf axismappingp\_\-t} {\bf newaxismapping} (const unsigned int axes)
\begin{CompactList}\small\item\em Make a new logical to physical axis mapping table. \item\end{CompactList}\item 
void {\bf disposeaxismapping} ({\bf axismappingp\_\-t} themap)
\begin{CompactList}\small\item\em Destroy a logical to physical axis mapping table. \item\end{CompactList}\item 
void {\bf setaxismapping} ({\bf axismappingp\_\-t} themap, const unsigned int logical, const axismapentry\_\-t physical)
\begin{CompactList}\small\item\em Change an entry in a logical to physical axis mapping table. \item\end{CompactList}\item 
{\bf stagelocationp\_\-t} {\bf newstagelocation} (unsigned int axes)
\begin{CompactList}\small\item\em Make a new generalized stage coordinate vector. \item\end{CompactList}\item 
void {\bf disposestagelocation} ({\bf stagelocationp\_\-t} theloc)
\begin{CompactList}\small\item\em Destroy a generalized stage coordinate vector. \item\end{CompactList}\item 
void {\bf setstagelocation} ({\bf stagelocationp\_\-t} theloc, const unsigned int axisn, const coord\_\-t newval)
\begin{CompactList}\small\item\em Change one coordinate in a generalized stage coordinate vector. \item\end{CompactList}\item 
coord\_\-t {\bf getstagelocation} (const {\bf stagelocationp\_\-t} theloc, const unsigned int axisn)
\begin{CompactList}\small\item\em Access one coordinate in a generalized stage coordinate vector. \item\end{CompactList}\item 
{\bf stagecontrolp\_\-t} {\bf newstage} (const {\bf axismappingp\_\-t} themap)
\begin{CompactList}\small\item\em Initialize the data structures representing a stage (including the axes). \item\end{CompactList}\item 
void {\bf disposestage} ({\bf stagecontrolp\_\-t} stage)
\begin{CompactList}\small\item\em Destroy a stage data structure (without checking to see if it is in use). \item\end{CompactList}\item 
int {\bf openstage} ({\bf stagecontrolp\_\-t} stage, const char $\ast$path, const int flags)
\begin{CompactList}\small\item\em Connect to the physical port controlling the stage. \item\end{CompactList}\item 
int {\bf closestage} ({\bf stagecontrolp\_\-t} stage)
\begin{CompactList}\small\item\em Halt control of the stage, without de-allocating all data structures. \item\end{CompactList}\item 
int {\bf movestage} ({\bf stagecontrolp\_\-t} stage, const {\bf stagelocationp\_\-t} motn)
\begin{CompactList}\small\item\em Issue a request that the stage move to a particular position. \item\end{CompactList}\item 
int {\bf findstage} ({\bf stagecontrolp\_\-t} stage, {\bf stagelocationp\_\-t} posn)
\begin{CompactList}\small\item\em Copy the various axis positions into a coordinate structure. \item\end{CompactList}\item 
int {\bf stageactive} ({\bf stagecontrolp\_\-t} stage)
\begin{CompactList}\small\item\em Examine the stage to find if it is active. \item\end{CompactList}\end{CompactItemize}


\subsection{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 {\tt 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 {\tt ppdev} is included as part of the Linux kernel source, and Tim Waugh (one of the original authors) provides a manual at {\tt 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.

\begin{Desc}
\item[Author:]University of Arizona Digital Image Analysis Lab \end{Desc}
\begin{Desc}
\item[Date:]2003 \end{Desc}
\begin{Desc}
\item[Version:]\begin{Desc}
\item[Id]{\bf ppdev\_\-motion.c}{\rm (p.\,\pageref{ppdev__motion_8c})},v 1.6 2004/11/18 19:14:06 mmunro Exp \end{Desc}
\end{Desc}


\subsection{Define Documentation}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!resting_condition@{resting\_\-condition}}
\index{resting_condition@{resting\_\-condition}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}\#define resting\_\-condition(a)}\label{ppdev__motion_8c_a0}


{\bf Value:}

\footnotesize\begin{verbatim}((a->pos == a->goalpos) && \
                      (a->delay >= a->maxdelay) && \
                      ((a->delta < 0) == (a->backlash == 0)) && \
                      ((a->delta > 0) == (a->backlash == a->maxlash)))
\end{verbatim}\normalsize 


\subsection{Function Documentation}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!closestage@{closestage}}
\index{closestage@{closestage}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}int closestage ({\bf stagecontrolp\_\-t} {\em stage})}\label{ppdev__motion_8c_a48}


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

This is the inverse of {\em {\bf openstage()}{\rm (p.\,\pageref{ppdev__motion_8c_a47})}\/}, 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. \begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em stage}]the open stage to be closed. \end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]an error code on failure, zero on success. \end{Desc}
\begin{Desc}
\item[See also:]{\bf disposestage()}{\rm (p.\,\pageref{ppdev__motion_8c_a45})} 

{\bf openstage()}{\rm (p.\,\pageref{ppdev__motion_8c_a47})} \end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!disposeaxismapping@{disposeaxismapping}}
\index{disposeaxismapping@{disposeaxismapping}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}void disposeaxismapping ({\bf axismappingp\_\-t} {\em themap})}\label{ppdev__motion_8c_a38}


Destroy a logical to physical axis mapping table. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em themap}]the map to destroy. \end{description}
\end{Desc}
\begin{Desc}
\item[See also:]{\bf newaxismapping()}{\rm (p.\,\pageref{ppdev__motion_8c_a37})} \end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!disposestage@{disposestage}}
\index{disposestage@{disposestage}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}void disposestage ({\bf stagecontrolp\_\-t} {\em stage})}\label{ppdev__motion_8c_a45}


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

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em stage}]the stage to destroy. \end{description}
\end{Desc}
\begin{Desc}
\item[See also:]{\bf newstage()}{\rm (p.\,\pageref{ppdev__motion_8c_a44})} 

{\bf closestage()}{\rm (p.\,\pageref{ppdev__motion_8c_a48})} \end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!disposestagelocation@{disposestagelocation}}
\index{disposestagelocation@{disposestagelocation}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}void disposestagelocation ({\bf stagelocationp\_\-t} {\em theloc})}\label{ppdev__motion_8c_a41}


Destroy a generalized stage coordinate vector. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em theloc}]the stage coordinates to destroy. \end{description}
\end{Desc}
\begin{Desc}
\item[See also:]{\bf newstagelocation()}{\rm (p.\,\pageref{ppdev__motion_8c_a40})} \end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!findstage@{findstage}}
\index{findstage@{findstage}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}int findstage ({\bf stagecontrolp\_\-t} {\em stage}, {\bf stagelocationp\_\-t} {\em posn})}\label{ppdev__motion_8c_a50}


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. \begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em stage}]the stage whose position will be found. \item[{\em posn}]where to record the coordinates. \end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]an error code on failure, zero on success. \end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!getstagelocation@{getstagelocation}}
\index{getstagelocation@{getstagelocation}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}coord\_\-t getstagelocation (const {\bf stagelocationp\_\-t} {\em theloc}, const unsigned int {\em axisn})}\label{ppdev__motion_8c_a43}


Access one coordinate in a generalized stage coordinate vector. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em theloc}]the coordinate vector to examine. \item[{\em axisn}]selects the logical axis number. \end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]the current position ascribed to this axis. \end{Desc}
\begin{Desc}
\item[See also:]{\bf setstagelocation()}{\rm (p.\,\pageref{ppdev__motion_8c_a42})} \end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!movestage@{movestage}}
\index{movestage@{movestage}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}int movestage ({\bf stagecontrolp\_\-t} {\em stage}, const {\bf stagelocationp\_\-t} {\em motn})}\label{ppdev__motion_8c_a49}


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

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em stage}]the stage to move. \item[{\em motn}]the requested position. \end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]an error code on failure, zero on success. \end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!newaxismapping@{newaxismapping}}
\index{newaxismapping@{newaxismapping}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}{\bf axismappingp\_\-t} newaxismapping (const unsigned int {\em axes})}\label{ppdev__motion_8c_a37}


Make a new logical to physical axis mapping table. 

The logical axes are numbered from 0 to {\em axes\/} - 1, and the physical axes are initially assigned the same numbers. \begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em axes}]the number of axes in the mapping. \end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]the newly-allocated mapping. \end{Desc}
\begin{Desc}
\item[See also:]{\bf disposeaxismapping()}{\rm (p.\,\pageref{ppdev__motion_8c_a38})} 

{\bf setaxismapping()}{\rm (p.\,\pageref{ppdev__motion_8c_a39})} \end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!newstage@{newstage}}
\index{newstage@{newstage}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}{\bf stagecontrolp\_\-t} newstage (const {\bf axismappingp\_\-t} {\em themap})}\label{ppdev__motion_8c_a44}


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 {\em {\bf openstage()}{\rm (p.\,\pageref{ppdev__motion_8c_a47})}\/} the task of opening the physical port and starting the threads responsible for controlling each axis. \begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em themap}]the logical to physical axis mapping. \end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]the newly-allocated stage structure. \end{Desc}
\begin{Desc}
\item[See also:]{\bf openstage()}{\rm (p.\,\pageref{ppdev__motion_8c_a47})} 

{\bf disposestage()}{\rm (p.\,\pageref{ppdev__motion_8c_a45})} \end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!newstagelocation@{newstagelocation}}
\index{newstagelocation@{newstagelocation}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}{\bf stagelocationp\_\-t} newstagelocation (unsigned int {\em axes})}\label{ppdev__motion_8c_a40}


Make a new generalized stage coordinate vector. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em axes}]the number of axes requiring positions. \end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]the newly-allocated position information. \end{Desc}
\begin{Desc}
\item[See also:]{\bf disposestagelocation()}{\rm (p.\,\pageref{ppdev__motion_8c_a41})} 

{\bf setstagelocation()}{\rm (p.\,\pageref{ppdev__motion_8c_a42})} 

{\bf getstagelocation()}{\rm (p.\,\pageref{ppdev__motion_8c_a43})} \end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!openstage@{openstage}}
\index{openstage@{openstage}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}int openstage ({\bf stagecontrolp\_\-t} {\em stage}, const char $\ast$ {\em path}, const int {\em flags})}\label{ppdev__motion_8c_a47}


Connect to the physical port controlling the stage. 

We need a stage data structure previously allocated by {\em {\bf newstage()}{\rm (p.\,\pageref{ppdev__motion_8c_a44})}\/} and a path that defines the physical port controlling the stage hardware (something like {\tt /dev/parport\-N}). 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. \begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em stage}]the previously allocated stage control structure. \item[{\em path}]the device port path. \item[{\em flags}]additional flags specifying attributes for the stage. \end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]an error code on failure, zero on success. \end{Desc}
\begin{Desc}
\item[See also:]{\bf newstage()}{\rm (p.\,\pageref{ppdev__motion_8c_a44})} 

{\bf closestage()}{\rm (p.\,\pageref{ppdev__motion_8c_a48})} \end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!setaxismapping@{setaxismapping}}
\index{setaxismapping@{setaxismapping}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}void setaxismapping ({\bf axismappingp\_\-t} {\em themap}, const unsigned int {\em logical}, const axismapentry\_\-t {\em physical})}\label{ppdev__motion_8c_a39}


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

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em themap}]the map to modify. \item[{\em logical}]the logical axis number. \item[{\em physical}]the new corresponding physical number. \end{description}
\end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!setstagelocation@{setstagelocation}}
\index{setstagelocation@{setstagelocation}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}void setstagelocation ({\bf stagelocationp\_\-t} {\em theloc}, const unsigned int {\em axisn}, const coord\_\-t {\em newval})}\label{ppdev__motion_8c_a42}


Change one coordinate in a generalized stage coordinate vector. 

\begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em theloc}]the coordinate vector to modify. \item[{\em axisn}]selects the logical axis number. \item[{\em newval}]the new position ascribed to this axis. \end{description}
\end{Desc}
\begin{Desc}
\item[See also:]{\bf getstagelocation()}{\rm (p.\,\pageref{ppdev__motion_8c_a43})} \end{Desc}
\index{ppdev_motion.c@{ppdev\_\-motion.c}!stageactive@{stageactive}}
\index{stageactive@{stageactive}!ppdev_motion.c@{ppdev\_\-motion.c}}
\subsubsection{\setlength{\rightskip}{0pt plus 5cm}int stageactive ({\bf stagecontrolp\_\-t} {\em stage})}\label{ppdev__motion_8c_a51}


Examine the stage to find if it is active. 

We try to acquire the lock on the stage structure, and immediately determine that the stage is busy if we can't acquire it, without examining anything else. As soon as we find an axis that's not in its resting state we also determine the stage must be busy, but test it again after waiting one polling interval (currently a hard-wired constant). However we release the lock before returning, so it's quite possible that the stage is busy again by the time this returns, if no other conditions are imposed. \begin{Desc}
\item[Parameters:]
\begin{description}
\item[{\em stage}]the stage to examine. \end{description}
\end{Desc}
\begin{Desc}
\item[Returns:]a non-zero code if the stage is active, zero if it is not. \end{Desc}
