capture1.c -- Perform a velocity move and capture position based
on Home or Index pulse.
/* capture1.c */
/* Copyright(c) 1991-2006 by Motion Engineering, Inc. All rights reserved.
*
* This software contains proprietary and confidential information of
* Motion Engineering Inc., and its suppliers. Except as may be set forth
* in the license agreement under which this software is supplied, use,
* disclosure, or reproduction is prohibited without the prior express
* written consent of Motion Engineering, Inc.
*/
/*
:Perform a velocity move and capture position based on Home or Index pulse.
This sample application demonstrates use of the Capture feature.
First, a velocity move is commanded on an Axis. A capture is then configured
to trigger on either a Home sensor or index pulse.
This program presumes the tuning parameters(PID, PIV, etc.) for your
stage(or tool, or machine) have already been set. That is, the tuning
parameters need to be established prior to running this program so the
stage can move in a stable manner. Please use the Tuning Guidelines if
these values haven't been determined.
Warning! This is a sample program to assist in the integration of an
MEI motion controller with your application. It may not contain all
of the logic and safety features that your application requires.
The msgCHECK(...) macros used in the following sample code are intended
to convey our strong belief that ALL error return codes should be checked.
Actual application code should use specific error handling techniques (other
than msgCHECKs) best suited to your internal error recovery methods.
*/
#include <stdlib.h>
#include <stdio.h>
#include "stdmpi.h"
#include "stdmei.h"
#include "apputil.h"
/* Capture Parameters */
#define CAPTURE_COUNT (1) /* Enabled Capture count */
#define CAPTURE_NUMBER (0) /* Capture object number */
#define CAPTURE_MOTOR (0) /* Motor number */
#define CAPTURE_INDEX (0) /* Index to capture engine */
#define CAPTURE_FEEDBACK (0) /* same as CAPTURE_MOTOR for CaptureTypePOSITION */
#define CAPTURE_TYPE (MPICaptureTypePOSITION) /* Capture type */
/* Position (MPICaptureTypePOSITION) or */
/* Time (MPICaptureTypeTIME) */
#define CAPTURE_ENCODER (MPIMotorEncoderPRIMARY) /* Encoder primary or secondary */
/* primary (MPIMotorEncoderPRIMARY) or */
/* secondary (MPIMotorEncoderSECONDARY) */
/* Capture Parameters */
#define CAPTURE_GLOBAL_TRIGGER (FALSE) /* signal all captures to latch */
#define CAPTURE_TRIGGER_EDGE (MPICaptureEdgeRISING)
/* IO */
#define TRIGGER_SOURCE_HOME (FALSE)
#define TRIGGER_HOME_INVERT (FALSE)
#define TRIGGER_SOURCE_IO (MPICaptureSourceHOME) /* choice of IO */
/* MPICaptureSourceHOME
MPICaptureSourceLIMIT_HW_NEG
MPICaptureSourceLIMIT_HW_POS
MPICaptureSourceGLOBAL
MPICaptureSourceMOTOR_IO_0
MPICaptureSourceMOTOR_IO_1
MPICaptureSourceMOTOR_IO_2
MPICaptureSourceMOTOR_IO_3
MPICaptureSourceMOTOR_IO_4
MPICaptureSourceMOTOR_IO_5
MPICaptureSourceMOTOR_IO_6
MPICaptureSourceMOTOR_IO_7
*/
/* INDEX */
#define TRIGGER_SOURCE_INDEX (TRUE)
#define TRIGGER_INDEX_INVERT (FALSE)
/* Motion Parameters */
#define VELOCITY (30000.0) /* Move velocity */
#define ACCEL (100000.0) /* Move acceleration*/
/* Perform basic command line parsing. (-control -server -port -trace) */
void basicParsing(int argc,
char *argv[],
MPIControlType *controlType,
MPIControlAddress *controlAddress)
{
long argIndex;
/* Parse command line for Control type and address */
argIndex = argControl(argc, argv, controlType, controlAddress);
/* Check for unknown/invalid command line arguments */
if (argIndex < argc) {
meiPlatformConsole("usage: %s %s\n", argv[0], ArgUSAGE);
exit(MPIMessageARG_INVALID);
}
}
/* Create and initialize MPI objects */
void programInit(MPIControl *control,
MPIControlType controlType,
MPIControlAddress *controlAddress,
MPIMotion *motion,
long motionNumber,
MPIAxis *axis,
long axisNumber,
MPIMotor *motor,
long motorNumber,
MPICapture *capture,
long captureNumber,
long captureCount)
{
MPIControlConfig controlConfig;
long returnValue;
/* Create motion controller object */
*control =
mpiControlCreate(controlType,
controlAddress);
msgCHECK(mpiControlValidate(*control));
/* Initialize motion controller */
returnValue =
mpiControlInit(*control);
msgCHECK(returnValue);
/* Create axis object */
*axis =
mpiAxisCreate(*control,
axisNumber);
msgCHECK(mpiAxisValidate(*axis));
/* Create motion supervisor object with axis */
*motion =
mpiMotionCreate(*control,
motionNumber,
*axis);
msgCHECK(mpiMotionValidate(*motion));
/* Create motor object */
*motor =
mpiMotorCreate(*control,
motorNumber);
msgCHECK(mpiMotorValidate(*motor));
/* Enable capture objects */
returnValue =
mpiControlConfigGet(*control,
&controlConfig,
NULL);
msgCHECK(returnValue);
controlConfig.captureCount = captureCount;
returnValue =
mpiControlConfigSet(*control,
&controlConfig,
NULL);
msgCHECK(returnValue);
/* Create capture object */
*capture =
mpiCaptureCreate(*control,
captureNumber);
msgCHECK(mpiCaptureValidate(*capture));
}
/* Perform certain cleanup actions and delete MPI objects */
void programCleanup(MPIControl *control,
MPIMotion *motion,
MPIAxis *axis,
MPIMotor *motor,
MPICapture *capture)
{
long returnValue;
/* Delete capture object */
returnValue =
mpiCaptureDelete(*capture);
msgCHECK(returnValue);
*capture = MPIHandleVOID;
/* Delete motor object */
returnValue =
mpiMotorDelete(*motor);
msgCHECK(returnValue);
*motor = MPIHandleVOID;
/* Delete motion supervisor object */
returnValue =
mpiMotionDelete(*motion);
msgCHECK(returnValue);
*motion = MPIHandleVOID;
/* Delete axis object */
returnValue =
mpiAxisDelete(*axis);
msgCHECK(returnValue);
*axis = MPIHandleVOID;
/* Delete motion controller object */
returnValue =
mpiControlDelete(*control);
msgCHECK(returnValue);
*control = MPIHandleVOID;
}
/* Configure capture object. */
void configureCapture(MPICapture capture)
{
MPICaptureConfig captureConfig;
long index;
long returnValue;
/* Disable capture */
returnValue =
mpiCaptureArm(capture,
FALSE);
msgCHECK(returnValue);
/*
Clear out capture registers before modifiying them.
This keeps from unintentionally combining capture triggers.
*/
returnValue = mpiCaptureConfigReset(capture);
msgCHECK(returnValue);
/* Read caputre configuration */
returnValue =
mpiCaptureConfigGet(capture,
&captureConfig,
NULL);
msgCHECK(returnValue);
/* Set capture parameters */
captureConfig.captureMotorNumber = CAPTURE_MOTOR;
captureConfig.feedbackMotorNumber = CAPTURE_FEEDBACK;
captureConfig.encoder = CAPTURE_ENCODER;
captureConfig.global.enabled = CAPTURE_GLOBAL_TRIGGER;
captureConfig.edge = CAPTURE_TRIGGER_EDGE;
captureConfig.type = CAPTURE_TYPE;
captureConfig.captureIndex = CAPTURE_INDEX;
/* disable capture source */
for(index=0; index < MPICaptureSourceLAST; index++) {
captureConfig.source[index].enabled = FALSE;
}
/* Enable capture source */
/* IO */
if (TRIGGER_SOURCE_HOME) {
captureConfig.source[TRIGGER_SOURCE_IO].enabled = TRUE;
captureConfig.source[TRIGGER_SOURCE_IO].invert = TRIGGER_HOME_INVERT;
}
/* Index */
if (TRIGGER_SOURCE_INDEX) {
captureConfig.source[MPICaptureSourceINDEX].enabled = TRUE;
captureConfig.source[MPICaptureSourceINDEX].invert = TRIGGER_INDEX_INVERT;
}
/* Write capture configuration */
returnValue =
mpiCaptureConfigSet(capture,
&captureConfig,
NULL);
msgCHECK(returnValue);
}
/* Disable Home Event action */
void disableHomeEvent(MPIMotor motor,
MPICapture capture)
{
MPIMotorEventConfig eventConfig;
long returnValue;
returnValue =
mpiMotorEventConfigGet(motor,
MPIEventTypeHOME,
&eventConfig,
NULL);
msgCHECK(returnValue);
eventConfig.action = MPIActionNONE; /* No action */
eventConfig.trigger.polarity = TRUE; /* Active high */
returnValue =
mpiMotorEventConfigSet(motor,
MPIEventTypeHOME,
&eventConfig,
NULL);
msgCHECK(returnValue);
/* Arm the capture */
returnValue =
mpiCaptureArm(capture,
TRUE);
msgCHECK(returnValue);
}
/* Perform a Velocity move */
void velocityMove(MPITrajectory *trajectory,
MPIMotionParams *params,
MPIMotion *motion)
{
long returnValue;
/* Setup motion parameters */
trajectory->velocity = VELOCITY;
trajectory->acceleration = ACCEL;
trajectory->deceleration = ACCEL; /* Not used for velocity move */
trajectory->jerkPercent = 0.0; /* Not used for velocity move */
params->velocity.trajectory = trajectory;
/* Start a velocity move */
returnValue =
mpiMotionStart(*motion,
MPIMotionTypeVELOCITY,
params);
msgCHECK(returnValue);
}
/* Poll capture status and update display */
void pollForCaptureAndUpdateDisplay(MPICapture *capture,
MPIMotor *motor)
{
MPICaptureStatus captureStatus;
unsigned long dedicatedIn;
long caputuresCounted = 0;
long returnValue;
/* State Machine - Poll capture status, update display, etc. */
while (meiPlatformKey(MPIWaitPOLL) <= 0) {
long position[2] = {0, 0};
returnValue =
mpiCaptureStatus(*capture,
&captureStatus,
NULL);
msgCHECK(returnValue);
/* Display Home and Capture state */
returnValue =
mpiMotorDedicatedIn(*motor,
0,
MPIMotorDedicatedInLAST,
&dedicatedIn );
msgCHECK(returnValue);
meiPlatformConsole("\rCaptureState:%d ", captureStatus.state); /* (1=ARMED, 2=CAPTURED) */
if (captureStatus.state == MPICaptureStateCAPTURED) {
caputuresCounted++;
position[1] = position[0];
position[0] = (long)captureStatus.latchedValue;
meiPlatformConsole("IO = 0x%08X\tLatched Position = %d (%d)\n\n",
dedicatedIn,
(long)captureStatus.latchedValue,
position[0] - position[1]);
/* Re-arm position capture */
returnValue =
mpiCaptureArm(*capture,
TRUE);
msgCHECK(returnValue);
}
meiPlatformSleep(1);
}
}
int main(int argc,
char *argv[])
{
MPIControl control;
MPIControlType controlType;
MPIControlAddress controlAddress;
MPIMotion motion;
MPIAxis axis;
MPIMotor motor;
MPICapture capture;
MPITrajectory trajectory;
MPIMotionParams params;
long returnValue; /* Return value from library */
long motorNumber = CAPTURE_MOTOR;
long motionNumber = motorNumber;
long axisNumber = motorNumber;
long captureNumber = CAPTURE_NUMBER;
long captureCount = CAPTURE_COUNT;
/* The number of enabled captures must be greater than the id number of the capture used */
meiAssert(captureCount>captureNumber);
/* Perform basic command line parsing. (-control -server -port -trace) */
basicParsing(argc,
argv,
&controlType,
&controlAddress);
/* Create and initialize MPI objects */
programInit(&control,
controlType,
&controlAddress,
&motion,
motionNumber,
&axis,
axisNumber,
&motor,
motorNumber,
&capture,
captureNumber,
captureCount);
/* Configure capture */
configureCapture(capture);
/* Disable Home Event action */
disableHomeEvent(motor,
capture);
/* Perform a Velocity move */
velocityMove(&trajectory,
¶ms,
&motion);
meiPlatformConsole("\n Moving.... Press any key to quit.\n\n");
/* Poll capture status and update display */
pollForCaptureAndUpdateDisplay(&capture,
&motor);
meiPlatformConsole("\nStopping.\n");
/* Stop motion on axis */
returnValue =
mpiMotionAction(motion,
MPIActionSTOP);
msgCHECK(returnValue);
/* Perform certain cleanup actions and delete MPI objects */
programCleanup(&control,
&motion,
&axis,
&motor,
&capture);
return ((int)returnValue);
}
|