#pragma once

#include "PMC_Enums.h"

#define MAXREALXBOTS 100

namespace PMC
{
    /// Return info for the FindPMCs function
	struct FindPMCsRtn
	{
		/// PMC command return for the FindPMCs command
		PMCRTN PmcRtn = PMCRTN::ALLOK;		
		/// The number PMCs found on EtherCAT 
		PMC_UINT numPMCsFound = 0;		
		/// The station addresses (AutoInc) of the PMCs found on EtherCAT
		PMC_UINT PMCIOIndexes[256];
	};

    /// return struct for motion commands, includes PMC return + travel time
	struct MotionRtn
	{
		/// PMC return for the motion command
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// travelling time for the command, in seconds
		PMC_REAL TravelTimeSecs = 0;
	};

    /// Return information for PMC border status
	struct BorderStatusRtn
	{
		/// PMC command return for the border status query command
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// The status of the border
		BORDERSTATUS BorderStatus = BORDERSTATUS::DISCONNECTED;
	};

    /// Return information for getting new xbots at PMC borders
	struct BorderNewXbotRtn
	{
		/// PMC command return for the border status query command
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// Number of new received XBOTs
		PMC_USINT XBotCount = 0;
		/// The current IDs of the received XBOTs
		PMC_USINT XBotIDs[100];
		/// The border ID where each xbot was received from
		PMC_USINT BorderIDs[100];
	};

    ///  structure for WaitUntil command
	struct WaitUntilTriggerParams
	{
		/// When trigger source is set to time delay, this is the delay duration, in seconds
		PMC_REAL delaySecs = 0;     //trigger delay time(s)
		/// When trigger source is set to Digital Input (external or fieldbus), this is digital input channel ID.
		PMC_USINT externalOrFBInputChannelID = 0;        //external digital input channel
		/// When trigger source is set to Digital Input (external or fieldbus), the edge type or value that will trigger the event
		TRIGGEREDGETYPE edgeType;      //0: rising edge;1: falling edge;
		/// When trigger source is set to Command Label or Displacement, this is the ID of the XBOT to act as the trigger source 
		PMC_USINT triggerXbotID = 0;     //trigger xbot ID
		/// When trigger source is set to Command Label, this is Command Label to trigger the event
		PMC_USINT triggerCmdLabel = 0;   //trigger command label

		/// For specifying hte details of a command label trigger.
		/// 0 = motion command label; 1 = Run Macro command label
		TRIGGERCMDTYPE triggerCmdType;   //trigger command label
		/// When trigger source is set to Command Label,
		/// CMD_Start means the event will trigger when the command first starts executing, 
		/// CMD_FINISH = after command has finished executing, 
		/// CMD_EXECUTING = at any point during command execution
		TRIGGERCMDLABELTYPE CmdLabelTriggerType;    //0: command start;1: command end;
		/// When the trigger source is set to Displacement, the statement AX+BY vs Threshold is evaluated.
		/// GREATER_THAN means event triggers when AX+BY > Threshold, if is X_ONLY mode, then X > Threshold, in Y_ONLY mode, Y > Threshold. 
		/// LESS_THAN triggers when AX+BY less than Threshold. 
		/// POSITIVE_CROSS triggers when AX+BY is first less than Threshold, then later greater than Threshold. 
		/// NEGATIVE_CROSS triggers when AX+BY is first greater than Threshold, then later less than Threshold. 
		TRIGGERDISPLACEMENTTYPE displacementTriggerType;    //0: greater than;1: less than;
		/// When the trigger source is set to Displacement, this will determine if only the X position is evaluated,
		/// or if only the Y position is evaluated, or if the position is evaluated as AX+BY
		TRIGGERDISPLACEMENTMODE displacementTriggerMode;    //0: greater than;1: less than;
		/// When the trigger source is set to Displacement, and the trigger mode is set to AX+BY, 
		/// this will specify the A parameter
		PMC_REAL lineParamAx = 0;
		/// When the trigger source is set to Displacement, and the trigger mode is set to AX+BY, 
		/// this will specify the B parameter
		PMC_REAL lineParamBy = 0;
		/// When the trigger source is set to Displacement, this will set the threshold to be compared to
		PMC_REAL displacementThresholdMeters = 0;
	};

    /// full XBot status, including it's position and state
	struct XBotStatusRtn
	{
		/// return value for checking the xbot status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// XBot state
		XBOTSTATE State = XBOTSTATE::XBOT_UNDETECTED;		
		/// Command Label@Motion State
		PMC_UINT CmdLb = 0;		
		/// 0: Not Force Mode;1: X force mode;2: Y force mode;4: Z force mode;3: XY force mode
		PMC_USINT FMState = 0;		
		/// 0: Not linked to any xbot; >0: start Xbot ID
		PMC_USINT StarXID = 0;		
		/// 0: Not bond to any group; >0: group ID
		PMC_USINT GroupID = 0;		
		/// number of commands in motion buffer
		PMC_UINT nCmds = 0;		
		/// is the xbot buffer blocked
		PMC_BOOL IsBlocked = false;		
		/// is the xbot motion paused
		PMC_BOOL IsPaused = false;		
		/// xbot X position in meters, force in Newtons
		PMC_REAL PosX = 0;		
		/// xbot Y position in meters, force in Newtons
		PMC_REAL PosY = 0;		
		/// xbot Z position in meters, force in Newtons
		PMC_REAL PosZ = 0;		
		/// xbot rotation about the X axis in radians, torque in Newton*Meters 
		PMC_REAL PosRx = 0;		
		/// xbot rotation about the Y axis in radians, torque in Newton*Meters 
		PMC_REAL PosRy = 0;		
		/// xbot rotation about the Z axis in radians, torque in Newton*Meters 
		PMC_REAL PosRz = 0;		
		/// XBot stereotype ID
		PMC_USINT StereotypeID = 0;		
		/// XBot Type (0 = M3-06,2 = M3-08,4 = M3-09X,5 = M3-09Y,6 = M3-10,8 = M3-11X,9 = M3-11Y,12 = M3-12,14 = M3-13)
		PMC_USINT MoverType = 0;
		/// >0, stream ID that xbot is currently following
		PMC_UINT StreamID = 0;
		/// current part state set using XbotPartCtrl  
		PMC_USINT PartState = 0;
	};

    /// full return for the Get Flyway Status Command. Includes various temperature measurements and power consumption
	struct FlywayPhysicalStatus
	{
		/// return value for checking the xbot status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// power consumption, in watts
		PMC_REAL powerConsumptionW = 0;
		/// CPU temperature, in celsius
		PMC_REAL cpuTempC = 0;
		/// amplifier temperature, in celcius
		PMC_REAL amplifierTempC = 0;
		/// motor temperature, in celsius
		PMC_REAL motorTempC = 0;
	};

    /// a single XBOT's payload options
	struct XBotPayloadSettings
	{
		/// The weight of the payload, in kg
		PMC_REAL payloadkg = 0;
		/// the payload's center of gravity, in meters
		PMC_REAL payloadCGHeightm = 0;
		/// Payload X Dimensions(meters)
		PMC_REAL payloadDimensionXm = 0;
		/// Payload Y Dimensions(meters)
		PMC_REAL payloadDimensionYm = 0;
	};

    /// defines a single mover property
	struct MoverProperty
	{
		/// ID of the mover to set the property for
		PMC_USINT moverID = 0;
		/// the index of the mover property
		MOVERPROPERTY propertyID;
		/// the value of the mover property
		PMC_REAL propertyValue = 0;
	};

    /// full return for the Get Mover Property Command. Contains 8 mover properties
	struct XbotPropertyReturn
	{
		/// return value for checking the xbot status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;		
		/// xbot type (0 = M3-06,2 = M3-08,4 = M3-09X,5 = M3-09Y,6 = M3-10,8 = M3-11X,9 = M3-11Y,12 = M3-12,14 = M3-13)
		MOVERTYPE MoverType;		
		/// payload weight in kilograms
		PMC_REAL PayloadW;		
		/// payload center of gravity in meters
		PMC_REAL PayloadCG;		
		/// mover X dimension in meters
		PMC_REAL XDim;		
		/// mover X dimension in meters
		PMC_REAL YDim;		
		/// acceleration limit in meters/second^2
		PMC_REAL accLimit;
	};

    /// full return for the Get Zone Status Command. Contains Zone information
	struct ZoneStatusReturn
	{
		/// return value for checking the zone status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// Zone State: 0-undefined, 1-active unfenced, 2-deactivating, 3-loading, 4-activating, 5-active fenced
		ZONESTATE State;
		/// Number of XBots inside the zone
		PMC_USINT NumXbots = 0;
		/// IDs of xbots in the zone
		PMC_USINT XbotIDs[39];
	};

    /// full return for the Get Zone Status Extended Command. Contains Extended Zone information
	struct ZoneStatusExReturn
	{
		/// return value for checking the zone status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// Zone State: 0-undefined, 1-active unfenced, 2-deactivating, 3-loading, 4-activating, 5-active fenced
		ZONESTATE State;
		/// Number of XBots inside the zone
		PMC_USINT NumXbotsInZone = 0;
		/// IDs of xbots in the zone
		PMC_USINT XbotIDsInZone[32];
		/// number of xbots on boundary of zone
		PMC_USINT NumXbotsOnBoundary = 0;
		/// xbot IDs of xbots on boundary
		PMC_USINT XbotIDsOnBoundary[32];
	};

    /// Full return from the GetPMCWarnings command
	struct WarningsReturn
	{
		/// return value for checking the zone status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;		
		/// Number of warnings
		PMC_USINT nWarnings = 0;
		/// the warning codes
		PMC_UDINT Warnings[100];
	};

    /// full return for the Get Star Status Command. Contains star information
	struct StarStatusReturn
	{
		/// return value for checking the zone status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;		
		/// 0: not defined, 1: defined, 2: error
		PMC_USINT WheelState = 0;		
		/// 0: not clear, 1: clear
		PMC_USINT EntranceState = 0;		
		/// 0: no xbot in exit, 1: xbot in exit
		PMC_USINT ExitState = 0;		
		/// Exit xbot ID
		PMC_USINT ExitXID = 0;		
		/// Xbot start X coordinate in meters
		PMC_REAL StartX = 0;		
		/// Xbot start Y coordinate in meters
		PMC_REAL StartY = 0;		
		/// Xbot end X coordinate in meters
		PMC_REAL EndX = 0;		
		/// Xbot end Y coordinate in meters
		PMC_REAL EndY = 0;
	};

    /// mover stereotype definition
	struct MoverStereotypeData
	{
		/// The control performance level[0-3], 0 = most conservative level, 3 = most aggresive level
		PMC_USINT performanceLevel = 0;
		/// The weight of the payload, in kg
		PMC_REAL payloadkg = 0;
		/// Payload size from center of the XBOT, in +X direction (meters) 
		PMC_REAL payloadPositiveXmFromXBOTCenter = 0;
		/// Payload size from center of the XBOT, in -X direction (meters)
		PMC_REAL payloadNegativeXmFromXBOTCenter = 0;
		/// Payload size from center of the XBOT, in +Y direction (meters) 
		PMC_REAL payloadPositiveYmFromXBOTCenter = 0;
		/// Payload size from center of the XBOT, in -Y direction (meters) 
		PMC_REAL payloadNegativeYmFromXBOTCenter = 0;
		/// the payload's center of gravity in the x direction, in meters
		PMC_REAL payloadCGXm = 0;
		/// the payload's center of gravity in the y direction, in meters
		PMC_REAL payloadCGYm = 0;
		/// the payload's center of gravity in the z direction, in meters
		PMC_REAL payloadCGZm = 0;		
		/// Acceleration limit during emergency stop (m/s^2)
		PMC_REAL EmergencyStopDecel = 0;
	};

    /// full return for the Get Mover Stereotype Command. 	
	struct MoverStereotypeDefinitionReturn
	{
		/// return value for checking the xbot status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// mover stereotype data
		MoverStereotypeData StereotypeData;
	};

    /// full return for the read assigned mover stereotype Command. 	
	struct ReadAssignedStereotypeReturn
	{
		/// return value for checking the xbot status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// ID of the assigned mover stereotype
		PMC_USINT AssignedStereotypeID = 0;
	};

    /// full return for the Get Mover Property Command. Contains 8 mover properties	
	struct PayloadWeighingReturn
	{
		/// return value for checking the xbot status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// Measured weight, in kg
		PMC_REAL WeightKG = 0;
	};

    /// return struct for get payload settings commands, includes PMC return + PayloadSettings	
	struct PayloadRtn
	{
		/// PMC return for the motion command
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// an xbot's payload settings
		PMC_REAL Payload;
	};

    /// full return of the motion buffer command
	struct MotionBufferStatusRtn
	{
		/// return value for checking the xbot status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// true is xbot buffer is currently blocked, false is buffer is unblocked
		PMC_BOOL State = false;
		/// number of motions commands stored in the xbot's buffer. If xbot ID = 0, the reply will be 0
		PMC_UINT nCmds = 0;
		/// command label of the first command in the buffer, it is the next command that will be executed by the xbot.
		PMC_UINT nextCmdLb = 0;
		/// command label of the last command in the buffer, this is the command that is most recently added to the motion buffer.
		PMC_UINT newCmdLb = 0;
	};

    /// a single XBOT's motion macro status
	struct MotionMacroStatus
	{
		/// 0 = macro is not saved (cannot be run); 2 = macro is saved (ready to run)
		PMC_USINT macroState = 0;
		/// the number of commands stored in this macro
		PMC_USINT storedCommandsCount = 0;
	};

    /// full return of the motion macro	
	struct MotionMacroReturn
	{
		/// return value of the motion macro command
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// the status of the motion macro
		MotionMacroStatus motionMacroStatus;
	};

    /// full return for the group control command	
	struct GroupStatusRtn
	{
		/// return value for checking the xbot status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// 0 = group is disconnected, 1 = group is connected
		PMC_USINT groupStatus = 0;
		/// number of xbots in this group
		PMC_USINT groupMembersCount = 0;
		/// the IDs of the xbots in this group
		PMC_USINT groupMembersID[32];
	};

    /// information required to setup 1 axis of the slave xbot's cam trajectory. 
	struct CamAxisDataClass
	{
		/// ID of the master XBOT
		PMC_USINT MasterXID = 0;
		/// Axis of the master XBOT to track
		AXISNAMES MasterAxisID = AXISNAMES::X_1;
		/// Axis of the slave XBOT used to follow the CAM
		AXISNAMES SlaveAxisID = AXISNAMES::X_1;
		/// ID of the Cam
		PMC_USINT CamID = 128;
	};

    /// information required to setup 1 axis of the slave xbot's cam trajectory. 
	struct CamAxisDataClassExtended
	{
		/// ID of the master XBOT
		PMC_USINT MasterXID = 0;
		/// Axis of the master XBOT to track
		AXISNAMES MasterAxisID = AXISNAMES::X_1;
		/// Axis of the slave XBOT used to follow the CAM
		AXISNAMES SlaveAxisID = AXISNAMES::X_1;
		/// ID of the Cam
		PMC_USINT CamID = 128;

		/// operating mode of the cam, can set cam to automatically repeat
		CAMMODE CamMode = CAMMODE::AutoStart;

		/// Scaling factor for master axis position interval
		PMC_REAL MasterAxisScaling = 1;

		/// Scaling factor for slave axis position values
		PMC_REAL SlaveAxisScaling = 1;

		/// The offset between the start of master axis and the specified origin point, in meters
		PMC_REAL MasterAxisOffsetM = 0;

		/// In absolute mode, the origin position of the cam master axis is the same as the system origin. In relative mode, the origin position of the cam master axis is the same as the current position of the master xbot when the cam was activated
		POSITIONMODE MasterAxisOffsetMode = POSITIONMODE::RELATIVE_MOTION;

		/// The offset between the start of slave axis and the specified origin point, in meters
		PMC_REAL SlaveAxisOffsetM = 0;

		/// In absolute mode, the origin position of the cam slave axis is the same as the system origin. In relative mode, the origin position of the cam slave axis is the same as the current position of the slave xbot when the cam was activated
		POSITIONMODE SlaveAxisOffsetMode = POSITIONMODE::RELATIVE_MOTION;

		/// ratchet direction of the cam master axis. choose whether cam is engage whether the master cam position is increasing or decreasing, only engaged when it's increasing, or only when it's decreasing
		CAMRATCHETDIRECTION MasterAxisRatchetDirection;
	};

    /// Define the queue region
	struct QueueDefinition
	{
		/// starting x coordinate of the queue area, in meters
		PMC_REAL AreaLeftXm = 0;
		/// starting y coordinate of the queue area, in meters
		PMC_REAL AreaBottomYm = 0;
		/// ending x coordinate of the queue area, in meters
		PMC_REAL AreaRightXm = 0;
		/// ending y coordinate of the queue area, in meters
		PMC_REAL AreaTopYm = 0;
		/// entry area of the queue region
		AREASELECTION EntryLocation;
		/// exit area of the queue region
		AREASELECTION ExitLocation;
		/// size of the largest Xbot allowed in the queue, x dimension, in meters
		PMC_REAL MaxXbotXSizem = 0;
		/// size of the largest xbot allowed in the queue, y dimension, in meters
		PMC_REAL MaxXbotYSizem = 0;
		/// max speed used by the queue management to move the XBots
		PMC_REAL MaxSpeedInQueue = 0;
		/// max acceleration used by the queue management to move the XBots
		PMC_REAL MaxAccelInQueue = 0;
	};

    /// Define the auto load region
	struct AutoLoadZoneDefinition
	{
		/// center of the zone at the boundary of the flyway, x position, meters
		PMC_REAL BoundaryCenterXm = 0;
		/// center of the zone at the boundary of the flyway, y position, meters
		PMC_REAL BoundaryCenterYm = 0;
		/// Length of the zone, meters
		PMC_REAL ZoneLengthm = 0;
		/// Width of the zone, meters
		PMC_REAL ZoneWidthm = 0;
		/// loading zone = adding XBot to Flyway. unloading zone = removing XBot from flyway
		ALZONETYPE ZoneType;
		/// stop before unloading, or unload without stopping
		ALZONEUNLOADMODE UnloadingMode;
		/// x size of the Xbot to load / unload, meters
		PMC_REAL MaxXbotXSizem = 0;
		/// y size of the Xbot to load / unload, meters
		PMC_REAL MaxXbotYSizem = 0;
		/// max speed used to load or unload XBots
		PMC_REAL MaxSpeed = 0;
		/// max acceleration used to load or unload XBots
		PMC_REAL MaxAccel = 0;
	};

    /// Basic Queue Status information
	struct QueueStatus
	{
		/// The entry area is empty and ready to receive an XBot
		PMC_BOOL EntryReadyToReceiveXBot;
		/// there is an XBot available at the exit location
		PMC_BOOL XBotAvailableAtExit;
		/// ID of the XBot available at the exit location
		PMC_USINT XBotIDAtExit = 0;
		/// center x position of the entry area of the queue
		PMC_REAL QueueEntryXposm = 0;
		/// center y position of the entry area of the queue
		PMC_REAL QueueEntryYposm = 0;
	};

    /// the return value for the GetQueueStatus Command
	struct QueueStatusReturn
	{
		/// return value for checking the queue status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// the status of the queue
		QueueStatus queueStatus;
	};

    /// information about the queue
	struct QueueInfo
	{
		/// The entry area is empty and ready to receive an XBot
		PMC_BOOL EntryReadyToReceiveXBot;
		/// there is an XBot available at the exit location
		PMC_BOOL XBotAvailableAtExit;
		/// number of XBots being managed by the Queue
		PMC_USINT XBotCount = 0;
		/// Array of XBot IDs of the XBots being managed by the Queue
		PMC_USINT QueuedXBotsIDs[100];
	};

    /// the return value for the GetQueueInfo Command
	class QueueInfoReturn
	{
		/// return value for checking the queue info, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// detailed info of the queue
		QueueInfo queueInfo;
	};

	/// the return value for the AutoLoadingZone_GetAllStatus Command
	struct AutoLoadZoneAllStatusReturn
	{
		/// return value for checking all autoloadingzone status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		// Number of autoloading zones
		PMC_USINT nZones = 0;
		// The IDs of the autoloading zones
		PMC_USINT ZoneIDs[40];
		// 0: undefined, 1: defined, 2: unloading zone, 3: loading zone
		PMC_USINT ZoneStates[40];
		// 0: busy, 1: ready (if loading zone ready = xbot ready to fetch,if unloading zone ready = zone ready to receive new xbot)
		PMC_USINT EntranceExitStates[40];
		// xbot ID added to unloading zone or ready to fetch from loading zone 
		PMC_USINT XbotIDs[40];
		// zone error code
		PMC_USINT LoadingErrorCode[40];
	};

    /// the return value for the AutoLoadingZone_GetZoneStatus Command
	struct AutoLoadZoneStatusReturn
	{
		/// return value for checking the queue status, the validity of the remaining data in this struct in verified by this field
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// whether the zone is undefined, unloading, or loading state
		ALZONESTATE ZoneState;
		/// ID of the XBot loaded at the loading zone
		PMC_USINT LoadedXBotID = 0;
		/// unloading zone ready for next XBot means it is ready to receive another XBot to send to the external device
		/// loading zone ready for next XBot means it is ready to receive another XBot from the external device
		PMC_BOOL ReadyForNextXBot;
		/// number of XBots inside the zone
		PMC_USINT XBotCount = 0;
		/// x position of the unloading point in an unloading zone
		PMC_REAL UnloadingEntryXposm = 0;
		/// y position of the unloading point in an unloading zone
		PMC_REAL UnloadingEntryYposm = 0;
	};

    /// Define the star wheel
	struct StarWheelDefinition
	{
		/// Disc radius in meters
		PMC_REAL DiscRadius = 0;
		/// Max disc rotation speed in radians/sec (must be positive)
		PMC_REAL MaxDiscSpeed = 0;
		/// Max xbot acceleration in meters/sec^2 (must be positive)
		PMC_REAL MaxXbotAcc = 0;
		/// Start of sync section in radians (if CCW must be less than end angle, if CW must be greater than end angle) 
		PMC_REAL SyncAngleBegin = 0;
		/// End of sync section in ratdians (if CCW must be greater than end angle, if CW must be less than end angle)
		PMC_REAL SyncAngleEnd = 0;
		/// X coordinate of disc center in meters
		PMC_REAL DiscCenterX = 0;
		/// Y coordinate of disc center in meters
		PMC_REAL DiscCenterY = 0;
		/// X coordinate of starting location in meters
		PMC_REAL StartLocationX = 0;
		/// Y coordinate of starting location in meters
		PMC_REAL StartLocationY = 0;
		/// X coordinate of ending location in meters
		PMC_REAL EndLocationX = 0;
		/// Y coordinate of ending location in meters
		PMC_REAL EndLocationY = 0;
		/// locations of vials on the disc in radians (must be 0-2PI);
		PMC_REAL VialLocations[100];
		/// number of vials on the disc (less than or equal to 100)
		PMC_USINT NumVials = 0;
		/// Direction of disc rotation (0 = clockwise,1 = counterclockwise)
		PMC_USINT Direction = 0;
		/// ID of master xbot (must be virtual 100-127)
		PMC_USINT MasterXID = 0;
	};

    /// Status of star wheel
	struct StarWheelStatus
	{
		/// Star wheel state: 0 = unassigned, 1 = assigned
		PMC_USINT State = 0;
		/// Start location X coordinate in meters
		PMC_REAL StartLocationX = 0;
		/// Start location Y coordinate in meters
		PMC_REAL StartLocationY = 0;
		/// End location X coordinate in meters
		PMC_REAL EndLocationX = 0;
		/// End location Y coordinate in meters
		PMC_REAL EndLocationY = 0;
		/// Entrance status: 0 - not ready to receive new xbot, 1 - ready to receive new xbot
		PMC_USINT EntranceStatus = 0;
		/// Exit status: 0 - xbot is not ready to fetch, 1 - xbot is ready to fetch
		PMC_USINT ExitStatus = 0;
		/// Xbot ID to fetch 
		PMC_USINT ExitXID = 0;
	};

    /// Star wheel status return wrapper	
	struct StarWheelStatusRtn
	{
		/// Return code
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// Star wheel status
		StarWheelStatus WheelStatus;
	};

    struct GCodeRtn
	{
		/// Return code
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// length of GCode file in bytes
		PMC_DINT GCodeLength = 0;
		/// pointer to the raw binary of GCode file 
		PMC_BYTE GCodeFile[200000];
	};

    struct ConfigRtn
	{
		/// Return code
		PMCRTN PmcRtn = PMCRTN::ALLOK;
		/// length of config file in bytes
		PMC_DINT ConfigLength = 0;
		/// pointer to the raw binary of config file 
		PMC_BYTE ConfigFile[500000];
	};

    struct GCodeIDRtn
	{				
		/// Return code
		PMCRTN PmcRtn;		
		/// Number of G-code files on the PMC
		PMC_USINT nIDs;		
		/// the IDs of the G-code files on the PMC
		PMC_USINT GCodeIDs[64];
	};

    struct AccidentXbotRtn
	{		
		/// Return code
		PMCRTN PmcRtn;		
		/// The number of accident xbots
		PMC_USINT nXbots;		
		/// The accident xbot IDs
		PMC_USINT XbotIDs[150];
	};

    struct LogRtn
	{		
		/// Return Code
		PMCRTN PmcRtn;		
		/// Number of bytes in the log file
		PMC_DINT nBytes;		
		/// the log file as a raw binary
		PMC_BYTE Bytes[100000];
	};

    struct SerialNumRtn
	{		
		/// Return Code
		PMCRTN PmcRtn;		
		/// The 64-bit serial number
		PMC_ULINT SerialNum;		
		/// Flyway firmware version number
		PMC_UDINT FirmwareVersion;
		/// Application data version
		PMC_UDINT AppDataVersion;
	};

    struct VersionRtn
	{
		/// Return Code
		PMCRTN PmcRtn;
		/// The 64-bit version number
		PMC_ULINT VersionNum;
	};

    struct TrajectoryHashRtn
	{
		/// Return Code
		PMCRTN PmcRtn;		
		/// what axises are in the trajectory file: bit0=X; bit1=Y; bit2=Z; bit3=Rx; bit4=Ry; bit5=Rz; bit6=DO (1 means axis selected; 0 means not selected)
		PMC_USINT Axises = 0;		
		/// time interval between positions (seconds)  
		PMC_REAL TimeInterval = 0;		
		/// MD5 hash of the traj file
		PMC_USINT TrajHash[16];
	};

    struct FlywayTempRtn
	{		
		/// Return Code
		PMCRTN PmcRtn;		
		/// Flyway power consumption in watts
		PMC_REAL Power;		
		/// Flyway CPU temperature in degrees Celsius (integer precision)
		PMC_REAL CPUTemp;		
		/// Power amplifier temperature in degrees Celsius (integer precision)
		PMC_REAL PATemp;		
		/// Motor temperature in degrees Celsius (integer precision)
		PMC_REAL MTemp;		
		/// Flyway CPU temperature in degrees Celsius (floating point precision)
		PMC_REAL CPUTempFloat;		
		/// Power amplifier temperature in degrees Celsius (floating point precision)
		PMC_REAL PATempFloat;		
		/// Motor temperature in degrees Celsius (floating point precision)
		PMC_REAL MTempFloat;
	};

    struct FlywayErrorRtn
	{		
		/// Return Code
		PMCRTN PmcRtn;		
		/// The read error code (0 = no error)
		PMC_UDINT FlywayErrorCode;
	};

    struct IncomingXbotsRtn
	{		
		/// Return Code
		PMCRTN PmcRtn;		
		/// Number of incoming xbots
		PMC_USINT nXbots;				
		/// The IDs of the incoming xbots
		PMC_USINT XbotIDs[127];
		/// The IDs of the borders that the xbots are crossing
		PMC_USINT BorderIDs[127];
	};

    struct ErrorCodeRtn
	{		
		/// Return Code
		PMCRTN PmcRtn;		
		/// Number of error codes read 
		PMC_USINT NumErrors;		
		/// The read error codes
		PMC_DINT ErrorCodes[9];
	};

    struct PMCStatusRtn
	{		
		/// Return Code
		PMCRTN PmcRtn;		
		/// PMC Statue
		PMCSTATUS State;		
		/// number of XBots in the system
		PMC_UINT nXbots;		
		/// system power comsumption in Watts
		PMC_REAL Power;		
		/// highest cpu temperature in the system in degrees Celsius (integer precision)
		PMC_REAL MaxCPUTemp;		
		/// highest amplifier temperature in the system in degrees Celsius (integer precision)
		PMC_REAL MaxPATemp;		
		/// highest motor temperature in the system in degrees Celsius (integer precision)
		PMC_REAL MaxMTemp;		
		/// 0: connected and synced; 1: disconnected; 2: connected but not synced
		PMC_USINT FieldbusStatus;		
		/// 0: connected; 1: disconnected
		PMC_USINT PMNetStatus;		
		/// 0: at least one xbot doesn't finish XID scan; 1: all xbots finished XID scan
		PMC_USINT MoverIDScanStatus;		
		/// current PMC error code (0 is OK)
		PMC_UDINT PMCErrorCode;
	};

    struct DigitalSignalRtn
	{		
		/// Digital signal was read successfully
		PMC_BOOL valid = false;		
		/// level of the digital signal
		PMC_BOOL level;
	};

    struct ReadNumXbotsRtn
	{		
		/// number of xbots was read successfully
		PMC_BOOL valid = false;		
		/// The number of xbots
		PMC_USINT nXbots = 0;
	};

    struct PMCStateRtn
	{		
		/// successfully read PMC state
		PMC_BOOL valid = false;		
		/// 0: booting; 1: inactive; 2: activating; 5: operation; 7: deactivating; 8: error handling; 9: error
		PMCSTATUS state;
	};

    struct FeedbackRtn
	{		
		/// successfully read xbot stream feedback
		PMC_BOOL valid = false;		
		/// value read from stream: meters/Newtons for X, Y, Z; radians/Newton*Meters for Rx, Ry, Rz
		PMC_REAL FeedbackValue = 0;
	};

    struct ReadXbotIDsRtn
	{		
		/// successfully read xbot IDs
		PMC_BOOL valid;		
		/// number of xbots in system
		PMC_USINT NumXbots;		
		/// xbot ID#s of xbots in the system
		PMC_USINT Xbot_IDs[127];
	};

    struct GetXbotIDsRtn
	{		
		/// successfully read xbot IDs
		PMC_BOOL done;		
		/// number of xbots in system
		PMC_USINT NumXbots;		
		/// xbot ID#s of xbots in the system
		PMC_USINT Xbot_IDs[127];
	};

    struct ReadXbotPosRtn
	{		
		/// xbot position was read successfully 
		PMC_BOOL valid;		
		/// xbot X position in meters
		PMC_REAL PosX;		
		/// xbot Y position in meters
		PMC_REAL PosY;		
		/// xbot Z position in meters
		PMC_REAL PosZ;		
		/// xbot rotation about X axis in radians 
		PMC_REAL PosRx;		
		/// xbot rotation about Y axis in radians 
		PMC_REAL PosRy;		
		/// xbot rotation about Z axis in radians 
		PMC_REAL PosRz;
	};

    struct ReadXbotStateRtn
	{		
		/// successfully read xbot state
		PMC_BOOL valid;		
		/// 0 = undetected, 1 = discovering, 2 = landed, 3 = idle, 4 = disabled, 5 = in motion, 6 = waiting, 7 = stopping, 8 = obstacle, 9 = hold, 10 = stopped, 14 = error
		XBOTSTATE State;
	};

    struct ReadXbotStatusRtn
	{		
		/// xbot status is up-to-date, if false the output position is the last known status
		PMC_BOOL valid;		
		/// 0: position mode; 1: force mode
		PMC_USINT ControlMode;		
		/// 0: resumed; 1:paused
		PMC_USINT MotionStatus;		
		/// 0: buffer released; 1:buffer blocked
		PMC_USINT BufferStatus;		
		/// 0: unbond to group; 1:bonded to group
		PMC_USINT GroupStatus;		
		/// 0: unlinked to planet; 1: linked to planet
		PMC_USINT PlanetStatus;		
		/// 0: xbot free; 1: xbot locked
		PMC_USINT LockStatus;		
		/// active stereotype ID for this xbot 
		PMC_USINT StereotypeID;
	};

    struct FunctionRtn
	{
		/// Return Code
		PMCRTN PmcRtn;		
		/// The assigned function id number
		PMC_USINT FunctionID;
	};

    struct FunctionInfoRtn
	{
		/// Return Code
		PMCRTN PmcRtn;				
		/// The function state: 0 - inactive, 1 - active
		PMC_USINT functionState;
		/// The number of commands in the function
		PMC_USINT numCmds;
		/// The number xbots in the function
		PMC_USINT numXbots;
	};

    struct StartUpPMSRtn
	{
		/// Return Code
		PMCRTN PmcRtn;
		/// number of xbots in system
		PMC_USINT NumXbots = 0;
		/// xbot ID#s of xbots in the system
		PMC_USINT Xbot_IDs[127];
	};

    struct ScanXIDRtn
	{
		/// Return Code
		PMCRTN PmcRtn;		
		/// 1 : valid RFID detected, 0 : invalid
		PMC_USINT Status;		
		/// xbot global ID 
		PMC_ULINT XID;
	};

    struct ReadTimeStampRtn
	{
		/// successfully read the timestamp 
		bool valid;
		/// timestamp value in nanoseconds (local PMC time since power on) 
		PMC_ULINT TimeStamp_ns;
	};

    struct ReadXbotSpeedRtn
	{		
		/// successfully read the xbot speed
		PMC_BOOL valid;		
		/// speed in the X axis in m/s
		PMC_REAL SpeedX;		
		/// speed in the Y axis in m/s
		PMC_REAL SpeedY;		
		/// speed in the Rz axis in m/s
		PMC_REAL SpeedRz;
	};

    struct Sector_GetStatusRtn
	{
		/// Return Code
		PMCRTN PmcRtn;
		/// 0: not defined, 1: disconnected, 2: inactive and fenced, 3: deactivating, 4: stopping, 5: activating, 6: activated and fenced, 7: in operation
		PMC_USINT State;		
		/// Number of xbots in the sector
		PMC_USINT NumXbots;		
		/// IDs of the xbots in the sector
		PMC_USINT XbotIDs[32];
	};

    struct ThroughputTestRtn
	{		
		/// Return Code
		PMCRTN PmcRtn;		
		/// Full duplex 1 ms fieldbus throughput
		PMC_UDINT Throughput1ms;
	};

    struct GetXbotRFIDsRtn
	{		
		/// Return Code
		PMCRTN PmcRtn;		
		/// Number of RFIDs scanned
		PMC_USINT NumRFIDs;		
		/// the 64 bits scannded RFIDs
		PMC_ULINT RFIDs[127];			
		/// corresponding xbot IDs
		PMC_USINT XbotIDs[127];
	};

    struct LinkedMover_AssignRtn
	{
		/// Return Code
		PMCRTN PmcRtn;		
		/// linked xbot ID, used to drive the linked xbots
		PMC_USINT LinkedXbotID;
	};

    struct FindXbotsInAreaRtn
	{
		/// 1 if values are valid
		PMC_BOOL valid;		
		/// Number of xbots whose centers are in the area
		PMC_USINT nXbots;		
		/// IDs of xbots whose centers are in the area
		PMC_USINT XbotIDs[127];
	};

	struct GetSpacedXbotPositionsRtn
	{
		/// Return Code
		PMCRTN PmcRtn;	
		/// @brief Number xbots in system
		PMC_USINT nXbots;
		/// @brief The IDs of the xbots in the system
		PMC_USINT XbotIDs[127];
		/// @brief Spaced out X positions
		PMC_REAL PosX[127];
		/// @brief Spaced out Y positions
		PMC_REAL PosY[127];
	};

	struct AppDesign_GetAllStationXbotsRtn
	{
		/// Return Code
		PMCRTN PmcRtn;	
		/// @brief Total number of bays in the system
		PMC_UINT NumBays;
		/// @brief IDs of the station
		PMC_USINT StationIDs[5000];
		/// @brief IDs of the bay
		PMC_USINT BayIDs[5000];
		/// @brief IDs of the xbot
		PMC_USINT XbotIDs[5000];
	};

	struct AppDesign_GetBayXbotIDRtn
	{
		/// Return Code
		PMCRTN PmcRtn;	
		/// @brief Id of the xbot in the station's bay
		PMC_USINT XbotID;
	};

	struct AppDesign_GetDesignRtn
	{
		/// Return Code
		PMCRTN PmcRtn;	
		/// @brief Number of bytes in the read configuration file
		PMC_DINT nBytes;
		/// @brief the application designer file as a raw binary
		PMC_BYTE Bytes[500000];
	};

	struct AppDesign_GetStationXbotIDsRtn
	{
		/// Return Code
		PMCRTN PmcRtn;	
		/// @brief number of bays in the station
		PMC_USINT NumBays;
		/// @brief IDs of the xbots in the station's bays
		PMC_USINT XbotIDs[30];
	};

	struct AppDesign_GetXbotTargetRtn
	{
		/// Return Code
		PMCRTN PmcRtn;	
		/// @brief Station ID (>0)
		PMC_USINT StationID;
		/// @brief Bay ID (>0)
		PMC_USINT BayID;
	};

	struct MoverID_GetScanLocationRtn
	{
		/// Return Code
		PMCRTN PmcRtn;
		/// @brief X coordinate of the bottom left corner of the new station (m)
		PMC_REAL ScanLocationX;
		/// @brief Y coordinate of the bottom left corner of the new station (m)
		PMC_REAL ScanLocationY;
	};

	struct MoverID_ReadScanStatusRtn
	{
		/// @brief xbot state is up-to-date, if false the output state is the last known state
		PMC_BOOL Valid;
		/// @brief false: unscanned, true: scanned
		PMC_BOOL ScanStatus;
	};

	struct MoverID_ScanMoverIDRtn
	{
		/// @brief Return Code
		PMCRTN PmcRtn;
		/// @brief 1 : valid RFID detected, 0 : invalid
		PMC_USINT Status;
		/// @brief xbot global ID 
		PMC_ULINT XID;
	};

	struct MoverLabel_GetLabelRtn
	{
		/// @brief Return Code
		PMCRTN PmcRtn;
		/// @brief Mover label assigned to the xbot
		PMC_UINT MoverLabel;
	};

	struct MoverLabel_GetXbotIDRtn
	{
		/// @brief Return Code
		PMCRTN PmcRtn;
		/// @brief Xbot ID with the mover label
		PMC_USINT XbotID;
	};

	struct StreamModeCtrlRtn
	{
		/// @brief Return Code
		PMCRTN PmcRtn;
		/// @brief Starting X positions of the xbots 
		PMC_REAL StreamStartPosX[9];
		/// @brief Starting Y positions of the xbots 
		PMC_REAL StreamStartPosY[9];
	};

	struct GetAllAccidentLocationsRtn
	{
		/// @brief Return Code
		PMCRTN PmcRtn;
		/// @brief Number of accidents
		PMC_USINT nAccidents;
		/// @brief bottom left corner X coordinate of accident zone
		PMC_REAL AccidentBottomLeftX[225];
		/// @brief bottom left corner Y coordinate of accident zone
		PMC_REAL AccidentBottomLeftY[225];
		/// @brief top right corner X coordinate of accident zone
		PMC_REAL AccidentTopRightX[225];
		/// @brief top right corner Y coordinate of accident zone
		PMC_REAL AccidentTopRightY[225];
	};

	struct GetFlywayConnectErrorCountsRtn
	{
		/// @brief Return Code
		PMCRTN PmcRtn;
		/// @brief Number of flyways in the system
		PMC_USINT nFlyways;
		/// @brief The status of each flyway
		PMC_USINT FlywayStatus[200];
		/// @brief The number of flyway connection errors for each flyway
		PMC_UDINT ConnectionErrorCount[200];
	};

	struct GetPMNetErrorCountsRtn
	{
		/// @brief Return Code
		PMCRTN PmcRtn;
		/// @brief Number of flyways in the system
		PMC_USINT nFlyways;
		/// @brief Number of PMNet errors on the north edge
		PMC_USINT FlywayNorthConnectionErrorCount[200];
		/// @brief Number of PMNet errors on the east edge
		PMC_USINT FlywayEastConnectionErrorCount[200];
		/// @brief Number of PMNet errors on the south edge
		PMC_USINT FlywaySouthConnectionErrorCount[200];
		/// @brief Number of PMNet errors on the west edge
		PMC_USINT FlywayWestConnectionErrorCount[200];
	};

	struct ReadXbotForceRtn
	{
		/// @brief xbot force was read successfully
		PMC_BOOL Valid;
		/// @brief force in X in Newtons
		PMC_REAL Fx;
		/// @brief force in Y in Newtons
		PMC_REAL Fy;
		/// @brief force in Z in Newtons 
		PMC_REAL Fz;
		/// @brief torque about X axis in Newton*Meters
		PMC_REAL Tx;
		/// @brief torque about Y axis in Newton*Meters
		PMC_REAL Ty;
		/// @brief torque about Z axis in Newton*Meters
		PMC_REAL Tz;
	};

	struct IncomingXbotsExRtn
	{		
		/// Return Code
		PMCRTN PmcRtn;		
		/// Number of incoming xbots
		PMC_USINT nXbots;				
		/// The IDs of the incoming xbots
		PMC_USINT XbotIDs[127];
		/// The IDs of the borders that the xbots are crossing
		PMC_USINT BorderIDs[127];
		/// the mover types of the xbots that are crossing
		PMC_USINT MoverTypes[127];
		/// mover labels of the xbots that are crossing 
		PMC_UINT MoverLabels[127];
		/// the stereotype IDs of the xbots that are crossing 
		PMC_USINT StereotypeIDs[127];
	};

	struct GetPlanetsRtn
	{
		/// Return Code
		PMCRTN PmcRtn;		
		/// number of planet xbots attached to the star xbot
		PMC_USINT NumPlanets;
		/// IDs of planet xbots attached
		PMC_USINT PlanetXbotIDs[32];
	};

	struct GetStarRtn
	{
		/// Return Code
		PMCRTN PmcRtn;		
		/// 0: Not linked to any xbot; >0: star Xbot ID
		PMC_USINT StarXbotID;
	};
}