.

     

MPI Application Template
template.c
 

mboard2.c -- Two point motion on multiple controllers with an event manager in polling mode.
/* mboard2.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
 */
/*

:Two point motion on multiple controllers with an event manager in polling mode.

Creates a two point motion sequentially on multiple controller boards.
 One event manager is used for all controllers.  The event manager is polled
 to retrieve MotionDone events from each motion.

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    mboard2Main

argMainRENAME(main, mboard2)
#endif

#define BOARD_COUNT (2)

#define MOTION_COUNT    (1)
#define AXIS_COUNT      (1)

/* Command line arguments and defaults */
long            controlNumber   = 0;
long            axisNumber      = 0;
long            motionNumber    = 0;
MPIMotionType   motionType      = MPIMotionTypeTRAPEZOIDAL;

Arg argList[] = {
    {   "-control", ArgTypeLONG,    &controlNumber, },
    {   "-axis",    ArgTypeLONG,    &axisNumber,    },
    {   "-motion",  ArgTypeLONG,    &motionNumber,  },
    {   "-type",    ArgTypeLONG,    &motionType,    },

    {   NULL,       ArgTypeINVALID, NULL,   }
};

double position[MOTION_COUNT][AXIS_COUNT] = {
    { 20000.0 },
};

MPITrajectory trajectory[MOTION_COUNT][AXIS_COUNT] = {
    {   /* velocity     accel       decel */
        { 10000.0,      100000.0,   100000.0,   },
    },
};

/* motion parameters */
MPIMotionSCurve sCurve[MOTION_COUNT] = {
    {   &trajectory[0][0],  &position[0][0],    },
};

MPIMotionTrapezoidal    trapezoidal[MOTION_COUNT] = {
    {   &trajectory[0][0],  &position[0][0],    },
};

MPIMotionVelocity   velocity[MOTION_COUNT] = {
    {   &trajectory[0][0],  },
};

int
    main(int    argc,
         char   *argv[])
{
    MPIControl      controller[BOARD_COUNT];/* Array of control handles */
    MPIMotion       motion[BOARD_COUNT];    /* Array of motion handles */
    MPIAxis         axis[BOARD_COUNT];      /* Array of axis handles */
    MPINotify       notify[BOARD_COUNT];    /* Array of notify handles */
    MPIEventMgr     eventMgr;   /* Array of event manager handles */

    MPIEventMask    eventMask;

    MPIControlAddress   address;

    long    returnValue;
    long    argIndex=0;
    long    index;

    /* 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 - 1) ||    /* minus application name */
        (axisNumber   >= MEIXmpMAX_Axes) ||
        (motionNumber >= MEIXmpMAX_MSs) ||
        (motionType <  MPIMotionTypeFIRST) ||
        (motionType >= MEIMotionTypeLAST)) {
        meiPlatformConsole("usage: %s %s\n"
                           "\t\t[-axis # (0 .. %d)]\n"
                           "\t\t[-motion # (0 .. %d)]\n"
                           "\t\t[-type # (0 .. %d)]\n",
                            argv[0],
                            ArgUSAGE,
                            MEIXmpMAX_Axes - 1,
                            MEIXmpMAX_MSs - 1,
                            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;
        }
    }

    /*
        Initialize each controller with default settings,
        specifying the board's controller number.
     */
    for (index = 0; index < BOARD_COUNT; index++) {
        address.number = controlNumber + index; /* set controller number */

        controller[index] =
            mpiControlCreate(MPIControlTypeDEFAULT,
                             &address);
        msgCHECK(mpiControlValidate(controller[index]));
    }

    /* Initialize the controllers */
    for (index = 0; index < BOARD_COUNT; index++) {
        returnValue = mpiControlInit(controller[index]);

        if (returnValue != MPIMessageOK) {
            fprintf(stderr,
                    "Controller #%d : mpiControlInit(0x%x) returns 0x%x: %s\n",
                    index,
                    controller[index],
                    returnValue,
                    mpiMessage(returnValue, NULL));

            exit(1);
        }
    }

    /* Obtain Axis and Motion handle for each board */
    for (index = 0; index < BOARD_COUNT; index++) {
        axis[index] =
            mpiAxisCreate(controller[index],
                          axisNumber);
        msgCHECK(mpiAxisValidate(axis[index]));

        /* Create motion object, append axis */
        motion[index] =
            mpiMotionCreate(controller[index],
                            motionNumber,
                            axis[index]);
        msgCHECK(mpiMotionValidate(motion[index]));
    }

    /* Setup one Event Manager for all boards */

    /* Create event manager object */
    eventMgr = mpiEventMgrCreate(controller[0]);
    msgCHECK(mpiEventMgrValidate(eventMgr));

    for (index = 1; index < BOARD_COUNT; index++) {
        /* Append additional controllers to the event manager */
        returnValue =
            mpiEventMgrControlAppend(eventMgr,
                                     controller[index]);
        msgCHECK(returnValue);
    }

    /* Flush any existing events */
    returnValue = mpiEventMgrFlush(eventMgr);
    msgCHECK(returnValue);

    /* Setup Notify Object */
    mpiEventMaskCLEAR(eventMask);
    mpiEventMaskSET(eventMask, MPIEventTypeMOTION_DONE);

    for (index = 0; index < BOARD_COUNT; index++) {
        /* Request notification of Motion Done events from motion */
        returnValue =
            mpiMotionEventNotifySet(motion[index],
                                    eventMask,
                                    NULL);
        msgCHECK(returnValue);

        /* Create event notification object for motion */
        notify[index] =
            mpiNotifyCreate(eventMask,
                            motion[index]);
        msgCHECK(mpiNotifyValidate(notify[index]));

        /* Add notify to event manager's list */
        returnValue =
            mpiEventMgrNotifyAppend(eventMgr,
                                    notify[index]);
        msgCHECK(returnValue);
    }

    /* Clear the command and actual positions on each controller */
    for (index = 0; index < BOARD_COUNT; index++) {
        double command;

        returnValue =
            mpiAxisCommandPositionGet(axis[index],
                                      &command);
        msgCHECK(returnValue);

        returnValue =
            mpiAxisOriginSet(axis[index],
                             command);
        msgCHECK(returnValue);

        /* clear position error */
        returnValue =
            mpiAxisActualPositionSet(axis[index],
                                     0.0);
        msgCHECK(returnValue);
    }

    /* Sequentially start motion */
    for (index = 0; index < BOARD_COUNT; index++) {
        MPIMotionParams motionParams;

        switch (motionType) {
            case MPIMotionTypeS_CURVE: {
                motionParams.sCurve = sCurve[0];
                break;
            }
            case MPIMotionTypeTRAPEZOIDAL: {
                motionParams.trapezoidal = trapezoidal[0];
                break;
            }
            case MPIMotionTypeVELOCITY: {
                motionParams.velocity = velocity[0];
                break;
            }
            default: {
                meiAssert(FALSE);
                break;
            }
        }

        /* Start motion */
        returnValue =
            mpiMotionStart(motion[index],
                           motionType,
                           &motionParams);

        fprintf(stderr,
                "mpiMotionStart(0x%x, %d, 0x%x) returns 0x%x: %s\n",
                motion[index],
                motionType,
                &motionParams,
                returnValue,
                mpiMessage(returnValue, NULL));

        switch (returnValue) {
            case MPIMotionMessageERROR: {
                returnValue =
                    mpiMotionAction(motion[index],
                                    MPIActionRESET);
                fprintf(stderr,
                        "mpiMotionAction(0x%x, RESET) returns 0x%x\n",
                        motion[index],
                        returnValue);
                msgCHECK(returnValue);
                /* FALL THROUGH */
            }
            case MPIMotionMessageMOVING: {
                returnValue = MPIMessageOK;
                break;
            }
            case MPIMessageOK:
            default: {
                break;
            }
        }


        /* Collect motion events (Polling Event Manager)*/
        while (TRUE) {
            MPIEventStatus  eventStatus;

            /* Obtain firmware event(s) (if any) */
            returnValue =
                mpiEventMgrService(eventMgr,
                                   MPIHandleVOID);
            msgCHECK(returnValue);

            /* Poll for motion event */
            returnValue =
                mpiNotifyEventWait(notify[index],
                                   &eventStatus,
                                   MPIWaitPOLL);

            if (returnValue == MPIMessageTIMEOUT) {
                /* no events have happend yet */
                returnValue = MPIMessageOK;
            }

            if (returnValue == MPIMessageOK) {
                if (eventStatus.type == MPIEventTypeMOTION_DONE) {
                    /* Caught the motion done event */
                    printf("Motion Done: type %d source 0x%x info 0x%x\n",
                            eventStatus.type,
                            eventStatus.source,
                            eventStatus.info[0]);
                    break;
                }
            }
            else {
                printf("%d\n",returnValue);
                meiAssert(FALSE);
            }
        }
    }

    /* Delete the EventMgr handle (must happen before removing Notify) */
    returnValue = mpiEventMgrDelete(eventMgr);
    msgCHECK(returnValue);

    /* Delete the Notify handles */
    for (index = 0; index < BOARD_COUNT ;index++) {
        returnValue = mpiNotifyDelete(notify[index]);
        msgCHECK(returnValue);
    }

    /* Delete the Motion handles */
    for ( index = 0; index < BOARD_COUNT ;index++) {
        returnValue = mpiMotionDelete(motion[index]);
        msgCHECK(returnValue);
    }

    /* Delete the Axis handles */
    for (index = 0; index < BOARD_COUNT; index++) {
        returnValue = mpiAxisDelete(axis[index]);
        msgCHECK(returnValue);
    }

    /* Delete the CONTROL handles */
    for (index = 0; index < BOARD_COUNT; index++) {
        returnValue = mpiControlDelete(controller[index]);
        msgCHECK(returnValue);
    }

    return ((int)returnValue);
}


 
      
       Legal Notice  |  Tech Email  |  Feedback
      
Copyright ©
2001-2009 Motion Engineering