/* usrlim2.c */
/* Copyright(c) 1991-2009 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.
*/
/*
:Position comparison using User Limits to generate events.
This sample code shows how to configure the controller's User Limits
to compare an axis' actual position to a specific position value. If the
actual position is greater than or equal to the value specified, then
the controller will generate a User Event to the Host.
这个代码示例展示到大一个轴的指定位置,做一个比较,生成事件到主机。
The function compareUserLimitSet(...) demonstrates how to configure a
User Limit for position compare.
compareUserLimitSet(...)函数展示了怎么配置 user limit,来做位置比较。
Warning! This is a sample program to assist in the integration of a
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 "apputil.h"
#if defined(ARG_MAIN_RENAME)
#define main usrlim2Main
argMainRENAME(main, usrlim2)
#endif
#define USER_LIMIT_NUMBER (0)
#define MOTION_NUMBER (0)
#define AXIS_NUMBER (0)
#define END_POSITION (20000.0)
#define SPEED (10000.0)
#define ACCELERATION (50000.0)
#define DECELERATION (50000.0)
#define COMPARE_POSITION (10000) /* Actual Position */
#define COMPARISON_TYPE (MPIUserLimitLogicGE) /* Greater than or equal to */
/* Parse command line */
int32_t parseCommandLine(int argc,
char *argv[],
MPIControlType *controlType,
MPIControlAddress *controlAddress,
int32_t *userlimitNumber,
int32_t *motionNumber,
int32_t *axisNumber)
{
int32_t argIndex;
/* Application-specific command line arguments */
Arg argList[] =
{
{ "-userlimit", ArgTypeLONG, NULL, },
{ "-motion", ArgTypeLONG, NULL, },
{ "-axis", ArgTypeLONG, NULL, },
{ NULL, ArgTypeINVALID, NULL, }
};
argList[0].value = userlimitNumber;
argList[1].value = motionNumber;
argList[2].value = axisNumber;
/* Parse command line for Control type and address */
argIndex =
argControl(argc,
argv,
controlType,
controlAddress);
/* Parse command line for application-specific arguments */
while (argIndex < argc)
{
int32_t 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) ||
(*userlimitNumber >= MPIUserLimitCOUNT_MAX) ||
(*axisNumber >= MPIControlMAX_OBJECTS) ||
(*motionNumber >= MPIControlMAX_OBJECTS))
{
mpiPlatformConsole("usage: %s %s\n"
"\t\t[-userlimit # (0 .. %d)]\n"
"\t\t[-axis # (0 .. %d)]\n"
"\t\t[-motion # (0 .. %d)]\n",
argv[0],
ArgUSAGE,
MPIUserLimitCOUNT_MAX - 1,
MPIControlMAX_OBJECTS - 1,
MPIControlMAX_OBJECTS - 1);
exit(MPIMessageARG_INVALID);
}
return 0;
}
/* Create and initialize MPI objects */
void programInit(MPIControl *control,
MPIControlType controlType,
MPIControlAddress *controlAddress,
MPIUserLimit *userLimit,
int32_t userLimitNumber,
MPIMotion *motion,
int32_t motionNumber,
MPIAxis *axis,
int32_t axisNumber,
MPINotify *notify)
{
MPIEventMask eventMask;
MPIMotionAxisMap motionAxisMap;
MPI_RESULT returnValue;
/* Create motion controller object */
returnValue =
mpiControlCreate(control,
controlType,
controlAddress);
msgCHECK(returnValue);
/* Create user limit object */
returnValue =
mpiUserLimitCreate(userLimit,
*control,
userLimitNumber);
msgCHECK(returnValue);
/* Create axis object */
returnValue =
mpiAxisCreate(axis, *control, axisNumber);
msgCHECK(returnValue);
/* Create motion supervisor object */
returnValue =
mpiMotionCreate(motion, *control, motionNumber);
msgCHECK(returnValue);
/* map axis to motionSupervisor */
returnValue =
mpiMotionAxisMapGet(*motion, &motionAxisMap);
msgCHECK(returnValue);
motionAxisMap.count = 1;
motionAxisMap.number[0] = axisNumber;
returnValue =
mpiMotionAxisMapSet(*motion, &motionAxisMap);
msgCHECK(returnValue);
/* Obtain a notify handle */
mpiEventMaskCLEAR(eventMask);
mpiEventMaskALL(eventMask);
returnValue =
mpiControlNotifyCreate(*control, notify, eventMask, NULL);
msgCHECK(returnValue);
}
/* Perform certain cleanup actions and delete MPI objects */
void programCleanup(MPIControl *control,
MPIUserLimit *userLimit,
MPIMotion *motion,
MPIAxis *axis,
MPINotify *notify)
{
MPI_RESULT returnValue;
/* Delete notify handle */
returnValue =
mpiControlNotifyDelete(*control, *notify);
msgCHECK(returnValue);
*notify = MPIHandleVOID;
/* Delete motion supervisor object */
returnValue =
mpiMotionDelete(*motion);
msgCHECK(returnValue);
*motion = MPIHandleVOID;
/* Delete axis object */
returnValue =
mpiAxisDelete(*axis);
msgCHECK(returnValue);
*axis = MPIHandleVOID;
/* Delete user limit object */
returnValue =
mpiUserLimitDelete(*userLimit);
msgCHECK(returnValue);
*userLimit = NULL;
/* Delete motion controller object */
returnValue =
mpiControlDelete(*control);
msgCHECK(returnValue);
*control = NULL;
}
//userlimit配置函数
void compareUserLimitSet(MPIUserLimit userLimit,
int32_t axisNumber,
double comparePosition,
MPIUserLimitLogic logic)//logic定义大小比较
{
MPIUserLimitConfig config;
MPI_RESULT returnValue;
returnValue =
mpiUserLimitConfigDefault(&config);//把user limit的配置设置为默认属性
msgCHECK(returnValue);
config.generateEvent = TRUE; /* generate an event */
config.trigger.type = MPIUserLimitTriggerTypeSINGLE_CONDITION; /* Only use one condition */
/* Set up condition[0] */
config.trigger.condition[0].type = MPIUserLimitConditionTypeAXIS_ACTUAL_POSITION;//条件类型时轴的实际位置
config.trigger.condition[0].data.axisActualPosition.axisNumber = axisNumber;//轴的标号
config.trigger.condition[0].data.axisActualPosition.position = comparePosition;//比较的位置
config.trigger.condition[0].data.axisActualPosition.logic = logic;//MPIUserLimitLogicGE,大于等于时,触发用户限制条件
returnValue =
mpiUserLimitConfigSet(userLimit, &config);
msgCHECK(returnValue);
}
/* start move, display user limit event, wait for motion done event, repeat */
void commandMoves(MPIMotion motion,
double endPosition,
double speed,
double acceleration,
double deceleration,
MPIControl control,
MPINotify notify)
{
MPIEventData eventStatus;
MPIMotionStatus status;
double command; /* command position */
double actual; /* actual position */
double position; /* target position */
MPI_RESULT returnValue; /* MPI return value */
fprintf(stderr, "Press any key to exit...\n\n");
/* Loop until the user presses a key */
while (mpiPlatformKey(MPIWaitPOLL) < 0)
{
returnValue =
mpiMotionStatus(motion,
&status);
msgCHECK(returnValue);
returnValue =
mpiMotionPositionGet(motion,
&actual,
&command);
msgCHECK(returnValue);
if (status.state == MPIStateIDLE) {
/* Command a new move */
if (command != 0.0) {
position = 0.0;
}
else {
position = endPosition;
}
/* Perform a trapezoidal move */
returnValue =
mpiMotionSimpleTrapezoidalMove(motion,
position,
speed,
acceleration,
deceleration);
msgCHECK(returnValue);
}
else if (status.state == MPIStateERROR) {
/* An error has occurred, we need to exit */
fprintf(stderr,
"\n\nThe motion supervisor is in an error state.\n"
"Please correct the error before re-starting this application.\n");
}
fprintf(stderr, "Actual Position: %f\r", actual);
fflush(stderr);
/* Obtain firmware event(s) (if any) */
returnValue =
mpiControlProcessEvents(control);//获得固件的事件,获得所有的悬置异步事件,按照先进先出的顺序
msgCHECK(returnValue);
/* Poll for user limit event */
returnValue =
mpiNotifyEventWait(notify,
&eventStatus,
(MPIWait)MPIWaitMSEC*20);//轮询用户的user limit事件
if (returnValue != MPIMessageTIMEOUT)//轮询到这个user limit 事件
{
if (eventStatus.eventType == MPIEventTypeUSER_LIMIT) {
fprintf(stderr,
"\nUser Limit #%d occurred. Sample counter: %d\n",
eventStatus.objectIndex,
eventStatus.sampleCounter);
}
}
}
fprintf(stderr, "\n");
}
int main(int argc,
char *argv[])
{
MPIControl control;
MPIControlType controlType;
MPIControlAddress controlAddress;
MPIUserLimit userLimit;
MPIMotion motion;
MPIAxis axis;
MPINotify notify;
double endPosition = END_POSITION;
double speed = SPEED;
double acceleration = ACCELERATION;
double deceleration = DECELERATION;
int32_t userlimitNumber = USER_LIMIT_NUMBER;
int32_t motionNumber = MOTION_NUMBER;
int32_t axisNumber = AXIS_NUMBER;
/* Parse command line */
parseCommandLine(argc,
argv,
&controlType,
&controlAddress,
&userlimitNumber,
&motionNumber,
&axisNumber);
/* Create and initialize MPI objects */
programInit(&control,
controlType,
&controlAddress,
&userLimit,
userlimitNumber,
&motion,
motionNumber,
&axis,
axisNumber,
¬ify);
/* Setup user limit */
compareUserLimitSet(userLimit,
axisNumber,
COMPARE_POSITION,
COMPARISON_TYPE);
/* start move, display user limit event, wait for motion done event, repeat */
commandMoves(motion,
endPosition,
speed,
acceleration,
deceleration,
control,
notify);
/* Perform certain cleanup actions and delete MPI objects */
programCleanup(&control,
&userLimit,
&motion,
&axis,
¬ify);
return MPIMessageOK;
}
user limit 轴的指定位置
最新推荐文章于 2023-03-01 09:19:48 发布