From SoftMC-Wiki
Jump to: navigation, search


The FastData UDP server allows a UDP client to retrieve from the MC data about specific axes and variables.
The server is initialized upon MC startup and is immediately ready to respond to clients.

Server Functionality

The server will receive client requests from any IP address, on port 60000.
The server will send axes data ONCE upon a SINGLE request received from the client, and will send
data only about axes that were specifically requested by the client.
Meaning the server is blocked on receive( ) and anticipates data from the client that indicates which axes data to send back.

On version 1 of the FastData server, MC Integer and MC Double arrays are added to the requested axes data.

Client Request

The client sends to the server a character array. Each cell in the array indicates an axis number.
A cell that is set to a value different from zero indicates that the client is interested in that specific axis’ data.

For Example, if cells 0, 5 and 13 are set to some value (not zero), it means that the client wants the data of axes numbers 1, 6 and 14.

Server Response

Struct serverdata holds the FastData UDP version, arrays of MC Integer and MC Double (these arrays are set by the MC user) and requested data about the specified axes.
This struct allows backward compatibility in case that more data will be added to FastData in the future. It holds offsets from the head of the struct to beginnings of arrays of data and their lengths. This allows the client to read correctly the received data.

Following is the definition of the struct as it appears in FastData Version 1:

/* A structure to be sent back to the client after a request was received */<br/>
/* This structure holds the number of valid axis data structs and an array of the axis data structs */<br/><br/>
struct serverdata {

	INT32 version __attribute__ ((packed));       /* = FASTDATA_VERSION */

	INT32 axesdata_Offset __attribute__ ((packed));   /* Offset in bytes from beginning of data packet to axesdata array = &axesdata - &version */
	INT32 numOfAxesStructs __attribute__ ((packed));  /* number of valid axes info structures in FastAxisData array */
	INT32 sizeOfAxesStruct __attribute__ ((packed));  /* Size of 1 struct FastAxisData */

	INT32 int_array_Offset __attribute__ ((packed));  /* Offset in bytes from beginning of data packet to int_array = &int_array - &version */
	INT32 int_array_length __attribute__ ((packed));  /* number of integers in array = USER_REGISTER_LENGTH */

	INT32 double_array_Offset __attribute__ ((packed));  /* Offset in bytes from beginning of data packet to double_array = &double_array - &version */
	INT32 double_array_length __attribute__ ((packed));  /* number of doubles in array = USER_REGISTER_LENGTH */

	//INT32 sysDin __attribute__ ((packed));  // system digital input
	//INT32 sysDout __attribute__ ((packed));  // system digital output

	// Additional data set by a user task
	INT32 int_array[USER_REGISTER_LENGTH] __attribute__ ((packed));			/* user data integer array */
	double double_array[USER_REGISTER_LENGTH] __attribute__ ((packed));			/* user data double array */

	struct FastAxisData axesdata[64];


The Server sends the struct serverdata with the field numOfAxes holding the number of axes that were requested by the client (could be less than the total number of axes in the system), and an array of struct FastAxisData that holds axis data per each axis, including the specific axis number, and bus_cycle_num which holds the Sercos Sample count.

The array axesdata[-???-] has the length of the number of axes data structs which are sent back from the server to the client. It is populated sequentially, meaning, if the client was interested in 3 axes, say, 1, 6 and 19, the array axesdata[-???-] will have the length of 3, and indices 0, 1 and 2 will hold structs of axes 1, 6 and 19 respectively.

Fast Axis Data Structure

According to the array received from the client, the server collects the data and populates the following data structures:

/* This structure holds a specific axis data */<br/>
struct FastAxisData {

	int		pnStatus __attribute__ ((packed));
	int		axisnumber __attribute__ ((packed));
	int		drvStat __attribute__ ((packed)); 	// drive status word
	int		bus_cycle_num __attribute__ ((packed));  // system (sample number)

	double	pCmd __attribute__ ((packed));			// position command (user)
	double	pFb __attribute__ ((packed));			// position feedback (user)
	double	pExt __attribute__ ((packed));			// position external
	double	cCmd __attribute__ ((packed));			// position command (drive units)
	double	cFb __attribute__ ((packed));			// position feedback (drive units)
	double	vCmd __attribute__ ((packed));			// velocity command
	double	vFb __attribute__ ((packed));			// velocity feedback
	double	aCmd __attribute__ ((packed));			// acceleration command
//	double	aFb __attribute__ ((packed));			// acceleration feedback
	double	tAddCmd __attribute__ ((packed));		// torque (additional) command
	double	tFb __attribute__ ((packed));			// torque feedback


pnStatus is mapped as follows:
Bit 0 - IsSettled: Set to 1 when the generator has completed AND abs(Target_pos - Actual_pos) <= PositionErrorSettle
Bit 1 - IsMoving: Set to 1 when the profiler is active.
Bit 2 - DriveEnabled: Set to 1 when the drive associated with the axis is enabled.
Bit 3 - DriveFault: Set to 1 when a fault exists on the drive associated with the axis. All unused bits return 0.