You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
504 lines
14 KiB
504 lines
14 KiB
/*{{[PH]
|
|
****************************************************************************
|
|
Project: FRI
|
|
|
|
This material is the exclusive property of KUKA Roboter GmbH
|
|
and must be returned to KUKA Roboter GmbH immediately upon
|
|
request. This material and the information illustrated or
|
|
contained herein may not be used, reproduced, stored in a
|
|
retrieval system, or transmitted in whole or in part in any
|
|
way - electronic, mechanical, photocopying, recording, or
|
|
otherwise, without the prior written consent of KUKA Roboter GmbH.
|
|
|
|
All Rights Reserved
|
|
Copyright (C) 2009
|
|
KUKA Roboter GmbH
|
|
Augsburg, Germany
|
|
|
|
[PH]}}
|
|
*/
|
|
|
|
/*
|
|
{{[FH]
|
|
****************************************************************************
|
|
friComm.h
|
|
|
|
NOTE: FRI (Fast Research inteface) is subject to radical change
|
|
|
|
|
|
[FH]}}
|
|
*/
|
|
/**
|
|
\author (Andreas Stemmer,DLR)
|
|
\author (Guenter Schreiber,KUKA)
|
|
\file
|
|
\brief This header file describes the basic communcation structures for
|
|
the FastRobotInterface
|
|
|
|
|
|
- all data is transmitted in Intel byte order (little endian)
|
|
- structs use 4 byte padding
|
|
- all floats are IEEE 754 single precision floats with 4 bytes
|
|
- for the sequence counters in the header, the number following
|
|
#FRI_UINT16_MAX is assumed to be zero (normal integer overflow)
|
|
- For Checking, that your compiler setup interprets the binary communication as expceted,
|
|
use the macros #FRI_CHECK_SIZES_OK, #FRI_PREPARE_CHECK_BYTE_ORDER, #FRI_CHECK_BYTE_ORDER_OK in your code.
|
|
|
|
*/
|
|
/*****************************************************************************
|
|
|
|
friComm.h
|
|
|
|
created: 09/05/26 by Andreas Stemmer
|
|
|
|
$Revision: 1.17 $ $Author: stemmer $ $Date: 2010/02/12 15:15:18 $
|
|
|
|
(C) by Institute of Robotics and Mechatronics, DLR
|
|
|
|
Description:
|
|
|
|
This header file describes the basic communcation structures for
|
|
the FastRobotInterface
|
|
|
|
Note:
|
|
|
|
|
|
|
|
*****************************************************************************/
|
|
|
|
#ifndef FRICOMM_H
|
|
#define FRICOMM_H
|
|
|
|
|
|
#define LBR_MNJ 7 /*!< Number of Managed Joints for Light Weight Robot */
|
|
#define FRI_USER_SIZE 16 /*!< Number of Userdefined data, which are exchanged to KRL Interpreter */
|
|
#define FRI_CART_FRM_DIM 12 /*!< Number of data within a 3x4 Cartesian frame - homogenous matrix */
|
|
#define FRI_CART_VEC 6 /*!< Number of data for a Cartesian vector */
|
|
|
|
|
|
typedef unsigned char fri_uint8_t; /*!< 1 byte unsigned */
|
|
typedef unsigned short fri_uint16_t; /*!< 2 byte unsigned */
|
|
typedef unsigned int fri_uint32_t; /*!< 4 byte unsigned */
|
|
typedef int fri_int32_t; /*!< 4 byte signed */
|
|
typedef float fri_float_t; /*!< 4 byte IEEE 754 float */
|
|
#define FRI_UINT16_MAX ((1<<16) - 1) /*!< Biggest UINT16 w.r.t the interface - porting isno fun */
|
|
|
|
|
|
/** header data used in every packet in both directions
|
|
*
|
|
* */
|
|
typedef struct
|
|
{
|
|
/** sequence counter (increasing with every packet) of the sender
|
|
Used for detecting packet loss of UDP Transfer,
|
|
put in your code s.th. like
|
|
* fri_uint16_t seqCount;
|
|
* seqCount++;
|
|
* cmd.head.sendSeqCount=seqCount;
|
|
*/
|
|
fri_uint16_t sendSeqCount;
|
|
|
|
/** reflected sequence counter (mirrored from last received packet)
|
|
Used for detecting packet loss of UDP transfer and latency statistics
|
|
\sa tFriIntfStatistics
|
|
* remote side: put s.th. like
|
|
* cmd.head.reflSeqCount=msr.head.sendSeqCount;
|
|
*/
|
|
fri_uint16_t reflSeqCount;
|
|
|
|
/** overall packet size
|
|
Remote side: FRI_CMD_DATA_SIZE
|
|
*/
|
|
fri_uint16_t packetSize;
|
|
|
|
/** unique datagram id to detect version problems etc.
|
|
Remote side: FRI_DATAGRAM_ID_CMD
|
|
*/
|
|
fri_uint16_t datagramId;
|
|
} tFriHeader;
|
|
#define FRI_HEADER_SIZE 8
|
|
|
|
|
|
|
|
|
|
/** data for direct interaction with KRL */
|
|
typedef struct
|
|
{
|
|
/** 16 float values (corresponds to $FRI_TO_REA[] and $FRI_FRM_REA[]) */
|
|
fri_float_t realData[FRI_USER_SIZE];
|
|
|
|
/** 16 int values (corresponds to $FRI_TO_INT[] and $FRI_FRM_INT[]) */
|
|
fri_int32_t intData[FRI_USER_SIZE];
|
|
|
|
/** 16 bool values, stored in one int */
|
|
fri_uint16_t boolData;
|
|
|
|
/** manual padding to a multiple of 4 bytes */
|
|
fri_uint16_t fill;
|
|
} tFriKrlData;
|
|
#define FRI_KRL_DATA_SIZE 132
|
|
|
|
|
|
|
|
|
|
/** reported communication statistics (average rating over the last
|
|
100 packets) */
|
|
typedef struct
|
|
{
|
|
/** avg. answer rate (should be close to 1) */
|
|
fri_float_t answerRate;
|
|
|
|
/** avg. latency in seconds (should be as small as possible) */
|
|
fri_float_t latency;
|
|
|
|
/** avg. jitter in seconds (should be as small as possible) */
|
|
fri_float_t jitter;
|
|
|
|
/** avg. missing answer packets (should be as small as possible) */
|
|
fri_float_t missRate;
|
|
|
|
/** absolute missing answer packets */
|
|
fri_uint32_t missCounter;
|
|
} tFriIntfStatistics;
|
|
#define FRI_INTF_STATISTICS_SIZE 20
|
|
|
|
|
|
|
|
|
|
/** feedback about the interface itself */
|
|
typedef struct
|
|
{
|
|
/** current system time in seconds */
|
|
fri_float_t timestamp;
|
|
|
|
/** state of interface (monitor or command FRI_STATE) */
|
|
fri_uint16_t state;
|
|
|
|
/** quality of communication (FRI_QUALITY) */
|
|
fri_uint16_t quality;
|
|
|
|
/** configured sample time for sent measurment packets */
|
|
fri_float_t desiredMsrSampleTime;
|
|
|
|
/** configured sample time for received command packets */
|
|
fri_float_t desiredCmdSampleTime;
|
|
|
|
/** configured safety limits */
|
|
fri_float_t safetyLimits;
|
|
|
|
/** communication statistics */
|
|
tFriIntfStatistics stat;
|
|
} tFriIntfState;
|
|
#define FRI_INTF_STATE_SIZE (20 + FRI_INTF_STATISTICS_SIZE)
|
|
|
|
|
|
|
|
|
|
/** these are the states that are reported */
|
|
typedef enum
|
|
{
|
|
FRI_STATE_INVALID =-1, /**< State invalid e.g. not initialized */
|
|
FRI_STATE_OFF = 0, /**< internal state only (no active interface) */
|
|
FRI_STATE_MON = 1, /**< FRI is in monitor mode */
|
|
FRI_STATE_CMD = 2 /**< FRI is in command mode */
|
|
} FRI_STATE;
|
|
|
|
|
|
|
|
|
|
/** quality of the connection is classified in four steps */
|
|
typedef enum
|
|
{
|
|
FRI_QUALITY_INVALID =-1, /**< not allowed, since improber initialized */
|
|
FRI_QUALITY_UNACCEPTABLE = 0, /**< commanding is not allowed */
|
|
FRI_QUALITY_BAD = 1, /**< commanding is allowed */
|
|
FRI_QUALITY_OK = 2, /**< commanding is allowed */
|
|
FRI_QUALITY_PERFECT = 3 /**< commanding is allowed */
|
|
} FRI_QUALITY;
|
|
|
|
|
|
|
|
|
|
/** currently active controller */
|
|
typedef enum
|
|
{
|
|
/** only joint position can be commanded */
|
|
FRI_CTRL_POSITION = 1,
|
|
/** joint/cart positions, joint/cart stiffness, joint/cart damping
|
|
and additional TCP F/T can be commanded */
|
|
FRI_CTRL_CART_IMP = 2,
|
|
/** joint positions, stiffness and damping and additional joint
|
|
torques can be commanded */
|
|
FRI_CTRL_JNT_IMP = 3,
|
|
/** for all the other modes... */
|
|
FRI_CTRL_OTHER = 0
|
|
} FRI_CTRL;
|
|
|
|
|
|
|
|
|
|
/** feedback about the robot */
|
|
typedef struct
|
|
{
|
|
/** power state of drives (bitfield) */
|
|
fri_uint16_t power;
|
|
|
|
/** selected control strategy (FRI_CTRL) */
|
|
fri_uint16_t control;
|
|
|
|
/** drive errors (leads to power off) */
|
|
fri_uint16_t error;
|
|
|
|
/** drive warnings */
|
|
fri_uint16_t warning;
|
|
|
|
/** temperature of drives */
|
|
fri_float_t temperature[LBR_MNJ];
|
|
} tFriRobotState;
|
|
#define FRI_ROBOT_STATE_SIZE 36
|
|
|
|
|
|
|
|
|
|
/** current robot data */
|
|
typedef struct
|
|
{
|
|
/** measured joint angles (in rad)
|
|
* KRL: $AXIS_ACT_MSR
|
|
* */
|
|
fri_float_t msrJntPos[LBR_MNJ];
|
|
|
|
/** measured Cartesian frame (in m)
|
|
* KRL: $POS_ACT_MSR
|
|
* Reference: Base and tool are specified by $stiffness.base, $stiffness.tool
|
|
* */
|
|
fri_float_t msrCartPos[FRI_CART_FRM_DIM];
|
|
|
|
/** commanded joint angle (in rad, before FRI)
|
|
* KRL: $AXIS_ACT_CMD
|
|
* */
|
|
fri_float_t cmdJntPos[LBR_MNJ];
|
|
|
|
/** commanded joint offset (in rad, due to FRI) */
|
|
fri_float_t cmdJntPosFriOffset[LBR_MNJ];
|
|
|
|
/** commanded Cartesian frame (in m, before FRI)
|
|
* KRL: $POS_ACT_CMD
|
|
* Reference: Base and tool are specified by $stiffness.base, $stiffness.tool
|
|
* */
|
|
fri_float_t cmdCartPos[FRI_CART_FRM_DIM];
|
|
|
|
/** commanded Cartesian frame (in m, due to FRI) */
|
|
fri_float_t cmdCartPosFriOffset[FRI_CART_FRM_DIM];
|
|
|
|
/** measured joint torque (in Nm)
|
|
* KRL $TORQUE_AXIS_ACT
|
|
* */
|
|
fri_float_t msrJntTrq[LBR_MNJ];
|
|
|
|
/** estimated external torque (in Nm)
|
|
* KRL: $TORQUE_AXIS_EST
|
|
* */
|
|
fri_float_t estExtJntTrq[LBR_MNJ];
|
|
|
|
/** estimated TCP force/torque (N, Nm)
|
|
KRL: $TORQUE_TCP_EST
|
|
- reference frame: $STIFFNESS.TASKFRAME
|
|
- Layout: Fx, Fy, Fz, Tz, Ty, Tx
|
|
*/
|
|
fri_float_t estExtTcpFT[FRI_CART_VEC];
|
|
|
|
/** Jacobian matrix
|
|
* reference frame: $STIFFNESS.TASKFRAME
|
|
* row major (#FRI_CART_VEC x #LBR_MNJ)
|
|
* You should be able to cast it directly into a C-matrix with the layout of
|
|
J[FRI_CART_VEC][LBR_MNJ]
|
|
* Or copy it like
|
|
for ( int i = 0; i < FRI_CART_VEC; i++)
|
|
for ( int j = 0; j < LBR_MNJ; j++)
|
|
J[i][j] = jacobian[i*LBR_MNJ+j]
|
|
* Interpretation of the colums [ _X_ _Y_ _Z_ _RZ_ _RY_ _RX_]
|
|
* The Jacobian is generated by "geometric" reasoning with a corresponding physical
|
|
interpretation of instantaneous angular velocity
|
|
*/
|
|
fri_float_t jacobian[FRI_CART_VEC*LBR_MNJ];
|
|
|
|
/** mass matrix */
|
|
fri_float_t massMatrix[LBR_MNJ*LBR_MNJ];
|
|
|
|
/** gravity (in m/s^2) */
|
|
fri_float_t gravity[LBR_MNJ];
|
|
} tFriRobotData;
|
|
#define FRI_ROBOT_DATA_SIZE (175*4) /**< Binary size of #tFriRobotData */
|
|
|
|
|
|
|
|
/** Identification constant for the structure #tFriMsrData
|
|
Note: This datagram id will be abused for versioning as well */
|
|
#define FRI_DATAGRAM_ID_MSR 0x2006
|
|
/** Data that is sent from the KRC to the external controller.
|
|
The structure is identified by #FRI_DATAGRAM_ID_MSR
|
|
*/
|
|
typedef struct
|
|
{
|
|
/** the header */
|
|
tFriHeader head;
|
|
|
|
/** data from KRL */
|
|
tFriKrlData krl;
|
|
|
|
/** state of interface */
|
|
tFriIntfState intf;
|
|
|
|
/** robot state */
|
|
tFriRobotState robot;
|
|
|
|
/** robot data */
|
|
tFriRobotData data;
|
|
} tFriMsrData;
|
|
#define FRI_MSR_DATA_SIZE (FRI_HEADER_SIZE + FRI_KRL_DATA_SIZE + \
|
|
FRI_INTF_STATE_SIZE + FRI_ROBOT_STATE_SIZE + \
|
|
FRI_ROBOT_DATA_SIZE)
|
|
|
|
|
|
|
|
|
|
/** The bitfield is subject to change, any use of hardcoded constants
|
|
is NOT RECOMMENDED! Use the provided defines instead! */
|
|
#define FRI_CMD_JNTPOS 0x0001
|
|
// Currently not supported #define FRI_CMD_JNTVEL 0x0002
|
|
#define FRI_CMD_JNTTRQ 0x0004
|
|
#define FRI_CMD_JNTSTIFF 0x0010
|
|
#define FRI_CMD_JNTDAMP 0x0020
|
|
|
|
#define FRI_CMD_CARTPOS 0x0100
|
|
//Currently not supported #define FRI_CMD_CARTVEL 0x0200
|
|
#define FRI_CMD_TCPFT 0x0400
|
|
#define FRI_CMD_CARTSTIFF 0x1000
|
|
#define FRI_CMD_CARTDAMP 0x2000
|
|
|
|
|
|
|
|
|
|
/** new robot commands */
|
|
typedef struct
|
|
{
|
|
/** bitfield which selects which commanded values are relevant */
|
|
fri_uint32_t cmdFlags;
|
|
|
|
/** commanded joint angle (in rad)
|
|
#FRI_CMD_JNTPOS
|
|
*/
|
|
fri_float_t jntPos[LBR_MNJ];
|
|
|
|
/** commanded Cartesian frame (in m)
|
|
#FRI_CMD_CARTPOS
|
|
*/
|
|
fri_float_t cartPos[FRI_CART_FRM_DIM];
|
|
|
|
/** commanded additional joint torque (in Nm)
|
|
#FRI_CMD_JNTTRQ*/
|
|
fri_float_t addJntTrq[LBR_MNJ];
|
|
|
|
/** commanded additional TCP force/torque (N, Nm)
|
|
#FRI_CMD_TCPFT
|
|
* reference frame: $STIFFNESS.TASKFRAM
|
|
* Layout [Fx, Fy, Fz, Tz, Ty, Tx]*/
|
|
fri_float_t addTcpFT[FRI_CART_VEC];
|
|
|
|
/** joint stiffness (Nm/rad)
|
|
#FRI_CMD_JNTSTIFF */
|
|
fri_float_t jntStiffness[LBR_MNJ];
|
|
|
|
/** joint damping (normalized)
|
|
#FRI_CMD_JNTDAMP*/
|
|
fri_float_t jntDamping[LBR_MNJ];
|
|
|
|
/** Cartesian stiffness (N/m, Nm/rad)
|
|
* #FRI_CMD_CARTSTIFF
|
|
* Layout [Cx, Cy, Cz, Ca(Rz), Cb(Ry), Cc(Rx)]*/
|
|
fri_float_t cartStiffness[FRI_CART_VEC];
|
|
|
|
/** Cartesian damping (normalized)
|
|
* #FRI_CMD_CARTDAMP
|
|
* Layout [Dx, Dy, Dz, Da(Rz), Db(Ry), Dc(Rx)]*/
|
|
fri_float_t cartDamping[FRI_CART_VEC];
|
|
} tFriRobotCommand;
|
|
#define FRI_ROBOT_COMMAND_SIZE (59*4)
|
|
|
|
|
|
|
|
/** Symbolic define to identify #tFriCmdData
|
|
Note: This datagram id will be abused for versioning as well */
|
|
#define FRI_DATAGRAM_ID_CMD 0x1005
|
|
/** The commanding structure, which is sent to the KRC Side.
|
|
Identified by #FRI_DATAGRAM_ID_CMD */
|
|
typedef struct
|
|
{
|
|
/** the header */
|
|
tFriHeader head;
|
|
|
|
/** data to KRL */
|
|
tFriKrlData krl;
|
|
|
|
/** robot commands */
|
|
tFriRobotCommand cmd;
|
|
} tFriCmdData;
|
|
#define FRI_CMD_DATA_SIZE (FRI_HEADER_SIZE + FRI_KRL_DATA_SIZE + FRI_ROBOT_COMMAND_SIZE)
|
|
|
|
|
|
|
|
|
|
/** a convenience macro for the user to check if padding on the used
|
|
platform is as expected: if (!FRI_CHECK_SIZES_OK) ... */
|
|
#define FRI_CHECK_SIZES_OK \
|
|
((sizeof(tFriHeader) == FRI_HEADER_SIZE) && \
|
|
(sizeof(tFriKrlData) == FRI_KRL_DATA_SIZE) && \
|
|
(sizeof(tFriIntfStatistics) == FRI_INTF_STATISTICS_SIZE) && \
|
|
(sizeof(tFriIntfState) == FRI_INTF_STATE_SIZE) && \
|
|
(sizeof(tFriRobotState) == FRI_ROBOT_STATE_SIZE) && \
|
|
(sizeof(tFriRobotData) == FRI_ROBOT_DATA_SIZE) && \
|
|
(sizeof(tFriRobotCommand) == FRI_ROBOT_COMMAND_SIZE) && \
|
|
(sizeof(tFriMsrData) == FRI_MSR_DATA_SIZE) && \
|
|
(sizeof(tFriCmdData) == FRI_CMD_DATA_SIZE))
|
|
|
|
|
|
|
|
|
|
/** convenience macros for the user to check if byte order and float
|
|
representation on the used platform is as expected:
|
|
{
|
|
FRI_PREPARE_CHECK_BYTE_ORDER
|
|
if (!FRI_CHECK_BYTE_ORDER_OK) ...
|
|
}*/
|
|
#define FRI_PREPARE_CHECK_BYTE_ORDER \
|
|
union {fri_uint32_t a; fri_uint8_t b[4]; fri_float_t c;} _friTestByteOrder; \
|
|
_friTestByteOrder.a = 0x40490FDB;
|
|
/** convenience macros for the user to check if byte order and float
|
|
representation on the used platform is as expected:
|
|
{
|
|
FRI_PREPARE_CHECK_BYTE_ORDER
|
|
if (!FRI_CHECK_BYTE_ORDER_OK) ...
|
|
}*/
|
|
#define FRI_CHECK_BYTE_ORDER_OK \
|
|
((_friTestByteOrder.a == 0x40490FDB) &&\
|
|
(_friTestByteOrder.b[0] == 0xDB) &&\
|
|
(_friTestByteOrder.b[1] == 0x0F) &&\
|
|
(_friTestByteOrder.b[2] == 0x49) &&\
|
|
(_friTestByteOrder.b[3] == 0x40) &&\
|
|
(_friTestByteOrder.c > 3.141592) &&\
|
|
(_friTestByteOrder.c < 3.141593))
|
|
|
|
|
|
/**! Versioning Major Version */
|
|
#define FRI_MAJOR_VERSION 1
|
|
/**! Versioning Minor sub version for minor fixes */
|
|
#define FRI_SUB_VERSION 0
|
|
#define EXPAND_CONCAT(X1,X2,X3,X4,X5,X6,X7) X1 ## X2 ## X3 ## X4 ## X5 ## X6 ## X7
|
|
#define CONCAT(name1,name2,name3,name4) EXPAND_CONCAT(#name1,".",#name2,".",#name3,".",#name4)
|
|
|
|
/**! The Versionstring with all significant information */
|
|
#define FRI_VERSION_STRING CONCAT(FRI_MAJOR_VERSION, FRI_SUB_VERSION,FRI_DATAGRAM_ID_CMD,FRI_DATAGRAM_ID_MSR)
|
|
//"." #F "." #FRI_DATAGRAM_ID_MSR
|
|
|
|
#endif /* FRICOMM_H */
|