anticol1.c -- Program Sequencer aborts axes prior to a collision
(anti-collision protection)
/* anticol1.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.
*/
/*
:Program Sequencer aborts axes prior to a collision (anti-collision protection)
This sample program provides anti-collision protection for two axes that move
along the same physical space. The program creates a program sequencer that
will continually monitor the relative actual positions of two axes. When the
relative positions get closer than a defined tolerance (defined at the top of
the program as DIFFERENCE_TOLEARNCE) the axes will be aborted by the program
sequencer.
The XMP program sequencer controls the execution of a single command or a
series of commands on the XMP controller. The program sequencer provides the
ability to execute programs directly on the XMP controller without host
intervention. Examples of individual commands that can be executed by the
program sequencer are motion, looping, conditional branching, computation,
reading and writing of memory, time delays, waiting for conditions, setting
inputs/outputs, and generation of events. This rich command set provides
capability similar to, and beyond, that provided by Programmable Logic
Controller (PLC) programs.
From anticol1c.c (8/1/1999)
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 "apputil.h"
#if defined(ARG_MAIN_RENAME)
#define main anticol1Main
argMainRENAME(main, anticol1)
#endif
#define AXIS_COUNT (2)
#define DIFFERENCE_TOLERANCE (7000)
/* Command line arguments and defaults */
long axisNumber[AXIS_COUNT] = { 0, 1, };
long motionNumber = 0;
long sequenceNumber = 0;
long differenceTolerance = DIFFERENCE_TOLERANCE;
Arg argList[] = {
{ "-axis", ArgTypeLONG, &axisNumber[0], },
{ "-motion", ArgTypeLONG, &motionNumber, },
{ "-sequence", ArgTypeLONG, &sequenceNumber, },
{ "-tolerance", ArgTypeLONG, &differenceTolerance, },
{ NULL, ArgTypeINVALID, NULL, }
};
/* COMPUTE + BRANCH + BRANCH + ABORT = 4 */
MPICommand CommandTable[4];
#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 */
MPISequence sequence; /* sequence handle */
MPICommandParams commandParams; /* command parameters */
long returnValue; /* return value from library */
long commandIndex; /* CommandTable[] index */
long index;
MPIControlType controlType;
MPIControlAddress controlAddress;
MEIXmpData *firmware;
MEIPlatform platform; /* platform handle */
MEIXmpBufferData *xmpBufferData;
long *addressActPos1;
long *addressActPos2;
long address;
long *allocPointer;
long difference;
long *addressDifferenceStored;
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) ||
(sequenceNumber >= MEIXmpMAX_PSs) ||
(differenceTolerance < 0)){
meiPlatformConsole("usage: %s %s\n"
"\t\t[-axis # (0 .. %d)]\n"
"\t\t[-motion # (0 .. %d)]\n"
"\t\t[-sequence # (0 .. %d)]\n"
"\t\t[-tolerance # ( larger than 0)]\n",
argv[0],
ArgUSAGE,
MEIXmpMAX_Axes - AXIS_COUNT,
MEIXmpMAX_MSs - 1,
MEIXmpMAX_PSs - 1);
exit(MPIMessageARG_INVALID);
}
axisNumber[1] = axisNumber[0] + 1;
/* Create motion controller object */
control =
mpiControlCreate(controlType,
&controlAddress);
msgCHECK(mpiControlValidate(control));
/* Initialize motion controller */
returnValue = mpiControlInit(control);
if (returnValue != MPIMessageOK) {
fprintf(stderr, "%s: mpiControlInit() returns 0x%x: %s\n",
argv[0],
returnValue,
mpiMessage(returnValue, NULL));
exit(1);
}
/* Get pointer to XMP firmware */
returnValue =
mpiControlMemory(control,
&firmware,
&xmpBufferData);
msgCHECK(returnValue);
platform =
meiControlPlatform(control);
msgCHECK(meiPlatformValidate(platform));
/*Pointer into xmp memory space. Pointer to the user buffer */
returnValue =
mpiControlMemoryAlloc(control,
MPIControlMemoryTypeUSER,
sizeof(long),
&allocPointer);
msgCHECK(returnValue);
returnValue =
meiPlatformMemoryToFirmware(platform,
allocPointer,
(void **)&address);
msgCHECK(returnValue);
meiPlatformConsole("address of allocPointer (user buffer) is 0x%x\n",address);
/* Create motion object */
motion =
mpiMotionCreate(control,
motionNumber,
MPIHandleVOID);
msgCHECK(mpiMotionValidate(motion));
/* Create axis object for axis #0 */
axis[0] =
mpiAxisCreate(control,
axisNumber[0]); /* axis #0 */
msgCHECK(mpiAxisValidate(axis[0]));
/* Create axis object for axis #1 */
axis[1] =
mpiAxisCreate(control,
axisNumber[1]); /* axis #1 */
msgCHECK(mpiAxisValidate(axis[1]));
/* Create motion axis list */
returnValue =
mpiMotionAxisListSet(motion,
AXIS_COUNT,
axis);
msgCHECK(returnValue);
/* Write the axis list to the motion supervisor on the board */
returnValue =
mpiMotionAction(motion,
MEIActionMAP);
msgCHECK(returnValue);
/* Create Sequence */
sequence =
mpiSequenceCreate(control,
sequenceNumber,
-1);
msgCHECK(mpiSequenceValidate(sequence));
/* CommandTable[commandIndex] */
commandIndex = 0;
/* Get the address for the first axis's actual position register */
addressActPos1 = &firmware->Axis[axisNumber[0]].ActPosition.l[1];
/* Get the address for the second axis's actual position register */
addressActPos2 = &firmware->Axis[axisNumber[1]].ActPosition.l[1];
returnValue =
meiPlatformMemoryToFirmware(platform,
addressActPos1,
(void **)&address);
msgCHECK(returnValue);
meiPlatformConsole("addressActPos1 is 0x%x\n",address);
returnValue =
meiPlatformMemoryToFirmware(platform,
addressActPos2,
(void **)&address);
msgCHECK(returnValue);
meiPlatformConsole("addressActPos2 is 0x%x\n",address);
/* 1st. Command */
/* Take the difference of the two actual positions and store them in the user buffer */
addressDifferenceStored = allocPointer;
commandParams.compute.dst.l = addressDifferenceStored;
commandParams.compute.expr.address.l = addressActPos1;
commandParams.compute.expr.oper = MPICommandOperatorSUBTRACT;
commandParams.compute.expr.by.ref.l = addressActPos2;
CommandTable[commandIndex] =
mpiCommandCreate(MPICommandTypeCOMPUTE_REF,
&commandParams,
"First");
msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));
commandIndex++;
/* 2nd Command */
/* Compare the position differences to the position diference tolerance */
/* Perform abort if test is true */
commandParams.branch.label = "ABORT";
commandParams.branch.expr.address.l = addressDifferenceStored;
commandParams.branch.expr.oper = MPICommandOperatorLESS;
commandParams.branch.expr.by.value.l = differenceTolerance;
CommandTable[commandIndex] =
mpiCommandCreate(MPICommandTypeBRANCH,
&commandParams,
NULL);
msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));
commandIndex++;
/* 3rd. Command */
/* 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++;
/* 4th. command */
/* Abort the axes that are part of motion supervisor motion */
commandParams.motion.motionCommand = MPICommandMotionABORT;
commandParams.motion.motion = motion;
CommandTable[commandIndex] =
mpiCommandCreate(MPICommandTypeMOTION,
&commandParams,
"ABORT");
msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));
commandIndex++;
/* Create sequence command list */
returnValue =
mpiSequenceCommandListSet(sequence,
commandIndex,
CommandTable);
msgCHECK(returnValue);
/* 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);
returnValue =
mpiControlMemoryGet(control,
&difference,
allocPointer,
sizeof(long));
msgCHECK(returnValue);
meiPlatformConsole("Axis Position difference is %ld\n",difference);
/* 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 =
mpiControlMemoryFree(control,
MPIControlMemoryTypeUSER,
sizeof(long),
allocPointer);
msgCHECK(returnValue);
returnValue = mpiControlDelete(control);
msgCHECK(returnValue);
return ((int)returnValue);
}
|