seq3.c -- Wait for an I/O bit to Toggle Before Commanding Motion
with a Sequencer
/* seq3.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.
*/
/*
:Wait for an I/O bit to Toggle Before Commanding Motion with a Sequencer
Wait for an I/O bit between moves.
This program will wait for motor 0's Transceiver A to go high.
Use an event manager to handle flow control.
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.
*/
#include <stdlib.h>
#include <stdio.h>
#include "stdmpi.h"
#include "stdmei.h"
#include "mei_rmb.h"
#include "apputil.h"
#if defined(ARG_MAIN_RENAME)
#define main seq3Main
argMainRENAME(main, seq3)
#endif
#define MOTION_COUNT (2)
#define AXIS_COUNT (2)
/* Command line arguments and defaults */
long axisNumber[AXIS_COUNT] = { 0, 1, };
long motionNumber = 0;
long motorNumber = 0;
long sequenceNumber = 0;
long sequenceSize = -1;
MPIMotionType motionType = MPIMotionTypeTRAPEZOIDAL;
Arg argList[] = {
{ "-axis", ArgTypeLONG, &axisNumber[0], },
{ "-motion", ArgTypeLONG, &motionNumber, },
{ "-motor", ArgTypeLONG, &motorNumber, },
{ "-sequence", ArgTypeLONG, &sequenceNumber, },
{ "-size", ArgTypeLONG, &sequenceSize, },
{ "-type", ArgTypeLONG, &motionType, },
{ NULL, ArgTypeINVALID, NULL, }
};
double position[MOTION_COUNT][AXIS_COUNT] = {
{ 20000.0, 0.0, },
{ 0.0, 20000.0, },
};
MPITrajectory trajectory[MOTION_COUNT][AXIS_COUNT] = {
{ /* velocity accel decel jerkPercent */
{ 10000.0, 100000.0, 100000.0, 50.0, },
{ 10000.0, 100000.0, 100000.0, 50.0, },
},
{ /* velocity accel decel jerkPercent */
{ 10000.0, 100000.0, 100000.0, 50.0, },
{ 10000.0, 100000.0, 100000.0, 50.0, },
},
};
/* motion parameters */
MPIMotionSCurve sCurve[MOTION_COUNT] = {
{ &trajectory[0][0], &position[0][0], },
{ &trajectory[1][0], &position[1][0], },
};
MPIMotionTrapezoidal trapezoidal[MOTION_COUNT] = {
{ &trajectory[0][0], &position[0][0], },
{ &trajectory[1][0], &position[1][0], },
};
MPIMotionVelocity velocity[MOTION_COUNT] = {
{ &trajectory[0][0], },
{ &trajectory[1][0], },
};
/* 4 => START + MOTION_DONE + I/O + EVENT 1 => BRANCH */
MPICommand CommandTable[(MOTION_COUNT * 4) + 1];
#define COMMAND_COUNT (sizeof(CommandTable) / sizeof(MPICommand))
int
main(int argc,
char *argv[])
{
MPIControl control; /* motion controller handle */
MPIMotion motion; /* motion handle */
MPIAxis axis[AXIS_COUNT]; /* axis handles */
MPIMotor motor; /* motor handle */
MPISequence sequence; /* sequence handle */
MPIEventMgr eventMgr; /* event manager handle */
Service service;
MPICommandParams commandParams; /* command parameters */
MPIControlConfig controlConfig;
long returnValue; /* return value from library */
long commandIndex; /* CommandTable[] index */
long index;
MPIControlType controlType;
MPIControlAddress controlAddress;
long argIndex;
argIndex =
argControl(argc,
argv,
&controlType,
&controlAddress);
/* Parse command line for application-specific arguments */
while (argIndex < argc) {
long argIndexNew;
argIndexNew = argSet(argList, argIndex, argc, argv);
if (argIndexNew <= argIndex) {
argIndex = argIndexNew;
break;
}
else {
argIndex = argIndexNew;
}
}
/* Check for unknown/invalid command line arguments */
if ((argIndex < argc) ||
(axisNumber[0] > (MEIXmpMAX_Axes - AXIS_COUNT)) ||
(motionNumber >= MEIXmpMAX_MSs) ||
(motorNumber >= MEIXmpMAX_Motors) ||
(sequenceNumber >= MEIXmpMAX_PSs) ||
(motionType < MPIMotionTypeFIRST) ||
(motionType >= MEIMotionTypeLAST)) {
meiPlatformConsole("usage: %s %s\n"
"\t\t[-axis # (0 .. %d)]\n"
"\t\t[-motion # (0 .. %d)]\n"
"\t\t[-motor # (0 .. %d)]\n"
"\t\t[-sequence # (0 .. %d)]\n"
"\t\t[-size # (%d)]\n"
"\t\t[-type # (0 .. %d)]\n",
argv[0],
ArgUSAGE,
MEIXmpMAX_Axes - AXIS_COUNT,
MEIXmpMAX_MSs - 1,
MEIXmpMAX_Motors - 1,
MEIXmpMAX_PSs - 1,
sequenceSize,
MEIMotionTypeLAST - 1);
exit(MPIMessageARG_INVALID);
}
switch (motionType) {
case MPIMotionTypeS_CURVE:
case MPIMotionTypeTRAPEZOIDAL:
case MPIMotionTypeVELOCITY: {
break;
}
default: {
meiPlatformConsole("%s: %d: motion type not available\n",
argv[0],
motionType);
exit(MPIMessageUNSUPPORTED);
break;
}
}
axisNumber[1] = axisNumber[0] + 1;
/* Create motion controller object */
control =
mpiControlCreate(controlType,
&controlAddress);
msgCHECK(mpiControlValidate(control));
/* Initialize motion controller */
returnValue = mpiControlInit(control);
msgCHECK(returnValue);
/* Enable a sequence engine on the controller */
returnValue =
mpiControlConfigGet(control,
&controlConfig,
NULL);
msgCHECK(returnValue);
if (controlConfig.sequenceCount <= sequenceNumber) {
controlConfig.sequenceCount = (sequenceNumber + 1);
}
returnValue =
mpiControlConfigSet(control,
&controlConfig,
NULL);
msgCHECK(returnValue);
/* Create motion object for MS number */
motion =
mpiMotionCreate(control,
motionNumber,
MPIHandleVOID);
msgCHECK(mpiMotionValidate(motion));
/* Create axis object for X_AXIS number */
axis[0] =
mpiAxisCreate(control,
axisNumber[0]);
msgCHECK(mpiAxisValidate(axis[0]));
/* Create axis object for Y_AXIS number */
axis[1] =
mpiAxisCreate(control,
axisNumber[1]);
msgCHECK(mpiAxisValidate(axis[1]));
/* Create motion axis list */
returnValue =
mpiMotionAxisListSet(motion,
AXIS_COUNT,
axis);
msgCHECK(returnValue);
/* Create motor objects */
motor =
mpiMotorCreate(control,
motorNumber);
msgCHECK(mpiMotorValidate(motor));
/* Create Sequence */
sequence =
mpiSequenceCreate(control,
sequenceNumber,
sequenceSize);
msgCHECK(mpiSequenceValidate(sequence));
#if defined(_DEBUG)
returnValue =
meiObjectTraceSet(sequence,
MEISequenceTraceLOAD);
msgCHECK(returnValue);
#endif
/* CommandTable[commandIndex] */
commandIndex = 0;
/* Create motion Commands */
for (index = 0; index < MOTION_COUNT; index++) {
MPIMotionParams *motionParams;
/* mpiMotionStart(motion, type, params); */
commandParams.motion.motionCommand = MPICommandMotionSTART;
commandParams.motion.motion = motion;
commandParams.motion.type = motionType;
motionParams = &commandParams.motion.params;
switch (motionType) {
case MPIMotionTypeS_CURVE: {
motionParams->sCurve = sCurve[index];
break;
}
case MPIMotionTypeTRAPEZOIDAL: {
motionParams->trapezoidal = trapezoidal[index];
break;
}
case MPIMotionTypeVELOCITY: {
motionParams->velocity = velocity[index];
break;
}
default: {
meiAssert(FALSE);
break;
}
}
/* Create Command */
CommandTable[commandIndex] =
mpiCommandCreate(MPICommandTypeMOTION,
&commandParams,
(commandIndex == 0) ? "First" : NULL);
msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));
commandIndex++;
commandParams.waitEvent.handle = motion;
commandParams.waitEvent.oper = MPICommandOperatorBIT_SET;
mpiEventMaskCLEAR(commandParams.waitEvent.mask);
mpiEventMaskSET(commandParams.waitEvent.mask, MPIEventTypeMOTION_DONE);
/* Create Command */
CommandTable[commandIndex] =
mpiCommandCreate(MPICommandTypeWAIT_EVENT,
&commandParams,
NULL);
msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));
commandIndex++;
commandParams.branchEvent.label = NULL;
commandParams.branchEvent.handle = motion;
commandParams.branchEvent.oper = MPICommandOperatorBIT_SET;
mpiEventMaskCLEAR(commandParams.branchEvent.mask);
mpiEventMaskMOTOR(commandParams.branchEvent.mask);
/* Create Command */
CommandTable[commandIndex] =
mpiCommandCreate(MPICommandTypeBRANCH_EVENT,
&commandParams,
NULL);
msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));
commandIndex++;
/* while (mpiControlUserIoGet(control, &io), (io.input[0] & mask) == 0); */
commandParams.waitIO.type = MPIIoTypeMOTOR_GENERAL;
commandParams.waitIO.source.motor = motor;
commandParams.waitIO.oper = MPICommandOperatorBIT_SET;
commandParams.waitIO.mask = RMBGeneralIoXCVR_A;
/* Create Command */
CommandTable[commandIndex] =
mpiCommandCreate(MPICommandTypeWAIT_IO,
&commandParams,
NULL);
msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));
commandIndex++;
}
/* Branch to the first command of the sequence */
commandParams.branch.label = "First"; /* First command */
commandParams.branch.expr.oper = MPICommandOperatorALWAYS;
/* Create Command */
CommandTable[commandIndex] =
mpiCommandCreate(MPICommandTypeBRANCH,
&commandParams,
NULL);
msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));
commandIndex++;
/* Create sequence command list */
returnValue =
mpiSequenceCommandListSet(sequence,
commandIndex,
CommandTable);
msgCHECK(returnValue);
/* Create event manager object */
eventMgr = mpiEventMgrCreate(control);
msgCHECK(mpiEventMgrValidate(eventMgr));
/* Create service thread */
service =
serviceCreate(eventMgr,
-1, /* default (max) priority */
-1); /* -1 => enable interrupts */
meiAssert(service != NULL);
/* Start sequence */
returnValue =
mpiSequenceStart(sequence,
MPIHandleVOID);
if (returnValue != MPIMessageOK) {
fprintf(stderr, "%s: mpiSequenceStart() returns 0x%x: %s\n",
argv[0],
returnValue,
mpiMessage(returnValue, NULL));
exit(2);
}
meiPlatformConsole("Press any key to stop sequence\n");
meiPlatformKey(MPIWaitFOREVER);
/* Stop sequence */
returnValue = mpiSequenceStop(sequence);
msgCHECK(returnValue);
returnValue = mpiSequenceDelete(sequence);
msgCHECK(returnValue);
returnValue = mpiMotionDelete(motion);
msgCHECK(returnValue);
for (index = 0; index < AXIS_COUNT; index++) {
returnValue = mpiAxisDelete(axis[index]);
msgCHECK(returnValue);
}
returnValue = mpiMotorDelete(motor);
msgCHECK(returnValue);
returnValue = serviceDelete(service);
msgCHECK(returnValue);
returnValue = mpiEventMgrDelete(eventMgr);
msgCHECK(returnValue);
returnValue = mpiControlDelete(control);
msgCHECK(returnValue);
return ((int)returnValue);
}
|