commit
						4f33861787
					
				 35 changed files with 6645 additions and 0 deletions
			
			
		- 
					82lwrserv/Makefile
- 
					14lwrserv/Point.h
- 
					417lwrserv/SocketObject.cpp
- 
					172lwrserv/SocketObject.h
- 
					36lwrserv/StringTool.cpp
- 
					13lwrserv/StringTool.h
- 
					1079lwrserv/SvrHandling.cpp
- 
					61lwrserv/SvrHandling.h
- 
					38lwrserv/defines.h
- 
					504lwrserv/friComm.h
- 
					288lwrserv/friremote.cpp
- 
					194lwrserv/friremote.h
- 
					543lwrserv/friudp.cpp
- 
					257lwrserv/friudp.h
- 
					36lwrserv/global.cpp
- 
					32lwrserv/global.h
- 
					24lwrserv/header.h
- 
					BINlwrserv/include/libblas.dll
- 
					BINlwrserv/include/libblas.lib
- 
					BINlwrserv/include/liblapack.dll
- 
					BINlwrserv/include/liblapack.lib
- 
					354lwrserv/mat.h
- 
					520lwrserv/program.cpp
- 
					1368lwrserv/pthread/pthread.h
- 
					BINlwrserv/pthread/pthreadVC2.dll
- 
					BINlwrserv/pthread/pthreadVC2.lib
- 
					BINlwrserv/pthread/pthreadVCE2.dll
- 
					BINlwrserv/pthread/pthreadVCE2.lib
- 
					BINlwrserv/pthread/pthreadVSE2.dll
- 
					BINlwrserv/pthread/pthreadVSE2.lib
- 
					183lwrserv/pthread/sched.h
- 
					169lwrserv/pthread/semaphore.h
- 
					14lwrserv/resource.h
- 
					13lwrserv/sgn.h
- 
					234lwrserv/vec.h
| @ -0,0 +1,82 @@ | |||||
|  | ################################################################################
 | ||||
|  | # Contents: makefile with dependency generation                                #
 | ||||
|  | #           26.05.2015                                                         #
 | ||||
|  | #------------------------------------------------------------------------------#
 | ||||
|  | #           makefile for cpp/c bins and libs                                   #
 | ||||
|  | #           autor Philipp Schoenberger                                         #
 | ||||
|  | #           ph.schoenberger@googlemail.com                                     #
 | ||||
|  | ################################################################################
 | ||||
|  | LIBS = pthread | ||||
|  | 
 | ||||
|  | OUT_BINARY = lwrserv | ||||
|  | 
 | ||||
|  | CC = g++ | ||||
|  | GLOBAL_FLAGS = -g -o2 -ansi -pedantic -DHAVE_SOCKLEN_T | ||||
|  | CFLAGS   = $(GLOBAL_FLAGS) | ||||
|  | CXXFLAGS = $(GLOBAL_FLAGS) | ||||
|  | CPPFLAGS = $(GLOBAL_FLAGS)  | ||||
|  | LDFLAGS = $(patsubst %,-l%,$(LIBS))  | ||||
|  | 
 | ||||
|  | BUILD_DIR = build | ||||
|  | 
 | ||||
|  | # Sources
 | ||||
|  | SRC_C   := $(wildcard *.c) | ||||
|  | SRC_H   := $(wildcard *.h) | ||||
|  | SRC_CPP  := $(wildcard *.cpp) | ||||
|  | SRC_HPP  := $(wildcard *.hpp) | ||||
|  | #SRC_CXX := $(wildcard *.cxx)
 | ||||
|  | #SRC_CC  := $(wildcard *.C)
 | ||||
|  | 
 | ||||
|  | # Objects
 | ||||
|  | OBJS_C = $(patsubst %.c,$(BUILD_DIR)/%.o,$(SRC_C)) | ||||
|  | OBJS_CPP = $(patsubst %.cpp,$(BUILD_DIR)/%.o,$(SRC_CPP)) | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | OBJS=$(patsubst %.o,%.o,$(OBJS_C) $(OBJS_CPP)) | ||||
|  | 
 | ||||
|  | # Dependencies
 | ||||
|  | DEPS_H = $(patsubst %.h,$(BUILD_DIR)/%.d,$(SRC_H)) | ||||
|  | DEPS_HPP = $(patsubst %.hpp,$(BUILD_DIR)/%.d,$(SRC_HPP)) | ||||
|  | 
 | ||||
|  | DEPS=$(OBJS:%.o=%.d) | ||||
|  | #DEPS+=$(DEPS_H)
 | ||||
|  | #DEPS+=$(DEPS_HPP)
 | ||||
|  | 
 | ||||
|  | .DEFAULT: all | ||||
|  | Q=@ | ||||
|  | 
 | ||||
|  | all: $(BUILD_DIR) $(BUILD_DIR)/$(OUT_BINARY) | ||||
|  | 
 | ||||
|  | $(BUILD_DIR): | ||||
|  | 	$(Q)echo " [mk] $(BUILD_DIR)" | ||||
|  | 	$(Q)mkdir -p $(BUILD_DIR) | ||||
|  | 
 | ||||
|  | clean: | ||||
|  | 	$(Q)echo " [rm] $(BUILD_DIR)" | ||||
|  | 	$(Q)rm -rf $(BUILD_DIR) | ||||
|  | 
 | ||||
|  | $(BUILD_DIR)/$(OUT_BINARY): $(BUILD_DIR) $(DEPS) $(DEP_LIBS) $(OBJS) | ||||
|  | 	$(Q)echo " [ld] $@" | ||||
|  | 	$(Q)( $(CC)  $(CFLAGS) $(OBJS) $(LDFLAGS)  -o $(OUT_BINARY)) || exit 1 | ||||
|  | 
 | ||||
|  | $(BUILD_DIR)/%.o : %.c $(BUILD_DIR) | ||||
|  | 	$(Q)echo " [CC] $@" | ||||
|  | 	$(Q)( $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ ) || exit 1 | ||||
|  | 
 | ||||
|  | $(BUILD_DIR)/%.o : %.cpp $(BUILD_DIR) | ||||
|  | 	$(Q)echo " [CXX] $@" | ||||
|  | 	$(Q)( $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $< -o $@ ) || exit 1 | ||||
|  | 
 | ||||
|  | $(BUILD_DIR)/%.d: $(BUILD_DIR) %.c  | ||||
|  | 	$(Q)echo " [DEP] $@" | ||||
|  | 	$(Q)touch $@ | ||||
|  | 	$(Q)echo -n "$@ $(patsubst %.d,%.o,$@):" >$@ | ||||
|  | 	$(Q)$(CC) -M $(CFLAGS) $(filter %.cpp,$^ ) | sed 's:$*.o\:::' >> $@ | ||||
|  | 
 | ||||
|  | $(BUILD_DIR)/%.d: $(BUILD_DIR) %.cpp  | ||||
|  | 	$(Q)echo " [DEP] $@" | ||||
|  | 	$(Q)touch $@ | ||||
|  | 	$(Q)echo -n "$@ $(patsubst %.d,%.o,$@):" >$@ | ||||
|  | 	$(Q)$(CC) -M $(filter-out -g -o0 -o1 -o2 ,$(CPPFLAGS)) $(filter %.cpp,$^) | sed 's:$*.o\:::' >> $@ | ||||
|  | 
 | ||||
|  | -include $(DEPS) | ||||
| @ -0,0 +1,14 @@ | |||||
|  | #ifndef POINT_H | ||||
|  | #define POINT_H | ||||
|  | 
 | ||||
|  | class Point { | ||||
|  | public: | ||||
|  | 
 | ||||
|  |    Point (int x=0, int y=0) { | ||||
|  |       this->x = x; | ||||
|  |       this->y = y; | ||||
|  |    } | ||||
|  | 
 | ||||
|  |    int x, y; | ||||
|  | }; | ||||
|  | #endif // POINT_H | ||||
| @ -0,0 +1,417 @@ | |||||
|  | #include "SocketObject.h"
 | ||||
|  | 
 | ||||
|  | #include <stdio.h>
 | ||||
|  | #include <stdlib.h>
 | ||||
|  | #include <string.h>
 | ||||
|  | #include <iostream>
 | ||||
|  | #include <cerrno>
 | ||||
|  | #include <iomanip>
 | ||||
|  | 
 | ||||
|  | using namespace std; | ||||
|  | 
 | ||||
|  | #if defined(__msdos__) || defined(WIN32)
 | ||||
|  | SocketObject::SocketObject(void) | ||||
|  | { | ||||
|  | #ifdef __SOCKET_OBJECT_DEBUG
 | ||||
|  |     cout << "Windows SocketObject Konstruktor" << endl; | ||||
|  | #endif
 | ||||
|  |     WSADATA wsaData; | ||||
|  |     WORD wVersionRequested; | ||||
|  | 
 | ||||
|  |     wVersionRequested = MAKEWORD( 2, 0 ); | ||||
|  |     _skSocket = INVALID_SOCKET; | ||||
|  |     WSAStartup(wVersionRequested, &wsaData); | ||||
|  | } | ||||
|  | 
 | ||||
|  | SocketObject::SocketObject(SocketObject& sk) | ||||
|  | { | ||||
|  |     WSADATA wsaData; | ||||
|  |     WORD    wVersionRequested; | ||||
|  | 
 | ||||
|  |     wVersionRequested = MAKEWORD( 2, 0 ); | ||||
|  |     _skSocket = sk._skSocket; | ||||
|  |     sk._skSocket = INVALID_SOCKET; | ||||
|  |     WSAStartup(wVersionRequested, &wsaData); | ||||
|  | } | ||||
|  | 
 | ||||
|  | SocketObject::~SocketObject(void) | ||||
|  | { | ||||
|  |     Disconnect(); | ||||
|  | } | ||||
|  | #endif
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | void SocketObject::setBlockingMode(bool nonblock) | ||||
|  | { | ||||
|  |     int errorCode = 0; | ||||
|  | #if defined(__msdos__) || defined(WIN32)
 | ||||
|  |     u_long iMode = 1; | ||||
|  | 
 | ||||
|  |     if (!nonblock) | ||||
|  |         iMode=0; | ||||
|  | 
 | ||||
|  |     if (0 != ioctlsocket(_skSocket, FIONBIO, &iMode)) | ||||
|  |     { | ||||
|  |         errorCode = WSAGetLastError(); | ||||
|  |         cout << "Set blocking mode ("<<iMode<<") failed! Errorcode "<< errorCode; | ||||
|  |     } | ||||
|  | #else
 | ||||
|  |     //CHANGED: Use the boolean value
 | ||||
|  |     if (nonblock) | ||||
|  |         fcntl(_skSocket, F_SETFL, O_NONBLOCK); | ||||
|  | #endif
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | int SocketObject::Bind(unsigned short int iPort) | ||||
|  | { | ||||
|  | #if defined(__msdos__) || defined(WIN32)
 | ||||
|  | 
 | ||||
|  |     struct sockaddr_in      saServerAddress; | ||||
|  |     // TCP-Socket erschaffen
 | ||||
|  |     _skSocket = socket(AF_INET, SOCK_STREAM, 0); | ||||
|  |     if (_skSocket == INVALID_SOCKET)  | ||||
|  |     { | ||||
|  | #ifdef __SOCKET_OBJECT_DEBUG
 | ||||
|  |         cout << "SocketObject::Bind(): INVALID SOCKET" << endl; | ||||
|  | #endif
 | ||||
|  |         return 0; | ||||
|  |     } | ||||
|  |     // serverAdress wählen
 | ||||
|  |     memset(&saServerAddress, 0, sizeof(sockaddr_in)); | ||||
|  |     saServerAddress.sin_family = AF_INET; | ||||
|  |     saServerAddress.sin_addr.s_addr = htonl(INADDR_ANY); | ||||
|  |     saServerAddress.sin_port = htons(iPort); | ||||
|  | 
 | ||||
|  |     if ( bind(_skSocket, (sockaddr*)&saServerAddress, sizeof(sockaddr))== SOCKET_ERROR) | ||||
|  |     { | ||||
|  |         Disconnect(); | ||||
|  |         return -1; | ||||
|  |     } else  | ||||
|  |     { | ||||
|  | #ifdef __SOCKET_OBJECT_DEBUG
 | ||||
|  |         cout << "SocketObject::Bind(): Alles ok" << endl; | ||||
|  | #endif
 | ||||
|  |         return 0; | ||||
|  |     } | ||||
|  | 
 | ||||
|  | #else
 | ||||
|  | 
 | ||||
|  |     struct sockaddr_in  saServerAddress; | ||||
|  | 
 | ||||
|  | #ifdef __SOCKET_OBJECT_DEBUG
 | ||||
|  |     std::cout << "Port: " << iPort << endl; | ||||
|  | #endif
 | ||||
|  | 
 | ||||
|  |     // Socket erschaffen
 | ||||
|  |     _skSocket = socket(AF_INET, SOCK_STREAM, 0);             | ||||
|  |     if (_skSocket < 0)  | ||||
|  |     { | ||||
|  | #ifdef __SOCKET_OBJECT_DEBUG
 | ||||
|  |         std::cout << "Fehler bei Bind - socket()" << std::endl; | ||||
|  | #endif
 | ||||
|  |         return -1; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     const int y = 1; | ||||
|  |     /* Socketoptionen fuer schnelles Verbinden setzen*/ | ||||
|  |     setsockopt(_skSocket, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int)); | ||||
|  | 
 | ||||
|  |     /* Initialisieren der aockaddr_in - structure */ | ||||
|  |     // Server-Adresse mit 0 vorbelegen
 | ||||
|  |     memset(&saServerAddress, 0, sizeof(struct sockaddr_in));     | ||||
|  |     // Domain
 | ||||
|  |     saServerAddress.sin_family = AF_INET;                | ||||
|  |     // Addresse
 | ||||
|  |     saServerAddress.sin_addr.s_addr =  INADDR_ANY; | ||||
|  |     // Port
 | ||||
|  |     saServerAddress.sin_port = htons( iPort );       | ||||
|  | 
 | ||||
|  |     // Versuch Socket an Port zu binden
 | ||||
|  |     if (0 > bind(_skSocket, (sockaddr*) &saServerAddress, sizeof(sockaddr))) | ||||
|  |     {    | ||||
|  |         // Socket will nicht mehr lesen und schreiben
 | ||||
|  |         shutdown(_skSocket,2);           | ||||
|  | #ifdef __SOCKET_OBJECT_DEBUG
 | ||||
|  |         std::cout << "Fehler bei Bind!" << std::endl; | ||||
|  | #endif
 | ||||
|  |         return -1; | ||||
|  |     } else  | ||||
|  |     { | ||||
|  |         return 0; | ||||
|  |     } | ||||
|  | #endif
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | int SocketObject::Listen( void ) | ||||
|  | { | ||||
|  |     // lauscht bei _skSocket, max Warteschlange = 2
 | ||||
|  |     return listen(_skSocket, 2);     | ||||
|  | // WIN32 : ,32
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | bool SocketObject::Accept(SocketObject &skAcceptSocket) | ||||
|  | { | ||||
|  |     struct sockaddr_in  saClientAddress; | ||||
|  |     int    iClientSize = sizeof(sockaddr_in); | ||||
|  | 
 | ||||
|  | #if defined(__msdos__) || defined(WIN32)
 | ||||
|  | 
 | ||||
|  |     skAcceptSocket._skSocket = accept(_skSocket, (struct sockaddr*)&saClientAddress, &iClientSize); | ||||
|  |     return !( skAcceptSocket._skSocket == INVALID_SOCKET); | ||||
|  | 
 | ||||
|  | #else
 | ||||
|  | 
 | ||||
|  |     skAcceptSocket._skSocket = accept( _skSocket, (sockaddr*) &saClientAddress,(socklen_t*) &iClientSize); | ||||
|  |     return !( skAcceptSocket._skSocket == -1); | ||||
|  | 
 | ||||
|  | #endif
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | bool SocketObject::Connect(const char* szServerAddress, unsigned short int iPort, bool nonblock) | ||||
|  | { | ||||
|  | #if defined(__msdos__) || defined(WIN32)
 | ||||
|  | 
 | ||||
|  |     struct sockaddr_in server_addr; | ||||
|  |     LPHOSTENT          lpHost; | ||||
|  |     int                error; | ||||
|  | 
 | ||||
|  |     // Open the socket
 | ||||
|  |     _skSocket = socket(AF_INET, SOCK_STREAM, 0); | ||||
|  |     if (_skSocket == INVALID_SOCKET) | ||||
|  |         return false; | ||||
|  | 
 | ||||
|  |     u_long iMode = 0; | ||||
|  |     if (nonblock) | ||||
|  |         iMode = 1; | ||||
|  |     ioctlsocket(_skSocket, FIONBIO, &iMode); | ||||
|  | 
 | ||||
|  |     memset(&server_addr,0,sizeof(struct sockaddr_in)); | ||||
|  |     server_addr.sin_family = AF_INET; | ||||
|  |     server_addr.sin_addr.s_addr = inet_addr(szServerAddress); | ||||
|  | 
 | ||||
|  |     if (server_addr.sin_addr.s_addr == INADDR_NONE) | ||||
|  |     { | ||||
|  |         lpHost = gethostbyname(szServerAddress); | ||||
|  |         if (lpHost != NULL)  | ||||
|  |         { | ||||
|  |             server_addr.sin_addr.s_addr = ((LPIN_ADDR)lpHost->h_addr)->s_addr; | ||||
|  |         } | ||||
|  |         else | ||||
|  |             return false; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     server_addr.sin_port = htons(iPort); | ||||
|  |     error = connect(_skSocket, (struct sockaddr*)&server_addr, sizeof(sockaddr)); | ||||
|  |     if (error == SOCKET_ERROR) | ||||
|  |     { | ||||
|  |         Disconnect(); | ||||
|  |         return false; | ||||
|  |     } | ||||
|  |     return true; | ||||
|  | 
 | ||||
|  | #else
 | ||||
|  | 
 | ||||
|  |     struct sockaddr_in      server_addr; | ||||
|  |     int             status; | ||||
|  | 
 | ||||
|  |     // Socket erschaffen
 | ||||
|  |     _skSocket = socket(AF_INET, SOCK_STREAM, 0); | ||||
|  |     if (_skSocket < 0) | ||||
|  |         return false; | ||||
|  | 
 | ||||
|  |     if (nonblock) | ||||
|  |         fcntl(_skSocket, F_SETFL, O_NONBLOCK); | ||||
|  | 
 | ||||
|  |     // Initilisieren der sockaddr_in- Struktur
 | ||||
|  |     memset(&server_addr, 0, sizeof(struct sockaddr_in)); | ||||
|  |     server_addr.sin_family = AF_INET; | ||||
|  |     // server-Adresse bergeben
 | ||||
|  |     server_addr.sin_addr.s_addr = inet_addr(szServerAddress); | ||||
|  |     // std::cout << inet_ntoa (server_addr.sin_addr)<< std::endl;
 | ||||
|  |     // Port
 | ||||
|  |     server_addr.sin_port = htons(iPort); | ||||
|  | 
 | ||||
|  |     // Verbindung herstellen
 | ||||
|  |     status = connect(_skSocket, (struct sockaddr*)&server_addr, sizeof(sockaddr)); | ||||
|  | 
 | ||||
|  |     if (status < 0) | ||||
|  |     { | ||||
|  |         shutdown(_skSocket,2); | ||||
|  |         return false; | ||||
|  |     } | ||||
|  |     return true; | ||||
|  | 
 | ||||
|  | #endif
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | bool SocketObject::Connect(const string szServerAddress, unsigned short int iPort, bool nonblock) | ||||
|  | { | ||||
|  |     return Connect((char*) szServerAddress.c_str(), iPort, nonblock); | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | void SocketObject::Disconnect() | ||||
|  | { | ||||
|  | #if defined(__msdos__) || defined(WIN32)
 | ||||
|  |     if (_skSocket != INVALID_SOCKET) | ||||
|  |     { | ||||
|  |         closesocket(_skSocket); | ||||
|  |         _skSocket = INVALID_SOCKET; | ||||
|  |     } | ||||
|  | #else
 | ||||
|  |     close(_skSocket); | ||||
|  | #endif
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | int SocketObject::Recv(char *szBuffer, int iBufferLength, int iFlags) | ||||
|  | { | ||||
|  |     return recv(_skSocket, szBuffer, iBufferLength, iFlags); | ||||
|  | } | ||||
|  | 
 | ||||
|  | int SocketObject::Recv (string& s) | ||||
|  | { | ||||
|  |     char buf [MAXRECV+1]; | ||||
|  |     // cout << WSAGetLastError() << " in SocketObject::Recv, vor recv" << endl;
 | ||||
|  |     s = ""; | ||||
|  |     memset(buf, 0, MAXRECV+1); | ||||
|  |     int status = Recv(buf, MAXRECV, 0); | ||||
|  | 
 | ||||
|  |     switch (status)  | ||||
|  |     { | ||||
|  |         case -1: | ||||
|  | #ifdef __SOCKET_OBJECT_DEBUG
 | ||||
|  |       cout << "status: -1  errno: " << errno << " in SocketObject::Recv" << endl; | ||||
|  | #endif
 | ||||
|  |             break; | ||||
|  |         case 0: | ||||
|  |             break; | ||||
|  | 
 | ||||
|  |         default: | ||||
|  |             s = buf; | ||||
|  |             // strip the (expected) CRLF
 | ||||
|  |             if(s.length() == 1)  | ||||
|  |             { | ||||
|  |                 if(s[s.length()-1]=='\n' || s[s.length()-1]=='\r') | ||||
|  |                     s.resize(s.length()-1); | ||||
|  |             } else if(s.length() >= 2)  | ||||
|  |             { | ||||
|  |                 if(s[s.length()-1]=='\n' && s[s.length()-2]=='\r') | ||||
|  |                     s.resize(s.length()-2); | ||||
|  |                 else if(s[s.length()-1]=='\n' || s[s.length()-1]=='\r') | ||||
|  |                     s.resize(s.length()-1); | ||||
|  |             } | ||||
|  |             break; | ||||
|  |     } | ||||
|  |     return status; | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | int SocketObject::receiveLine(char* array, int arraySize) | ||||
|  | { | ||||
|  |     //std::string ret;
 | ||||
|  |     char r; | ||||
|  |     int pos = 0; | ||||
|  | 
 | ||||
|  |     while (pos<arraySize-2) | ||||
|  |     { | ||||
|  |         switch(recv(_skSocket, &r, 1, 0)) | ||||
|  |         { | ||||
|  |             case 0: // not connected anymore;
 | ||||
|  |                 return 0; | ||||
|  |             case -1: | ||||
|  |                 return -1; | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         // check for carriage return or line feed (MAC: CR, Linux: LF, Windows: CRLF)
 | ||||
|  |         if ((r == char(13)) || (r == char(10))) | ||||
|  |         { | ||||
|  |             if (pos > 0) | ||||
|  |             { | ||||
|  |                 array[pos]='\0'; | ||||
|  |                 return pos; | ||||
|  |             } | ||||
|  |         }else | ||||
|  |         { | ||||
|  |             array[pos] = r; | ||||
|  |             pos++; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     return pos; | ||||
|  | } | ||||
|  | 
 | ||||
|  | std::string SocketObject::receiveLine() | ||||
|  | { | ||||
|  |     std::string ret; | ||||
|  |     char r; | ||||
|  | 
 | ||||
|  |     while (1) | ||||
|  |     { | ||||
|  |         //This will not work under windows if the blocking mode is non-blocking
 | ||||
|  |         // -1 will indicate that there is no value, it is not an error !!!
 | ||||
|  |         //http://msdn.microsoft.com/en-us/library/ms740121(VS.85).aspx
 | ||||
|  |         //For linux see:
 | ||||
|  |         //http://linux.about.com/library/cmd/blcmdl2_recv.htm
 | ||||
|  |         //If no messages are available at the socket, the receive calls wait for a message to arrive,
 | ||||
|  |         //unless the socket is nonblocking (see fcntl(2)) in which case the value -1 is returned and
 | ||||
|  |         // the external variable errno set to EAGAIN.
 | ||||
|  |         switch(recv(_skSocket, &r, 1, 0)) | ||||
|  |         { | ||||
|  |             case 0: // not connected anymore;
 | ||||
|  |                 return SOCKETOBJECT_NOT_CONNECTED; | ||||
|  |             case -1: // error
 | ||||
|  |                 return SOCKETOBJECT_RECV_ERROR; | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         // check for carriage return or line feed (MAC: CR, Linux: LF, Windows: CRLF)
 | ||||
|  |         if ((r == char(13)) || (r == char(10))) | ||||
|  |         { | ||||
|  |             if (ret.length() > 0) | ||||
|  |                 return ret; | ||||
|  |         } else | ||||
|  |         { | ||||
|  |             ret += r; | ||||
|  |         } | ||||
|  |     } | ||||
|  | } | ||||
|  | 
 | ||||
|  | int SocketObject::Send(const char *szBuffer, int iBufferLength, int iFlags)  | ||||
|  | { | ||||
|  |     return send(_skSocket,szBuffer,iBufferLength, iFlags); | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | int SocketObject::Send (const string s) | ||||
|  | { | ||||
|  |     string str = s; | ||||
|  |     // add the (expected) CRLF
 | ||||
|  |     if(str == "")  | ||||
|  |     { | ||||
|  |         str = "\n\r"; | ||||
|  |     } else if(str.size() == 1)  | ||||
|  |     { | ||||
|  |         if(str[0] == '\r')  | ||||
|  |         { | ||||
|  |             str = "\n\r"; | ||||
|  |         } else if(str[0] != '\n')  | ||||
|  |         { | ||||
|  |             str += "\n\r"; | ||||
|  |         } | ||||
|  |     } else if(str.size() >= 2)  | ||||
|  |     { | ||||
|  |         if(str[str.length()-1] != '\n' || str[str.length()-2]!='\r') | ||||
|  |         { | ||||
|  |             str += "\n\r"; | ||||
|  |         } | ||||
|  |     } | ||||
|  | #if defined(__msdos__) || defined(WIN32)
 | ||||
|  |     return Send((char*) str.c_str(), (int) str.size(), 0); | ||||
|  | #else
 | ||||
|  |     return Send((char*) str.c_str(), (int) str.size(), (int) MSG_NOSIGNAL); | ||||
|  | #endif
 | ||||
|  | } | ||||
|  | 
 | ||||
| @ -0,0 +1,172 @@ | |||||
|  | /** \class  SocketObject | ||||
|  | * | ||||
|  | *   \brief  Die Klasse SocketObject kapselt die Verwendung von Sockets | ||||
|  | * | ||||
|  | *   Die Klasse SocketObject liefert eine komfortable Benutzungs-Schnittstelle | ||||
|  | *   für Sockets. | ||||
|  | *   Sie bietet Methoden zum Senden und Empfangen von verschiedenen Datentypen, | ||||
|  | *   sowie Methoden zum Verbindungsauf- und abbau. | ||||
|  | */ | ||||
|  | #ifndef _SOCKETOBJECT_H | ||||
|  | #define _SOCKETOBJECT_H | ||||
|  | 
 | ||||
|  | #if (defined(__msdos__) || defined(WIN32)) | ||||
|  | #include <winsock.h> | ||||
|  | #else | ||||
|  | #include <sys/types.h> | ||||
|  | #include <sys/socket.h> | ||||
|  | #include <netinet/in.h> | ||||
|  | #include <arpa/inet.h> | ||||
|  | #include <netdb.h> | ||||
|  | #include <fcntl.h> | ||||
|  | #include <unistd.h> | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | #include <string> | ||||
|  | #include <sstream> | ||||
|  | #include <vector> | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | #define SOCKETOBJECT_NOT_CONNECTED "SOCKETOBJECT_NOT_CONNECTED" | ||||
|  | #define SOCKETOBJECT_RECV_ERROR "SOCKETOBJECT_RECV_ERROR" | ||||
|  | 
 | ||||
|  | class SocketObject { | ||||
|  | 
 | ||||
|  | public: | ||||
|  | 
 | ||||
|  |     static const int MAXRECV = 1024; | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | private: | ||||
|  | 
 | ||||
|  | #if defined(__msdos__) || defined(WIN32) | ||||
|  |     SOCKET  _skSocket; | ||||
|  | #else | ||||
|  |     int _skSocket; | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | public: | ||||
|  | 
 | ||||
|  | #if defined(__msdos__) || defined(WIN32) | ||||
|  |     //  Konstruktor der Klasse | ||||
|  |     SocketObject(); | ||||
|  | 
 | ||||
|  |     // Copy-Konstruktor | ||||
|  |     SocketObject(SocketObject& sk); | ||||
|  | 
 | ||||
|  |     //  Destruktor der Klasse | ||||
|  |     ~SocketObject(); | ||||
|  | #endif | ||||
|  | 
 | ||||
|  |     /******     NUR SERVER - METHODEN       ******/ | ||||
|  | 
 | ||||
|  |     /** \brief  Bindet Socket an einen Port | ||||
|  |     * | ||||
|  |     *   Die bind()-Methdode gibt dem Socket einen | ||||
|  |     *   lokalen Namen, damit andere Prozesse mit | ||||
|  |     *   ihm kommunizieren können. | ||||
|  |     *   Wird <b>nur vom Server</b> benutzt! | ||||
|  |     * | ||||
|  |     *   @param  iPort   Port an den gebunden werden soll | ||||
|  |     * | ||||
|  |     *   @return 0 = ok, SOCKET_ERROR    = Fehler | ||||
|  |     * | ||||
|  |     */ | ||||
|  |     int Bind(unsigned short int iPort); | ||||
|  | 
 | ||||
|  |     /** \brief  Wartet auf eigehende Verbindungsanfragen | ||||
|  |     * | ||||
|  |     *   Die Listen()-Methode erwartet eingehende | ||||
|  |     *   Verbindungsanfragen. | ||||
|  |     *   Wird <b>nur vom Server</b> benutzt! | ||||
|  |     * | ||||
|  |     *   @return 0 = ok, SOCKET_ERROR = Fehler | ||||
|  |     * | ||||
|  |     */ | ||||
|  |     int Listen(); | ||||
|  | 
 | ||||
|  |     /** \brief  Acceptiert eingehende Verbindungsanfrage | ||||
|  |     * | ||||
|  |     *   Die accept()-Methode akzeptiert eine eingehende | ||||
|  |     *   Verbindung und "startet" die Verbindung" | ||||
|  |     *   Wird <b>nur vom Server</b> benutzt! | ||||
|  |     * | ||||
|  |     *   @param   skAcceptSocket  zu akzeptierender Socket | ||||
|  |     */ | ||||
|  |     bool Accept(SocketObject &skAcceptSocket); | ||||
|  | 
 | ||||
|  |     /******     SERVER - METHODEN  ENDE     ******/ | ||||
|  | 
 | ||||
|  |     /******     NUR CLIENT - METHODEN       ******/ | ||||
|  |     /** \brief  Stellt Verbindsanfage an den Server | ||||
|  |     * | ||||
|  |     *   Mittels der connect()-Methode stellt der Client | ||||
|  |     *   eine Verbindungsanfrage an den Server her, der | ||||
|  |     * | ||||
|  |     * | ||||
|  |     *   Wird <b>nur vom Client</b> benutzt! | ||||
|  |     * | ||||
|  |     *   @param  szServerAdrress Adresse des Servers | ||||
|  |     *   @param  iPort   Port des Server | ||||
|  |     */ | ||||
|  |     bool Connect(const char *szServerAddress, unsigned short int iPort, bool nonblock); | ||||
|  | 
 | ||||
|  |     /** \brief  Stellt Verbindsanfage an den Server | ||||
|  |     * | ||||
|  |     *   Mittels der connect()-Methode stellt der Client | ||||
|  |     *   eine Verbindungsanfrage an den Server her, der | ||||
|  |     *   Die IP wird hier als String übergeben | ||||
|  |     *   Wird <b>nur vom Client</b> benutzt! | ||||
|  |     * | ||||
|  |     *   @param  ServerAdrress Adresse des Servers | ||||
|  |     *   @param  iPort   Port des Server | ||||
|  |     */ | ||||
|  |     bool Connect(const std::string ServerAddress, unsigned short int iPort, bool nonblock = false); | ||||
|  | 
 | ||||
|  |     void setBlockingMode(bool nonblock); | ||||
|  | 
 | ||||
|  |     std::string receiveLine(); | ||||
|  |     int receiveLine(char* array, int arraySize); | ||||
|  | 
 | ||||
|  |     /******     CLIENT - METHODEN   ENDE    ******/ | ||||
|  |     /** | ||||
|  |     *   Die send()-Methode sendet Daten an den verbundenen | ||||
|  |     *   Socket | ||||
|  |     * | ||||
|  |     *   @param szBuffer     zu sendende Nachricht | ||||
|  |     *   @param iBufferLength    Läge der Nachricht | ||||
|  |     *   @param iFlags       Flags | ||||
|  |     * | ||||
|  |     *   @return Anzahl der gesendeten Bytes | ||||
|  |     */ | ||||
|  |     int Send(const char *szBuffer, int iBufferLength, int iFlags); | ||||
|  | 
 | ||||
|  |     /** \brief  Senden eines Strings | ||||
|  |     * | ||||
|  |     *   Die Methode sendet einen String an den Kommunikationspartner | ||||
|  |     * | ||||
|  |     *   @param  toSend  String, der gesendet werden soll | ||||
|  |     * | ||||
|  |     *   @return Anzahl der gesendeten Bytes | ||||
|  |     */ | ||||
|  |     int Send(const std::string toSend); | ||||
|  | 
 | ||||
|  |     /** \brief  Empfängt Characters | ||||
|  |     * | ||||
|  |     *   @param szBuffer     hier wird die Nachricht reingeschrieben | ||||
|  |     *   @param iBufferLength    max. Läge der Nachricht | ||||
|  |     *   @param iFlags       Flags | ||||
|  |     * | ||||
|  |     *   @return Anzahl der gesendeten Bytes | ||||
|  |     */ | ||||
|  |     int Recv(char *szBuffer, int iBufferLength, int iFlags); | ||||
|  |     int Recv (std::string& s); | ||||
|  | 
 | ||||
|  |     void Disconnect(); | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | }; | ||||
|  | 
 | ||||
|  | #endif | ||||
| @ -0,0 +1,36 @@ | |||||
|  | #include "header.h"
 | ||||
|  | 
 | ||||
|  | void StringTool::String2CmdArg(string s, string & cmd, string & arg) | ||||
|  | { | ||||
|  |     string message = stripWhiteSpace(s); | ||||
|  |     if (message.find_first_of(STRING_WHITESPACES, 1) != string::npos) | ||||
|  |     { | ||||
|  |         cmd = stripWhiteSpace(message.substr(0, message.find_first_of(STRING_WHITESPACES, 1))); | ||||
|  |         arg = stripWhiteSpace(message.substr(message.find_first_of(STRING_WHITESPACES, 1))); | ||||
|  |     } else  | ||||
|  |     { | ||||
|  |         cmd = message; | ||||
|  |         arg = ""; | ||||
|  |     } | ||||
|  |     return; | ||||
|  | } | ||||
|  | 
 | ||||
|  | string StringTool::stripWhiteSpace(string s) | ||||
|  | { | ||||
|  |     unsigned int i, j; | ||||
|  |     if (s.length() > 0) | ||||
|  |     { | ||||
|  |         i = s.find_first_not_of(STRING_WHITESPACES); | ||||
|  |         j = s.find_last_not_of(STRING_WHITESPACES); | ||||
|  | 
 | ||||
|  |         if (i == string::npos) | ||||
|  |             i = 0; | ||||
|  |         if (j == string::npos) | ||||
|  |             j = s.length()-1; | ||||
|  | 
 | ||||
|  |         return string(s, i, j-i+1); | ||||
|  |     } | ||||
|  |     return string(""); | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
| @ -0,0 +1,13 @@ | |||||
|  | #include <string> | ||||
|  | 
 | ||||
|  | #ifndef STRING_TOOL | ||||
|  | #define STRING_TOOL  | ||||
|  | 
 | ||||
|  | class StringTool | ||||
|  | { | ||||
|  | private: | ||||
|  | public: | ||||
|  |     void String2CmdArg(std::string s, std::string & cmd, std::string & arg); | ||||
|  |     std::string stripWhiteSpace(std::string s); | ||||
|  | }; | ||||
|  | #endif | ||||
						
							
						
						
							1079
	
						
						lwrserv/SvrHandling.cpp
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				File diff suppressed because it is too large
							
							
								
									View File
								
							
						| @ -0,0 +1,61 @@ | |||||
|  | #include "defines.h" | ||||
|  | #include "StringTool.h" | ||||
|  | #include <string> | ||||
|  | #include "friremote.h" | ||||
|  | 
 | ||||
|  | #ifndef SVR_HANDLING | ||||
|  | #define SVR_HANDLING | ||||
|  | 
 | ||||
|  | // Serve status | ||||
|  | typedef enum {waiting, handshake, accepted, done} svr_state; | ||||
|  | 
 | ||||
|  | class SvrHandling : private StringTool | ||||
|  | { | ||||
|  | private: | ||||
|  |     svr_state c_state; | ||||
|  |     //Handshake | ||||
|  |     bool handshakeAccepted(SocketObject& client); | ||||
|  |     //Handle client | ||||
|  |     void handle(SocketObject& client); | ||||
|  |     //Handling request for current Joint Values | ||||
|  |     void GetPositionJoints(SocketObject& client); | ||||
|  |     //Get Position as POSE Matrix | ||||
|  |     void GetPositionHomRowWise(SocketObject& client); | ||||
|  |     //Get Force/torque values from TCP | ||||
|  |     void GetForceTorqueTcp(SocketObject& client); | ||||
|  |     //Move to given Joint combination | ||||
|  |     void MovePTPJoints(SocketObject& client, std::string& args); | ||||
|  |     //Move to given POSE position | ||||
|  |     void MoveHomRowWiseStatus(SocketObject& client, std::string& args); | ||||
|  |     //Set Velocity | ||||
|  |     void SetSpeed(SocketObject& client, std::string& args); | ||||
|  |     //Set Acceleration | ||||
|  |     void SetAccel(SocketObject& client, std::string& args); | ||||
|  |     //Starting Potential Field Movement Mode | ||||
|  |     void StartPotFieldMode(SocketObject& client, std::string& args); | ||||
|  |     //Stopping Potential Field Movement Mode | ||||
|  |     void StopPotFieldMode(SocketObject& client, std::string& args); | ||||
|  |     //Setting Target Position HomRowWise for Potential Move | ||||
|  |     void SetPos(SocketObject& client, std::string& args); | ||||
|  |     //Setting Target Position as Joints for Potential Move | ||||
|  |     void SetJoints(SocketObject& client, std::string& args); | ||||
|  |     //Cartesian Movement | ||||
|  |     //Move to given POSE position | ||||
|  |     void MoveCartesian(SocketObject& client, std::string& args); | ||||
|  |     //Do Ultrasound | ||||
|  |     void DoUltrasound(SocketObject& client, std::string& args); | ||||
|  |     //Quit | ||||
|  |     void quit(SocketObject& client); | ||||
|  |     //DEBUGGING | ||||
|  |     void debug(SocketObject& client); | ||||
|  | public: | ||||
|  |     //Constructor | ||||
|  |     SvrHandling(); | ||||
|  |     //Destructor | ||||
|  |     virtual ~SvrHandling(); | ||||
|  |     //Rund server @port | ||||
|  |     void run(int port); | ||||
|  |     //Get current timestamp | ||||
|  |     std::string timestamp(); | ||||
|  | }; | ||||
|  | #endif | ||||
| @ -0,0 +1,38 @@ | |||||
|  | 
 | ||||
|  | #ifndef __DEFINES_H__ | ||||
|  | #define __DEFINES_H__ | ||||
|  | 
 | ||||
|  | #define SVR_NAME			"lwrsvr 4.11d" | ||||
|  | #define SVR_DEFAULT_PORT	8000 | ||||
|  | #define SVR_HANDSHAKE		"Hello Robot" | ||||
|  | #define SVR_HELLO_MSG		std::string("welcome to ") + SVR_NAME + ("!") | ||||
|  | #define SVR_ACCEPTED		std::string("accepted") | ||||
|  | #define SVR_FAILED			std::string("Failed.") | ||||
|  | #define STRING_WHITESPACES  " \t\r\n" | ||||
|  | #define SVR_TRUE_RSP		"true" | ||||
|  | #define SVR_FALSE_RSP		"false" | ||||
|  | #define M_PI				3.141592654f | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | //Begin SVR_COMMANDS | ||||
|  | #define CMD_GetPositionJoints			"GPJ" | ||||
|  | #define CMD_GetPositionHomRowWise		"GPHRW" | ||||
|  | #define CMD_GetForceTorqueTcp			"GFT" | ||||
|  | #define CMD_MovePTPJoints				"MPTPJ" | ||||
|  | #define CMD_MoveHomRowWiseStatus		"MHRWS" | ||||
|  | #define CMD_SetSpeed					"SS" | ||||
|  | #define CMD_SetAccel					"SA" | ||||
|  | #define CMD_StartPotFieldMode			"STPF" | ||||
|  | #define CMD_StopPotFieldMode			"SPPF" | ||||
|  | #define CMD_SetPos						"SP" | ||||
|  | #define CMD_SetJoints					"SJ" | ||||
|  | #define CMD_QUIT						"Quit" | ||||
|  | #define CMD_ISKUKA						"IsKukaLWR" | ||||
|  | #define CMD_MoveCartesian				"MC" | ||||
|  | #define CMD_DoUltrasound				"DU" | ||||
|  | //End SVR_COMMANDS | ||||
|  | 
 | ||||
|  | #endif /* __DEFINES_H__ */ | ||||
|  | 
 | ||||
| @ -0,0 +1,504 @@ | |||||
|  | /*{{[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 */ | ||||
| @ -0,0 +1,288 @@ | |||||
|  | /*{{[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] | ||||
|  | **************************************************************************** | ||||
|  |   friRemote.cpp | ||||
|  |         | ||||
|  |       NOTE: This sample, as the corresponding FRI (Fast Research inteface) is subject to radical change | ||||
|  | 	   | ||||
|  |        | ||||
|  | [FH]}} | ||||
|  | */  | ||||
|  | /**
 | ||||
|  | 	\addtogroup friRemoteLib | ||||
|  | 	\brief Library for FRI (FastResearchInterface)  | ||||
|  | */ | ||||
|  | /* @{ */ | ||||
|  | 
 | ||||
|  | /** *************************************************************************
 | ||||
|  |  \author (Guenter Schreiber) | ||||
|  | \file | ||||
|  | \brief  FRI Remote class encapsulating UDP package handshakes | ||||
|  |  *                                                                         * | ||||
|  |  ***************************************************************************/ | ||||
|  | #include "friremote.h"
 | ||||
|  | 
 | ||||
|  | #include <iostream>
 | ||||
|  | #include <stdlib.h>
 | ||||
|  | 
 | ||||
|  | friRemote::friRemote(int port,char *hintToRemoteHost):remote(port,hintToRemoteHost) | ||||
|  | { | ||||
|  | 	//std::cout << __FUNCTION__ << " " <<port <<std::endl;
 | ||||
|  | 	//std::cout << "FRI Version " << FRI_MAJOR_VERSION << "." << FRI_SUB_VERSION << "." <<FRI_DATAGRAM_ID_CMD << "." <<FRI_DATAGRAM_ID_MSR << std::endl;
 | ||||
|  | 	memset((void*)(& msr),0x0,sizeof(msr)); | ||||
|  | 	memset((void*)(& cmd), 0x0,sizeof(cmd)); | ||||
|  | 	{ | ||||
|  | 		// do checks, whether the interface - and the host meets the requirements
 | ||||
|  | 		FRI_PREPARE_CHECK_BYTE_ORDER; | ||||
|  | 		if (!FRI_CHECK_BYTE_ORDER_OK)  | ||||
|  | 		{ | ||||
|  | 			std::cerr << __FUNCTION__<<"Byte order on your system is not appropriate - expect deep trouble" << std::endl; | ||||
|  | 		} | ||||
|  | 		if (!FRI_CHECK_SIZES_OK) | ||||
|  | 		{ | ||||
|  | 			std::cout << __FUNCTION__<<"Sizes of datastructures not appropriate - expect even deeper trouble" << std::endl; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | } | ||||
|  | 
 | ||||
|  | friRemote::~friRemote() | ||||
|  | { | ||||
|  | 	std::cout << __FUNCTION__ << " bye for now "  << std::endl; | ||||
|  | } | ||||
|  | 
 | ||||
|  | int friRemote::doReceiveData() | ||||
|  | { | ||||
|  | 	return remote.Recv(&msr); | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | /** Data Exchanger -- normally update within access routine implicitely ... */ | ||||
|  | int friRemote::doSendData() | ||||
|  | { | ||||
|  |   // received at least something 
 | ||||
|  |    seqCount++; | ||||
|  |    cmd.head.sendSeqCount = seqCount; | ||||
|  |    cmd.head.reflSeqCount = msr.head.sendSeqCount; | ||||
|  |    cmd.head.datagramId = FRI_DATAGRAM_ID_CMD; | ||||
|  |    cmd.head.packetSize = sizeof(tFriCmdData); | ||||
|  |     int rc=remote.Send(&cmd); | ||||
|  |   return rc; | ||||
|  | } | ||||
|  | 
 | ||||
|  | /** send commands based on last msr datagram and 
 | ||||
|  |     receives a new one | ||||
|  | */ | ||||
|  | int friRemote::doDataExchange() | ||||
|  | { | ||||
|  | 	doSendData(); | ||||
|  | 	return doReceiveData(); | ||||
|  | } | ||||
|  | 
 | ||||
|  | /** automatically do data exchange, if not otherwise specified */ | ||||
|  | int friRemote::doPositionControl(float newJntPosition[LBR_MNJ], bool flagDataExchange) | ||||
|  | { | ||||
|  | 	// Helper, if not properly initialized or the like...
 | ||||
|  | 
 | ||||
|  | 	cmd.cmd.cmdFlags=FRI_CMD_JNTPOS; | ||||
|  | 	// Note:: If the interface is not in Command mode,
 | ||||
|  | 	// The commands have to be "mirrored" to get in sync
 | ||||
|  | 	// Note:: If the interface is not in Command mode,
 | ||||
|  | 	// The commands have to be "mirrored" to get in sync
 | ||||
|  | 	if ((getState() != FRI_STATE_CMD) || (!isPowerOn())) | ||||
|  | 	{ | ||||
|  | 		for (int i = 0; i < LBR_MNJ; i++) | ||||
|  | 		{ | ||||
|  | 			cmd.cmd.jntPos[i]=msr.data.cmdJntPos[i]+msr.data.cmdJntPosFriOffset[i]; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	else | ||||
|  | 	{ | ||||
|  | 		// compute new values here ...
 | ||||
|  | 		for (int i = 0; i < LBR_MNJ; i++) | ||||
|  | 		{ | ||||
|  | 			cmd.cmd.jntPos[i]=newJntPosition[i]; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	if (flagDataExchange) | ||||
|  | 	{ | ||||
|  | 		return doDataExchange(); | ||||
|  | 	} | ||||
|  | 	return 1; | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | /** automatically do data exchange, if not otherwise specified 
 | ||||
|  |  if flagDataExchange is set to false, call doDataExchange()  | ||||
|  |  or doReceiveData()/doSendData() on your own | ||||
|  |  IN: newJntPosition   - joint positions | ||||
|  | 	 newJntStiff      - joint stiffness (Spring factor) | ||||
|  | 	 newJntDamp       - joint damping   (Damping factor) | ||||
|  | 	 newJntAddTorque  - additional torque  | ||||
|  |         | ||||
|  |  Note: If any of the pointers (newJntPosition, newJntStiff, newJntDamp, newJntAddTorque) is NULL, the  | ||||
|  | 	   value is ignored -> the respective  cmd.cmd.cmdFlags field is set properly | ||||
|  |  Note: It is possible to change cmd.cmd.cmdFlags in monitor mode only !! | ||||
|  |  */ | ||||
|  | int friRemote::doJntImpedanceControl(const float newJntPosition[LBR_MNJ],  | ||||
|  | 										const float newJntStiff[LBR_MNJ],  | ||||
|  | 										const float newJntDamp[LBR_MNJ],  | ||||
|  | 										const float newJntAddTorque[LBR_MNJ], | ||||
|  | 										bool flagDataExchange) | ||||
|  | 
 | ||||
|  | { | ||||
|  | 	// Helper, if not properly initialized or the like...
 | ||||
|  | 	cmd.cmd.cmdFlags=0; | ||||
|  | 	if (newJntPosition) | ||||
|  | 	{ | ||||
|  | 		cmd.cmd.cmdFlags|=FRI_CMD_JNTPOS; | ||||
|  | 		// Note:: If the interface is not in Command mode,
 | ||||
|  | 		// The commands have to be "mirrored" to get in sync
 | ||||
|  | 		if ((getState() != FRI_STATE_CMD) || (!isPowerOn())) | ||||
|  | 		{ | ||||
|  | 			for (int i = 0; i < LBR_MNJ; i++) | ||||
|  | 			{ | ||||
|  | 				cmd.cmd.jntPos[i]=msr.data.cmdJntPos[i]+msr.data.cmdJntPosFriOffset[i]; | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 		else | ||||
|  | 		{ | ||||
|  | 			// compute new values here ...
 | ||||
|  | 			for (int i = 0; i < LBR_MNJ; i++) | ||||
|  | 				cmd.cmd.jntPos[i]=newJntPosition[i]; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	if (newJntStiff) | ||||
|  | 	{ | ||||
|  | 		cmd.cmd.cmdFlags|=FRI_CMD_JNTSTIFF; | ||||
|  | 		for (int i = 0; i < LBR_MNJ; i++) | ||||
|  | 			cmd.cmd.jntStiffness[i]=newJntStiff[i]; | ||||
|  | 	} | ||||
|  | 	if (newJntDamp) | ||||
|  | 	{ | ||||
|  | 		cmd.cmd.cmdFlags|=FRI_CMD_JNTDAMP; | ||||
|  | 		for (int i = 0; i < LBR_MNJ; i++) | ||||
|  | 			cmd.cmd.jntDamping[i]=newJntDamp[i]; | ||||
|  | 	} | ||||
|  | 	if (newJntAddTorque) | ||||
|  | 	{ | ||||
|  | 		cmd.cmd.cmdFlags|=FRI_CMD_JNTTRQ; | ||||
|  | 		for (int i = 0; i < LBR_MNJ; i++) | ||||
|  | 			cmd.cmd.addJntTrq[i]=newJntAddTorque[i]; | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	if (flagDataExchange) | ||||
|  | 	{ | ||||
|  | 		return doDataExchange(); | ||||
|  | 	} | ||||
|  | 	return 1; | ||||
|  | } | ||||
|  | 
 | ||||
|  | 	/** automatically do data exchange, if not otherwise specified 
 | ||||
|  | 	if flagDataExchange is set to false, call doDataExchange()  | ||||
|  | 	or doReceiveData()/doSendData() on your own | ||||
|  | 	IN: newJntPosition   - joint positions | ||||
|  | 	newJntStiff      - joint stiffness (Spring factor) | ||||
|  | 	newJntDamp       - joint damping   (Damping factor) | ||||
|  | 	newJntAddTorque  - additional torque  | ||||
|  | 
 | ||||
|  | 	Note: If any of the pointers (newJntPosition, newJntStiff, newJntDamp, newJntAddTorque) is NULL, the  | ||||
|  | 	value is ignored -> the respective  cmd.cmd.cmdFlags field is set properly | ||||
|  | 	Note: It is possible to change cmd.cmd.cmdFlags in monitor mode only !! | ||||
|  | 	*/ | ||||
|  | int friRemote::doCartesianImpedanceControl(const float newCartPosition[FRI_CART_FRM_DIM],  | ||||
|  | 										   const float newCartStiff[FRI_CART_VEC],  | ||||
|  | 										   const float newCartDamp[FRI_CART_VEC],  | ||||
|  | 										   const float newAddTcpFT[FRI_CART_VEC], | ||||
|  | 										   const float newJntNullspace[LBR_MNJ],   | ||||
|  | 										   bool flagDataExchange) | ||||
|  | { | ||||
|  | 
 | ||||
|  | 		// Helper, if not properly initialized or the like...
 | ||||
|  | 	cmd.cmd.cmdFlags=0; | ||||
|  | 	if ( newCartPosition ) | ||||
|  | 	{ | ||||
|  | 		cmd.cmd.cmdFlags|=FRI_CMD_CARTPOS; | ||||
|  | 		for ( int i = 0; i < FRI_CART_FRM_DIM; i++) | ||||
|  | 		{ | ||||
|  | 			cmd.cmd.cartPos[i]=newCartPosition[i]; | ||||
|  | 
 | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	if ( newCartStiff) | ||||
|  | 	{ | ||||
|  | 		cmd.cmd.cmdFlags|=FRI_CMD_CARTSTIFF; | ||||
|  | 		for ( int i = 0; i < FRI_CART_VEC; i++) | ||||
|  | 		{ | ||||
|  | 			cmd.cmd.cartStiffness[i]=newCartStiff[i]; | ||||
|  | 
 | ||||
|  | 		} | ||||
|  | 
 | ||||
|  | 	} | ||||
|  | 	if ( newCartDamp) | ||||
|  | 	{ | ||||
|  | 		cmd.cmd.cmdFlags|=FRI_CMD_CARTDAMP; | ||||
|  | 			; | ||||
|  | 		for ( int i = 0; i < FRI_CART_VEC; i++) | ||||
|  | 		{ | ||||
|  | 			cmd.cmd.cartDamping[i]=newCartDamp[i]; | ||||
|  | 
 | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	if ( newAddTcpFT) | ||||
|  | 	{ | ||||
|  | 		cmd.cmd.cmdFlags|=FRI_CMD_TCPFT; | ||||
|  | 			; | ||||
|  | 		for ( int i = 0; i < FRI_CART_VEC; i++) | ||||
|  | 		{ | ||||
|  | 			cmd.cmd.addTcpFT[i]=newAddTcpFT[i]; | ||||
|  | 
 | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	if (newJntNullspace) | ||||
|  | 	{ | ||||
|  | 		cmd.cmd.cmdFlags|=FRI_CMD_JNTPOS; | ||||
|  | 		// Note:: If the interface is not in Command mode,
 | ||||
|  | 		// The commands have to be "mirrored" to get in sync
 | ||||
|  | 		 | ||||
|  | 			// compute new values here ...
 | ||||
|  | 			for (int i = 0; i < LBR_MNJ; i++) | ||||
|  | 				cmd.cmd.jntPos[i]=newJntNullspace[i];		 | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | if (flagDataExchange) | ||||
|  | 	{ | ||||
|  | 		return doDataExchange(); | ||||
|  | 	} | ||||
|  | 	return 1; | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | /* @} */ | ||||
|  | 
 | ||||
| @ -0,0 +1,194 @@ | |||||
|  | /* {{[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] | ||||
|  | **************************************************************************** | ||||
|  |   friFirstApp.cpp | ||||
|  |         | ||||
|  |       NOTE: This sample, as the corresponding FRI (Fast Research inteface) is subject to radical change | ||||
|  | 	   | ||||
|  |        | ||||
|  | [FH]}} | ||||
|  | */  | ||||
|  | /** | ||||
|  | 	\defgroup friRemoteLib | ||||
|  | 	\brief Library for FRI (FastResearchInterface)  | ||||
|  | */ | ||||
|  | /* @{ */ | ||||
|  | 
 | ||||
|  | /**  | ||||
|  |  \author (Guenter Schreiber) | ||||
|  | \file | ||||
|  | \brief Remote class for handshaking/dealing with udp datastructures | ||||
|  | 
 | ||||
|  |   This code is most important to understand the concepts behind data handshake | ||||
|  | */ | ||||
|  | #ifndef FRIFRIREMOTE_H | ||||
|  | #define FRIFRIREMOTE_H | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | #include "friudp.h" | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | /** | ||||
|  | 	@author Günter Schreiber <guenter@jacobus> | ||||
|  | */ | ||||
|  | 
 | ||||
|  | class friRemote | ||||
|  | { | ||||
|  | public: | ||||
|  | 	friRemote(int port = FRI_DEFAULT_SERVER_PORT, char * hintToRemoteHost=NULL); | ||||
|  | 	~friRemote(); | ||||
|  | 
 | ||||
|  | 	/** Data Exchanger -- normally update within access routine implicitely  | ||||
|  | 	send commands based on last datagram and after waits on new measurement | ||||
|  | 	calls doSendData() and doReceiveData(); | ||||
|  | 	... */ | ||||
|  | 	int doDataExchange(); | ||||
|  | 	/** Receives data while calling friUdp::Recv() | ||||
|  | 	The call will block.. | ||||
|  | 	*/ | ||||
|  | 	int doReceiveData(); | ||||
|  | 	/** Sends the data */ | ||||
|  | 	int doSendData(); | ||||
|  | 		/* @{ */ | ||||
|  | 	/** automatically do data exchange, if not otherwise specified  | ||||
|  | 	if flagDataExchange is set to false, call doDataExchange()  | ||||
|  | 	or doReceiveData()/doSendData() on your own | ||||
|  | 	*/ | ||||
|  | 	int doPositionControl(float newJntPosition[LBR_MNJ], bool flagDataExchange=true); | ||||
|  | 
 | ||||
|  | 	/** automatically do data exchange, if not otherwise specified  | ||||
|  | 	if flagDataExchange is set to false, call doDataExchange()  | ||||
|  | 	or doReceiveData()/doSendData() on your own | ||||
|  | 	IN: newJntPosition   - joint positions | ||||
|  | 	newJntStiff      - joint stiffness (Spring factor) | ||||
|  | 	newJntDamp       - joint damping   (Damping factor) | ||||
|  | 	newJntAddTorque  - additional torque  | ||||
|  | 
 | ||||
|  | 	Note: If any of the pointers (newJntPosition, newJntStiff, newJntDamp, newJntAddTorque) is NULL, the  | ||||
|  | 	value is ignored -> the respective  cmd.cmd.cmdFlags field is set properly | ||||
|  | 	Note: It is possible to change cmd.cmd.cmdFlags in monitor mode only !! | ||||
|  | 	*/ | ||||
|  | 	int doJntImpedanceControl(const float newJntPosition[LBR_MNJ], const float newJntStiff[LBR_MNJ] = NULL, const float newJntDamp[LBR_MNJ]=NULL, const float newJntAddTorque[LBR_MNJ]=NULL,bool flagDataExchange=true); | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 	/** automatically do data exchange, if not otherwise specified  | ||||
|  | 	if flagDataExchange is set to false, call doDataExchange()  | ||||
|  | 	or doReceiveData()/doSendData() on your own | ||||
|  | 	IN: newJntPosition   - joint positions | ||||
|  | 	newJntStiff      - joint stiffness (Spring factor) | ||||
|  | 	newJntDamp       - joint damping   (Damping factor) | ||||
|  | 	newJntAddTorque  - additional torque  | ||||
|  | 
 | ||||
|  | 	Note: If any of the pointers (newJntPosition, newJntStiff, newJntDamp, newJntAddTorque) is NULL, the  | ||||
|  | 	value is ignored -> the respective  cmd.cmd.cmdFlags field is set properly | ||||
|  | 	Note: It is possible to change cmd.cmd.cmdFlags in monitor mode only !! | ||||
|  | 	*/ | ||||
|  | 	int doCartesianImpedanceControl(const float newCartPosition[FRI_CART_FRM_DIM],  | ||||
|  | 		const float newCartStiff[FRI_CART_VEC]=NULL,  | ||||
|  | 		const float newCartDamp[FRI_CART_VEC]=NULL,  | ||||
|  | 		const float newAddTcpFT[FRI_CART_VEC]=NULL, | ||||
|  | 		const float newJntNullspace[LBR_MNJ]=NULL,  bool flagDataExchange=true); | ||||
|  | 		/* @} */ | ||||
|  | 
 | ||||
|  | 	/** measured Cartesian frame (in m) | ||||
|  | 	KRL: $POS_ACT_MSR | ||||
|  | 	Reference: Base and tool are specified by $stiffness.base, $stiffness.tool  | ||||
|  | 	*/ | ||||
|  | 	float * getMsrCartPosition() { return msr.data.msrCartPos; } | ||||
|  | 	/** commanded Cartesian frame (in m, before FRI)  | ||||
|  | 	KRL: $POS_ACT_CMD | ||||
|  | 	Reference: Base and tool are specified by $stiffness.base, $stiffness.tool  | ||||
|  | 	*/ | ||||
|  | 	float * getMsrCmdCartPosition() { return msr.data.cmdCartPos; } | ||||
|  | 
 | ||||
|  | 	/** commanded Cartesian frame (in m, due to FRI) */ | ||||
|  | 	float * getMsrCmdCartPosFriOffset() { return msr.data.cmdCartPosFriOffset; } | ||||
|  | 
 | ||||
|  | 	/** Access to inner buffers for further manipulation */ | ||||
|  | 	tFriMsrData & getMsrBuf() { return msr;} | ||||
|  | 	tFriCmdData & getCmdBuf() { return cmd;} | ||||
|  | 	/* @{ */ | ||||
|  | 	/** interpretational access routines */ | ||||
|  | 	FRI_STATE getState()      { return (FRI_STATE)msr.intf.state;   } | ||||
|  | 	FRI_QUALITY getQuality()  { return (FRI_QUALITY)msr.intf.quality; } | ||||
|  | 	FRI_CTRL getCurrentControlScheme (){ return (FRI_CTRL)msr.robot.control; } | ||||
|  | 
 | ||||
|  | 	bool isPowerOn() { return msr.robot.power!=0; } | ||||
|  | 	/* @} */ | ||||
|  | 
 | ||||
|  | 	/* @{ */ | ||||
|  | 	/** Important value for superposition - and during poweroff stages, to become command mode */ | ||||
|  | 	float * getMsrCmdJntPosition() { return msr.data.cmdJntPos; } | ||||
|  | 	/** returns the offset, which is commanded by FRI Remote side  | ||||
|  | 	*  Complete desired position inside LBR Kernel is the sum of cmdJntPos and cmdJntPosFriOffset */ | ||||
|  | 	float * getMsrCmdJntPositionOffset() { return msr.data.cmdJntPosFriOffset; } | ||||
|  | 
 | ||||
|  | 	void getCurrentCmdJntPosition( float jntVec[LBR_MNJ] ) { for ( int i = 0; i < LBR_MNJ; i++) jntVec[i]= msr.data.cmdJntPos[i]+msr.data.cmdJntPosFriOffset[i];} | ||||
|  | 	/** Current measured jnt position of the robot */ | ||||
|  | 	float * getMsrMsrJntPosition() { return msr.data.msrJntPos; } | ||||
|  | 	float * getMsrEstExtJntTrq() { return msr.data.estExtJntTrq; } | ||||
|  | 	float * getMsrJntTrq() { return msr.data.msrJntTrq; } | ||||
|  | 		/* @} */ | ||||
|  | 
 | ||||
|  | 	float getSampleTime() { return msr.intf.desiredCmdSampleTime; } | ||||
|  | 	int getSequenceCount() { return seqCount; } | ||||
|  | 
 | ||||
|  | 	/* @{ */ | ||||
|  | 	/** KRL Interaction -- Corresponds to $FRI_TO_REA */ | ||||
|  | 	float getFrmKRLReal(int index) { return msr.krl.realData[index]; } | ||||
|  | 	/** KRL Interaction -- Corresponds to $FRI_FRM_REA */ | ||||
|  | 	void  setToKRLReal(int index, float val) { cmd.krl.realData[index]=val; } | ||||
|  | 		/** KRL Interaction -- Corresponds to $FRI_TO_INT */ | ||||
|  | 	int   getFrmKRLInt(int index) { return msr.krl.intData[index]; } | ||||
|  | 		/** KRL Interaction -- Corresponds to $FRI_FRM_INT */ | ||||
|  | 	void  setToKRLInt(int index, int val) { cmd.krl.intData[index]=val; } | ||||
|  | 		/** KRL Interaction -- Corresponds to $FRI_TO_BOOL */ | ||||
|  | 	bool  getFrmKRLBool(int index) { return ((msr.krl.boolData & (1<<index)) != 0);} | ||||
|  | 		/** KRL Interaction -- Corresponds to $FRI_FRM_BOOL */ | ||||
|  | 	fri_uint16_t getFrmKRLBool() { return msr.krl.boolData; } | ||||
|  | 		/** KRL Interaction -- Corresponds to $FRI_FRM_BOOL */ | ||||
|  | 	void  setToKRLBool(int index, bool val)  | ||||
|  | 	{ if ( val) { cmd.krl.boolData |= (1<<index);}  | ||||
|  | 	else {cmd.krl.boolData &= (~(1<<index));}} | ||||
|  | 	void setToKRLBool(fri_uint16_t val) {   cmd.krl.boolData = val; } | ||||
|  | 	/* @} */ | ||||
|  | 	/** Get Jacobian Matrix | ||||
|  | 	*/ | ||||
|  | 	float * getJacobian() { return msr.data.jacobian; } | ||||
|  | 	float * getFTTcp() {return msr.data.estExtTcpFT;} | ||||
|  | 
 | ||||
|  | protected: | ||||
|  | 	tFriMsrData msr; | ||||
|  | 	tFriCmdData cmd; | ||||
|  | private: | ||||
|  | 	friUdp remote; | ||||
|  | 	int seqCount; | ||||
|  | }; | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | #endif | ||||
|  | /* @} */ | ||||
| @ -0,0 +1,543 @@ | |||||
|  | /*{{[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] | ||||
|  | **************************************************************************** | ||||
|  |   friUdp.cpp | ||||
|  |         | ||||
|  |       NOTE: This sample, as the corresponding FRI (Fast Research inteface) is subject to radical change | ||||
|  |        | ||||
|  |        | ||||
|  | [FH]}} | ||||
|  | */  | ||||
|  | /**
 | ||||
|  |     \addtogroup friRemoteLib | ||||
|  |     \brief Library for FRI (FastResearchInterface)  | ||||
|  | */ | ||||
|  | /* @{ */ | ||||
|  | 
 | ||||
|  | /** *************************************************************************
 | ||||
|  |  \author (Guenter Schreiber) | ||||
|  | \file | ||||
|  | \brief Implementation of a UDP socket | ||||
|  |  *                                                                         * | ||||
|  |  ***************************************************************************/ | ||||
|  | #include "friudp.h"
 | ||||
|  | 
 | ||||
|  | #ifdef WIN32
 | ||||
|  | #include "SocketObject.h"
 | ||||
|  | //#pragma comment(lib, "ws2_32.lib") 
 | ||||
|  | #endif // WIN32
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | friUdp::friUdp(int port, char * remoteHost) : serverPort(port) | ||||
|  | { | ||||
|  |     /* check struct sizes */ | ||||
|  |     if (!FRI_CHECK_SIZES_OK) | ||||
|  |     { | ||||
|  |         printf("data structure size error!\n"); | ||||
|  |         exit(1); | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     m_timestamp=0; | ||||
|  |     // Make shure, that e.g. simulink uses no stupid standard definition - e.g. 0
 | ||||
|  |     if ( serverPort < 10 ) | ||||
|  |     { | ||||
|  |         serverPort=FRI_DEFAULT_SERVER_PORT;  | ||||
|  |     } | ||||
|  | 
 | ||||
|  | #ifdef WIN32
 | ||||
|  |     StartWinsock(); | ||||
|  | #endif
 | ||||
|  |     Init(remoteHost); | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | friUdp::~friUdp() | ||||
|  | { | ||||
|  |   Close(); | ||||
|  | } | ||||
|  | 
 | ||||
|  | #ifdef WIN32
 | ||||
|  | int friUdp::StartWinsock(void) | ||||
|  | { | ||||
|  |     WSADATA WSAData; | ||||
|  |     return WSAStartup(MAKEWORD(2,0), &WSAData); | ||||
|  | } | ||||
|  | #endif// WIN32
 | ||||
|  | 
 | ||||
|  | void friUdp::Init(char * remoteHost) | ||||
|  | { | ||||
|  |     struct sockaddr_in servAddr; | ||||
|  |     m_timestamp = 0; | ||||
|  |     memset(&servAddr, 0, sizeof(servAddr)); | ||||
|  |     memset(&krcAddr, 0, sizeof(krcAddr)); | ||||
|  | 
 | ||||
|  |     /* socket creation */ | ||||
|  |     udpSock = socket(PF_INET, SOCK_DGRAM, 0); | ||||
|  |     if (udpSock < 0) | ||||
|  |     { | ||||
|  |         printf("opening socket failed!\n"); | ||||
|  |         exit(1); | ||||
|  |     } | ||||
|  | 
 | ||||
|  | #ifdef HAVE_TIME_STAMP_RECEIVE
 | ||||
|  |     { | ||||
|  |         int temp = 1; | ||||
|  |         if (setsockopt(udpSock, SOL_SOCKET, SO_TIMESTAMP, &temp, sizeof(int)) < 0) | ||||
|  |         { | ||||
|  |             printf("failed to enable receive time stamps\n"); | ||||
|  |             exit(1); | ||||
|  |         } | ||||
|  |     } | ||||
|  | #endif
 | ||||
|  | 
 | ||||
|  |     /* bind local server port */ | ||||
|  |     servAddr.sin_family = AF_INET; | ||||
|  |     servAddr.sin_addr.s_addr = htonl(INADDR_ANY); | ||||
|  |     servAddr.sin_port = htons(serverPort); | ||||
|  | 
 | ||||
|  |     if (bind(udpSock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) | ||||
|  |     { | ||||
|  |         printf("binding port number %d failed!\n", serverPort); | ||||
|  |         Close(); | ||||
|  |         exit(1); | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     // if the remote host is specified, 
 | ||||
|  |     // preinitialize the socket properly
 | ||||
|  |     if ( remoteHost )  | ||||
|  |     { | ||||
|  |         printf("preinitialized remote host to %s\n",remoteHost); | ||||
|  |         krcAddr.sin_addr.s_addr = inet_addr(remoteHost); | ||||
|  |         krcAddr.sin_family = AF_INET; | ||||
|  |         krcAddr.sin_port=htons(serverPort); | ||||
|  |     } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | #ifdef HAVE_GETHOSTNAME
 | ||||
|  |     /* get IP(s) and port number and display them (just for
 | ||||
|  |      convenience, so debugging friOpen is easier) */ | ||||
|  |     { | ||||
|  |         char hostname[100]; | ||||
|  |         struct hostent * host; | ||||
|  |         int i; | ||||
|  | 
 | ||||
|  |         gethostname(hostname, sizeof(hostname)); | ||||
|  |         host = gethostbyname(hostname); | ||||
|  |         for (i=0; host->h_addr_list[i]!=0; i++) | ||||
|  |         { | ||||
|  |             struct in_addr addr; | ||||
|  |             memcpy(&addr, host->h_addr_list[i], sizeof(addr)); | ||||
|  |             //printf("helloIP %s - Port %d\n", inet_ntoa(addr), serverPort);
 | ||||
|  |         } | ||||
|  |     } | ||||
|  | #endif // 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | /* reveive one packet from KRC (blocking!) */ | ||||
|  | int friUdp::Recv(tFriMsrData *packet) | ||||
|  | { | ||||
|  |     if (udpSock >= 0) | ||||
|  |     { | ||||
|  |         int received; | ||||
|  |         struct timeval ts; | ||||
|  |          | ||||
|  |         received = RecvPacket(udpSock, packet, &ts, &krcAddr); | ||||
|  | 
 | ||||
|  |         if (received == sizeof(tFriMsrData)) | ||||
|  |         { | ||||
|  | #ifdef HAVE_TIME_STAMP_RECEIVE
 | ||||
|  | 
 | ||||
|  |             /* FIXME: need another #ifdef for VxWorks */ | ||||
|  | #ifdef QNX
 | ||||
|  |             struct timespec ts; | ||||
|  |             clock_gettime(CLOCK_REALTIME, &ts); | ||||
|  |             m_timestamp = (double)ts.tv_sec + (double)ts.tv_nsec/1.0e9; | ||||
|  | #else
 | ||||
|  |             m_timestamp = (double)ts.tv_sec + (double)ts.tv_usec/1.0e6; | ||||
|  | #endif // QNX
 | ||||
|  | #endif // HAVE_TIME_STAMP
 | ||||
|  |             return 0; | ||||
|  |         } | ||||
|  |         else | ||||
|  |         { | ||||
|  |             printf("received something, but wrong size %d (expected %d)...\n",received,(int) sizeof(tFriMsrData)); | ||||
|  |             fflush(stdout); | ||||
|  |         } | ||||
|  |     } | ||||
|  |     memset(packet, 0, sizeof(tFriMsrData)); | ||||
|  |     return -1; | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | /* send one answer packet to KRC */ | ||||
|  | int friUdp::Send(tFriCmdData *data) | ||||
|  | { | ||||
|  |     krcAddr.sin_family = AF_INET; | ||||
|  | #ifdef KRC_IP_ADDRESS
 | ||||
|  |     krcAddr.sin_addr.s_addr = inet_addr(KRC_IP_ADDRESS); | ||||
|  | #endif
 | ||||
|  | #ifdef KRC_RECEIVE_PORT
 | ||||
|  |     krcAddr.sin_port = htons(KRC_RECEIVE_PORT); | ||||
|  | #endif
 | ||||
|  | 
 | ||||
|  |     if ((udpSock >= 0) && (ntohs(krcAddr.sin_port) != 0)) | ||||
|  |     { | ||||
|  |         int sent; | ||||
|  |         sent = sendto(udpSock, (char *) data, sizeof(tFriCmdData), 0, | ||||
|  |                       (struct sockaddr *)&krcAddr, sizeof(krcAddr)); | ||||
|  |         if (sent == sizeof(tFriCmdData)) | ||||
|  |         { | ||||
|  |             return 0; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     return -1; | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | /* close the socket */ | ||||
|  | void friUdp::Close(void) | ||||
|  | { | ||||
|  |     if (udpSock >= 0) | ||||
|  |     { | ||||
|  | #ifdef WIN32
 | ||||
|  |         closesocket(udpSock);  | ||||
|  |         WSACleanup();  | ||||
|  | #else
 | ||||
|  |         close(udpSock); | ||||
|  | #endif
 | ||||
|  |     } | ||||
|  |     udpSock = -1; | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | #ifdef HAVE_TIME_STAMP_RECEIVE
 | ||||
|  | // Socket option SO_TIMESTAMP is supported 
 | ||||
|  | /* receive with timestamp  */ | ||||
|  | int friUdp::RecvPacket(int fd, tFriMsrData* p, struct timeval* ts, struct sockaddr_in* client)  | ||||
|  | { | ||||
|  |     struct msghdr msg; | ||||
|  |     struct iovec vec[1]; | ||||
|  |     union { | ||||
|  |         struct cmsghdr cm; | ||||
|  |         char control[20]; | ||||
|  |     } cmsg_un; | ||||
|  |     struct cmsghdr *cmsg; | ||||
|  |     struct timeval *tv = NULL; | ||||
|  |     int n; | ||||
|  |          | ||||
|  |     vec[0].iov_base = p; | ||||
|  |     vec[0].iov_len = sizeof(*p); | ||||
|  |          | ||||
|  |     memset(&msg, 0, sizeof(msg)); | ||||
|  |     memset(&cmsg_un, 0, sizeof(cmsg_un)); | ||||
|  |          | ||||
|  |     msg.msg_name = (caddr_t)client; | ||||
|  |     if(client) | ||||
|  |         msg.msg_namelen = sizeof(*client); | ||||
|  |     else | ||||
|  |         msg.msg_namelen = 0; | ||||
|  | 
 | ||||
|  |     msg.msg_iov = vec; | ||||
|  |     msg.msg_iovlen = 1; | ||||
|  |     msg.msg_control = cmsg_un.control; | ||||
|  |     msg.msg_controllen = sizeof(cmsg_un.control); | ||||
|  |     msg.msg_flags = 0; | ||||
|  |          | ||||
|  |     n = recvmsg(fd, &msg, 0); // MSG_DONTWAIT
 | ||||
|  |     if(n < 0) | ||||
|  |     { | ||||
|  |         perror("recvmsg"); | ||||
|  |         return -1; | ||||
|  |     } | ||||
|  |     if(msg.msg_flags & MSG_TRUNC) | ||||
|  |     { | ||||
|  |         printf("received truncated message\n"); | ||||
|  |         return -1; | ||||
|  |     } | ||||
|  |     if(!ts) | ||||
|  |         return n; | ||||
|  | 
 | ||||
|  |     /* get time stamp of packet */ | ||||
|  |     if(msg.msg_flags & MSG_CTRUNC) | ||||
|  |     { | ||||
|  |         printf("received truncated ancillary data\n"); | ||||
|  |         return -1; | ||||
|  |     } | ||||
|  |     if(msg.msg_controllen < sizeof(cmsg_un.control)) | ||||
|  |     { | ||||
|  |         printf("received short ancillary data (%d/%d)\n", msg.msg_controllen, (int)sizeof(cmsg_un.control)); | ||||
|  |         return -1; | ||||
|  |     } | ||||
|  |     for(cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) | ||||
|  |     { | ||||
|  |         if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMP) | ||||
|  |             tv = (struct timeval *)CMSG_DATA(cmsg); | ||||
|  |     } | ||||
|  |     if(tv) | ||||
|  |     { | ||||
|  |         ts->tv_sec = tv->tv_sec; | ||||
|  |         ts->tv_usec = tv->tv_usec; | ||||
|  |     } | ||||
|  |     return n; | ||||
|  | } | ||||
|  | 
 | ||||
|  | #else
 | ||||
|  | /* receive with timestamp  */ | ||||
|  | int friUdp::RecvPacket(int udpSock, tFriMsrData* data, struct timeval* ts, struct sockaddr_in* client)  | ||||
|  | { | ||||
|  | 
 | ||||
|  |     if (udpSock >= 0) | ||||
|  |     { | ||||
|  |         /** HAVE_SOCKLEN_T
 | ||||
|  |             Yes - unbelieavble: There are differences in standard calling parameters (types) to recvfrom  | ||||
|  |             Windows winsock, VxWorks and QNX use int | ||||
|  |             newer Posix (most Linuxes) use socklen_t | ||||
|  |          */ | ||||
|  | 
 | ||||
|  | #ifdef HAVE_SOCKLEN_T
 | ||||
|  |         socklen_t sockAddrSize; | ||||
|  | #else
 | ||||
|  |         int sockAddrSize; | ||||
|  | #endif
 | ||||
|  |         int received; | ||||
|  | 
 | ||||
|  |         sockAddrSize = sizeof(struct sockaddr_in); | ||||
|  | 
 | ||||
|  |         received = recvfrom(udpSock, (char *) data, sizeof(tFriMsrData), 0, | ||||
|  |                             (struct sockaddr *)&krcAddr, &sockAddrSize); | ||||
|  | 
 | ||||
|  |         return received; | ||||
|  |     } | ||||
|  |     return -1; | ||||
|  | } | ||||
|  | 
 | ||||
|  | #endif // HAVE_TIME_STAMP_RECEIVE
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | #ifdef VXWORKS //USE_BERKELEY_PACKAGE_FILTER_VXWORKS
 | ||||
|  | #define DEBUG_BPF_READ
 | ||||
|  | 
 | ||||
|  | #include "vxworks.h" 
 | ||||
|  | #include "bpfDrv.h" 
 | ||||
|  | #include "ioLib.h"
 | ||||
|  | #include <logLib.h> 
 | ||||
|  | #include <sys/ioctl.h>
 | ||||
|  | //#include "drv/netif/smNetLib.h"
 | ||||
|  | #include <wrn/coreip/net/ethernet.h> 
 | ||||
|  | #include <wrn/coreip/net/if.h>
 | ||||
|  | #include <wrn/coreip/netinet/ip.h>
 | ||||
|  | #include <wrn/coreip/netinet/udp.h>
 | ||||
|  | 
 | ||||
|  | #ifdef DEBUG_BPF_READ
 | ||||
|  | #include <iostream>
 | ||||
|  | #include "friremote.h"
 | ||||
|  | 
 | ||||
|  | #endif
 | ||||
|  |   | ||||
|  | 
 | ||||
|  | /*
 | ||||
|  |  * Packet filter program... | ||||
|  |  * | ||||
|  |  * XXX: Changes to the filter program may require changes to the | ||||
|  |  * constant offsets used in if_register_send to patch the BPF program! | ||||
|  |  */ | ||||
|  | struct bpf_insn friUpdSock_bpf_filter[] = | ||||
|  | { | ||||
|  |     /* Make sure this is an IP packet... */ | ||||
|  |     BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12), | ||||
|  |     BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8), | ||||
|  | 
 | ||||
|  |     /* Make sure it's a UDP packet... */ | ||||
|  |     BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23), | ||||
|  |     BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6), | ||||
|  | 
 | ||||
|  |     /* Make sure this isn't a fragment... */ | ||||
|  |     BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20), | ||||
|  |     BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0), | ||||
|  | 
 | ||||
|  |     /* Get the IP header length... */ | ||||
|  |     BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14), | ||||
|  | 
 | ||||
|  |     /* Make sure it's to the right port... */ | ||||
|  |     BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16), | ||||
|  |     BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),      /* patch */ | ||||
|  | 
 | ||||
|  |     /* If we passed all the tests, ask for the whole packet. */ | ||||
|  |     BPF_STMT(BPF_RET+BPF_K, (u_int)-1), | ||||
|  | 
 | ||||
|  |     /* Otherwise, drop it. */ | ||||
|  |     BPF_STMT(BPF_RET+BPF_K, 0), | ||||
|  | }; | ||||
|  | 
 | ||||
|  | int friUpdSock_bpf_filter_len = sizeof(friUpdSock_bpf_filter) / sizeof(struct bpf_insn); | ||||
|  | struct bpf_program  mybpf; | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | void testBPF1(int socketPort, char * devName)  | ||||
|  | { | ||||
|  |     int bpffd = 0;  | ||||
|  |     struct bpf_hdr * buf = NULL;  | ||||
|  |     char * pbuffer = NULL;  | ||||
|  |     int buflen;  | ||||
|  |     int len,i;  | ||||
|  |     ///int j=10; 
 | ||||
|  |     char dev[8] = "gei0";  | ||||
|  |     struct ifreq ifr;  | ||||
|  |     int trueValue=1;  | ||||
|  |     int Rcvlen;  | ||||
|  | 
 | ||||
|  |     if ( socketPort <= 10) | ||||
|  |         socketPort = 12345; | ||||
|  | 
 | ||||
|  |     if ( devName != NULL ) | ||||
|  |     { | ||||
|  |         strncpy(dev,devName,8); | ||||
|  |         dev[8]=0; | ||||
|  |     } | ||||
|  |     mybpf.bf_len = friUpdSock_bpf_filter_len;  | ||||
|  |     mybpf.bf_insns = friUpdSock_bpf_filter;  | ||||
|  | 
 | ||||
|  |     /* Patch the server port into the BPF program...
 | ||||
|  |      * | ||||
|  |      * XXX: changes to filter program may require changes to the | ||||
|  |      * insn number(s) used below! | ||||
|  |      */ | ||||
|  |     friUpdSock_bpf_filter[8].k = socketPort; | ||||
|  | 
 | ||||
|  |     bpfDrv(); | ||||
|  | 
 | ||||
|  |     if ( bpfDevCreate("/dev/bpf",2,4096) == ERROR) | ||||
|  |     { | ||||
|  |         printf("bpfDevCreate failed \n"); | ||||
|  |         return; | ||||
|  |     } | ||||
|  |     bpffd = open( "/dev/bpf0",0,0); | ||||
|  |     if ( bpffd <= 0) | ||||
|  |     { | ||||
|  |         printf("open /dev/bpf0 failed\n"); | ||||
|  |         return; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     memset(&ifr, sizeof(struct ifreq), 0);  | ||||
|  |     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));  | ||||
|  | 
 | ||||
|  | #define IOCTRL_CAST_THIRD_ARG (int)
 | ||||
|  | 
 | ||||
|  |     if (ioctl(bpffd,BIOCIMMEDIATE, IOCTRL_CAST_THIRD_ARG &trueValue) < 0)  | ||||
|  |     { | ||||
|  |         printf("Error BIOCIMMEDIATE \n"); | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     if (ioctl(bpffd,(BIOCSETF),IOCTRL_CAST_THIRD_ARG (caddr_t)(&mybpf)) < 0)  | ||||
|  |     { | ||||
|  |         perror("Error BIOCSETF \n"); | ||||
|  |         goto errorMark; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     if (ioctl(bpffd,(BIOCSETIF),IOCTRL_CAST_THIRD_ARG (caddr_t)&ifr) < 0)  | ||||
|  |     { | ||||
|  |         printf("ERROR BIOCSETIF %s \n",dev); | ||||
|  |         goto errorMark; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     if (ioctl(bpffd,BIOCGBLEN, IOCTRL_CAST_THIRD_ARG &buflen) < 0)  | ||||
|  |     { | ||||
|  |         printf("Error BIOCGBLEN \n"); | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     if (buflen > 4096) | ||||
|  |         buflen=4096; | ||||
|  | 
 | ||||
|  |     buf = (struct bpf_hdr *)malloc(buflen);  | ||||
|  |     //bzero(buf,buflen);  
 | ||||
|  |     memset(buf,0x0,buflen); | ||||
|  | 
 | ||||
|  |     while ((len = read(bpffd,(char *)buf,buflen)) != 0)  | ||||
|  |     { | ||||
|  |         // im bpf header steht noch ein Timestamp -- waere gut fuer Timing thematik
 | ||||
|  |         //
 | ||||
|  | 
 | ||||
|  |         //  Empfangene Rohdaten ohne bpf Header 
 | ||||
|  |         pbuffer = (char *)buf + buf->bh_hdrlen;  | ||||
|  | 
 | ||||
|  |         // Empfangene Rohdatenlaenge ohne bpf Header
 | ||||
|  |         Rcvlen = len - (buf->bh_hdrlen);  | ||||
|  |         //
 | ||||
|  |         // Wie trennt man nun die "Nutzdaten" von den Verwaltungsdaten??
 | ||||
|  |         //
 | ||||
|  | 
 | ||||
|  |         struct ip * iph = (struct ip *) ((char *) buf + buf->bh_hdrlen + sizeof(struct ether_header)); | ||||
|  |         struct udphdr * udph = (struct udphdr *) ((char *) iph + sizeof(struct ip)); | ||||
|  |         char * userData = ((char *) udph) + sizeof( struct udphdr);  | ||||
|  | 
 | ||||
|  |         tFriCmdData * cmd = ( tFriCmdData * ) userData; | ||||
|  | #ifdef DEBUG_BPF_READ
 | ||||
|  |         printf("recvLen %d\n",Rcvlen); | ||||
|  |         printf("IP SRC:\t\t%s\n", inet_ntoa(iph->ip_src)); | ||||
|  |         printf("IP DST:\t\t%s\n", inet_ntoa(iph->ip_dst)); | ||||
|  |         printf("UDP SRC:\t%u\n", ntohs(udph->uh_sport)); | ||||
|  |         printf("UDP DST:\t%u\n", ntohs(udph->uh_dport)); | ||||
|  |         printf("Len #:\t\t%u\n", ntohs(udph->uh_ulen)); | ||||
|  | #endif
 | ||||
|  | 
 | ||||
|  |         logMsg("BUF LEN = 0x%x\n",Rcvlen,0,0,0,0,0);  | ||||
|  | 
 | ||||
|  |         std::cout << (*cmd) << std::endl; | ||||
|  |         for (i=0;i< ntohs(udph->uh_ulen);i++)  | ||||
|  |         { | ||||
|  |             printf(" %2x", userData[i]); | ||||
|  |             if ((i % 10) == 9) | ||||
|  |             { | ||||
|  |                 printf("\n");//,0,0,0,0,0,0);
 | ||||
|  |             } | ||||
|  |         } | ||||
|  |         printf("\nFull packet \n"); | ||||
|  |         for (i=0; i < Rcvlen; i++)  | ||||
|  |         { | ||||
|  |             printf(" %2x(%4d)", pbuffer[i],pbuffer[i]); | ||||
|  |             if ((i % 10) == 9) | ||||
|  |             { | ||||
|  |                 printf("\n");//,0,0,0,0,0,0);
 | ||||
|  |             } | ||||
|  |        } | ||||
|  |     } | ||||
|  | errorMark: | ||||
|  |     printf("leaving %s\n",__PRETTY_FUNCTION__); | ||||
|  |     if ( buf != NULL ) | ||||
|  |         free(buf); | ||||
|  |     if ( bpffd > 0 ) | ||||
|  |         close (bpffd); | ||||
|  |     bpfDevDelete("/dev/bpf"); | ||||
|  | } | ||||
|  | #endif
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | /*****************************************************************************
 | ||||
|  |  $Log: $ | ||||
|  |  *****************************************************************************/ | ||||
|  | /* @} */ | ||||
| @ -0,0 +1,257 @@ | |||||
|  | /*{{[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] | ||||
|  | **************************************************************************** | ||||
|  |   friUdp.h | ||||
|  |         | ||||
|  |       NOTE: This sample, as the corresponding FRI (Fast Research inteface) is subject to radical change | ||||
|  |        | ||||
|  |        | ||||
|  | [FH]}} | ||||
|  | */  | ||||
|  | /** | ||||
|  |     \addtogroup friRemoteLib | ||||
|  |     \brief Library for FRI (FastResearchInterface)  | ||||
|  | */ | ||||
|  | /* @{ */ | ||||
|  | /** ************************************************************************* | ||||
|  |  \author (Guenter Schreiber) | ||||
|  | \file | ||||
|  | \brief header for udp Communications | ||||
|  |  *                                                                         * | ||||
|  |  ***************************************************************************/ | ||||
|  | #ifndef FRIFRIUDP_H | ||||
|  | #define FRIFRIUDP_H | ||||
|  | 
 | ||||
|  | #ifdef VXWORKS | ||||
|  | #else | ||||
|  | #define HAVE_GETHOSTNAME | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | #include <stdio.h> | ||||
|  | #include <stdlib.h> | ||||
|  | 
 | ||||
|  | #ifdef _MSC_VER | ||||
|  | #include "SocketObject.h" | ||||
|  | #else | ||||
|  | #include <sys/socket.h> | ||||
|  | #include <netinet/in.h> | ||||
|  | #include <arpa/inet.h> | ||||
|  | #include <unistd.h> | ||||
|  | #include <netdb.h> | ||||
|  | #include <string.h> | ||||
|  | #ifndef _WRS_KERNEL | ||||
|  | #include <sys/time.h> | ||||
|  | #endif | ||||
|  | #include <time.h> | ||||
|  | #endif | ||||
|  | #include "friComm.h" | ||||
|  | 
 | ||||
|  | #include <iostream> | ||||
|  | 
 | ||||
|  | #ifdef VXWORKS // VxWorks Kernel | ||||
|  | 
 | ||||
|  | #include <sockLib.h> | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | #define FRI_DEFAULT_SERVER_PORT 49938 | ||||
|  | 
 | ||||
|  | #ifdef QNX | ||||
|  | #define HAVE_TIME_STAMP_RECEIVE | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | #ifdef HAVE_TIME_STAMP_RECEIVE | ||||
|  | /** Receive Timestamp -- mechanism works under  | ||||
|  | QNX, Linux? | ||||
|  | 
 | ||||
|  | Not under Windows - and under VxWorks | ||||
|  | */ | ||||
|  | 
 | ||||
|  | typedef struct | ||||
|  | { | ||||
|  |     tFriMsrData load; | ||||
|  |     /* add a received-timestamp */ | ||||
|  |     double timestamp; | ||||
|  | } tFriMsrPacket; | ||||
|  | 
 | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | /** | ||||
|  | FRI Remote Sample Implementation | ||||
|  | 
 | ||||
|  |     @author Günter Schreiber <guenter@jacobus> | ||||
|  | */ | ||||
|  | class friUdp | ||||
|  | { | ||||
|  | public: | ||||
|  |     friUdp(int port=FRI_DEFAULT_SERVER_PORT, char *remoteHost = NULL); | ||||
|  |     ~friUdp(); | ||||
|  | 
 | ||||
|  | protected: | ||||
|  |     /// Note: Remote host need not to be specified - if NULL, wait for the  | ||||
|  |     /// incoming packages | ||||
|  |     void Init(char * remoteHost=NULL); | ||||
|  |     void Close(void); | ||||
|  | #ifdef WIN32 | ||||
|  |     int StartWinsock(void); | ||||
|  | #endif | ||||
|  | public: | ||||
|  |     int Send(tFriCmdData *data); | ||||
|  |     int Recv(tFriMsrData *packet); | ||||
|  | private: | ||||
|  |     int RecvPacket(int fd, tFriMsrData* p, struct timeval* ts, struct sockaddr_in* client); | ||||
|  |     int udpSock ; | ||||
|  |     int serverPort; | ||||
|  |     struct sockaddr_in krcAddr; | ||||
|  |     /// if timestamp on receive is available, last received value can be inquired here | ||||
|  |     double m_timestamp; | ||||
|  | public: | ||||
|  |     /// This feature will be available only for systems, which support  | ||||
|  |     /// SO_TIMESTAMP in the socket options, e.g. qnx | ||||
|  |     double  getLastTimestamp() { return m_timestamp; } | ||||
|  | }; | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | inline std::ostream & operator<<(std::ostream &out , tFriHeader & head) | ||||
|  | { | ||||
|  |   out << "sendSeqCount " << head.sendSeqCount << "\n"; | ||||
|  |   out << "reflSeqCount " << head.reflSeqCount << "\n"; | ||||
|  |   out << "packetSize   " << head.packetSize   << "\n"; | ||||
|  |   out << "datagramId   " << std::hex  << head.datagramId << std::dec  ; | ||||
|  |   switch (head.datagramId ) | ||||
|  |   { | ||||
|  |   case FRI_DATAGRAM_ID_CMD: | ||||
|  |       out << " FRI_DATAGRAM_ID_CMD \n" ; | ||||
|  |       break; | ||||
|  |   case FRI_DATAGRAM_ID_MSR: | ||||
|  |       out << " FRI_DATAGRAM_ID_MSR \n" ; | ||||
|  |       break; | ||||
|  |   default: | ||||
|  |       out <<" Unkown \n"; | ||||
|  |   } | ||||
|  |   return out; | ||||
|  | } | ||||
|  | inline std::ostream & operator<<(std::ostream &out , tFriKrlData& krl) | ||||
|  | { | ||||
|  |     out << "krl_real "; | ||||
|  |   for ( int i = 0; i < FRI_USER_SIZE; i++) | ||||
|  |   out << " " << krl.realData[i]; | ||||
|  |   out << "\n"; | ||||
|  |     out << "krl_int "; | ||||
|  |   for ( int i = 0; i < FRI_USER_SIZE; i++) | ||||
|  |   out << " " << krl.intData[i]; | ||||
|  |   out << "\n"; | ||||
|  |     out << "krl_bool "; | ||||
|  |   out << std::hex << krl.boolData << std::dec << "\n"; | ||||
|  |   return out; | ||||
|  | } | ||||
|  | 
 | ||||
|  | inline std::ostream & operator<<(std::ostream &out , tFriIntfStatistics & stat) | ||||
|  | { | ||||
|  |   out << "answerRate  " << stat.answerRate << "\n"; | ||||
|  |   out << "latency     " << stat.latency << "\n"; | ||||
|  |   out << "jitter      " << stat.jitter << "\n"; | ||||
|  |   out << "missRate    " << stat.missRate << "\n"; | ||||
|  |   out << "missCounter " << stat.missCounter << "\n"; | ||||
|  |   return out; | ||||
|  | } | ||||
|  | 
 | ||||
|  | inline std::ostream & operator<<(std::ostream &out , tFriIntfState & state) | ||||
|  | { | ||||
|  |   out << "timestamp " << state.timestamp<< "\n"; | ||||
|  |   out << "state     " << state.state<< "\n"; | ||||
|  |   out << "quality   " << state.quality << "\n"; | ||||
|  |   out << "desiredMsrSampleTime " << state.desiredMsrSampleTime << "\n"; | ||||
|  |   out << "desiredCmdSampleTiintfme " << state.desiredCmdSampleTime  << "\n"; | ||||
|  |   out << "safetyLimits " << state.safetyLimits << "\n"; | ||||
|  |   out << "statistics " << state.stat << "\n"; | ||||
|  | return out; | ||||
|  | } | ||||
|  | 
 | ||||
|  | inline std::ostream & operator<< (std::ostream & out, tFriRobotState & robot) | ||||
|  | { | ||||
|  |   out << "power   " << robot.power<< "\n"; | ||||
|  |   out << "control " << robot.control << "\n"; | ||||
|  |   out << "error   " << robot.error << "\n"; | ||||
|  |   out << "warning " << robot.warning << "\n"; | ||||
|  |   out << "temperature " ; | ||||
|  |   for (int i = 0; i < LBR_MNJ; i++) | ||||
|  |     out << robot.temperature[i] << " " ; | ||||
|  |   out << "\n"; | ||||
|  |   return out; | ||||
|  | 
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | #define WRITE_JNT_VEC(field) \ | ||||
|  |   out << ""#field; \ | ||||
|  |   for ( int i  = 0; i < LBR_MNJ; i++) \ | ||||
|  |   out << " " << robot.field[i]; \ | ||||
|  |   out << "\n"; | ||||
|  | inline std::ostream & operator<<(std::ostream &out, tFriRobotData & robot) | ||||
|  | { | ||||
|  |   WRITE_JNT_VEC(msrJntPos); | ||||
|  |   WRITE_JNT_VEC(cmdJntPos); | ||||
|  |   WRITE_JNT_VEC(msrJntTrq); | ||||
|  |   WRITE_JNT_VEC(estExtJntTrq); | ||||
|  |     return out; | ||||
|  | 
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | inline std::ostream & operator<<(std::ostream &out, tFriRobotCommand & robot) | ||||
|  | { | ||||
|  |   out << std::hex << robot.cmdFlags << std::dec << "\n"; | ||||
|  |   WRITE_JNT_VEC(jntPos); | ||||
|  |     return out; | ||||
|  | 
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | inline std::ostream & operator<<(std::ostream &out, tFriMsrData & msr) | ||||
|  | { | ||||
|  |   out << "head " << msr.head; | ||||
|  |   out << "krl " << msr.krl; | ||||
|  |   out << "intf " << msr.intf; | ||||
|  |   out << "robot " << msr.robot; | ||||
|  |   out << "data " << msr.data; | ||||
|  |   return out; | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | inline std::ostream & operator<<(std::ostream &out, tFriCmdData & cmd) | ||||
|  | { | ||||
|  |   out << "head " << cmd.head; | ||||
|  |   out << "krl " << cmd.krl; | ||||
|  |   out << "cmd " << cmd.cmd; | ||||
|  |     return out; | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | #endif | ||||
|  | /* @} */ | ||||
| @ -0,0 +1,36 @@ | |||||
|  | bool __SVR_CURRENT_JOB = false; | ||||
|  | bool __MSRMSRJNTPOS = false; | ||||
|  | bool __MSRCMDJNTPOS = false; | ||||
|  | bool __MSRCMDPOSE = false; | ||||
|  | bool __SETVELOCITY = false; | ||||
|  | bool __SETACCEL = false; | ||||
|  | bool __DEBUG = false; | ||||
|  | bool __POTFIELDMODE = false; | ||||
|  | bool __MSRSTARTPOTFIELD = false; | ||||
|  | bool __MSRSTOPPOTFIELD = false; | ||||
|  | bool __MSRSETPOS = false; | ||||
|  | bool __CARTMOVE = false; | ||||
|  | bool __DOUS = false; | ||||
|  | bool __DOUS2 = false; | ||||
|  | 
 | ||||
|  | int globi = 0; | ||||
|  | 
 | ||||
|  | float MSRMSRJNTPOS[7]; | ||||
|  | double MSRCMDJNTPOS[7]; | ||||
|  | double MSRMSRCARTPOS[12]; | ||||
|  | float MSRCMDCARTPOS[12]; | ||||
|  | double MSRMSRJACOBIAN[42]; | ||||
|  | double MSRMSRFTTCP[6]; | ||||
|  | double MSRCMDPOSE[3][4]; | ||||
|  | float USTarget[12]; | ||||
|  | float USApproach[12]; | ||||
|  | double VELOCITY = 20; | ||||
|  | double ACCELARATION = 10; | ||||
|  | double maxVelJnt[] = {110.0,110.0,128.0,128.0,204.0,184.0,184.0}; | ||||
|  | double maxAccJnt[] = {1.0,1.0,1.0,1.0,2.0,1.0,1.0}; | ||||
|  | double maxTrqJnt[] = {176.0,176.0,100.0,100.0,100.0,38.0,38.0}; | ||||
|  | double maxRangeJnt[] = {170.0,120.0,170.0,120.0,170.0,120.0,170.0}; | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
| @ -0,0 +1,32 @@ | |||||
|  | extern bool __SVR_CURRENT_JOB; | ||||
|  | extern bool __MSRMSRJNTPOS; | ||||
|  | extern bool __MSRCMDJNTPOS; | ||||
|  | extern bool __MSRCMDPOSE; | ||||
|  | extern bool __SETVELOCITY; | ||||
|  | extern bool __SETACCEL; | ||||
|  | extern bool __DEBUG; | ||||
|  | extern bool __POTFIELDMODE; | ||||
|  | extern bool __MSRSTARTPOTFIELD; | ||||
|  | extern bool __MSRSTOPPOTFIELD; | ||||
|  | extern bool __MSRSETPOS; | ||||
|  | extern bool __CARTMOVE; | ||||
|  | extern bool __DOUS; | ||||
|  | extern bool __DOUS2; | ||||
|  | 
 | ||||
|  | extern int globi; | ||||
|  | 
 | ||||
|  | extern float MSRMSRJNTPOS[7]; | ||||
|  | extern double MSRMSRCARTPOS[12]; | ||||
|  | extern float MSRCMDCARTPOS[12]; | ||||
|  | extern double MSRMSRJACOBIAN[42]; | ||||
|  | extern double MSRMSRFTTCP[6]; | ||||
|  | extern double MSRCMDJNTPOS[7]; | ||||
|  | extern double MSRCMDPOSE[3][4]; | ||||
|  | extern float USTarget[12]; | ||||
|  | extern float USApproach[12]; | ||||
|  | extern double VELOCITY; | ||||
|  | extern double ACCELARATION; | ||||
|  | extern double maxVelJnt[LBR_MNJ]; | ||||
|  | extern double maxAccJnt[LBR_MNJ]; | ||||
|  | extern double maxTrqJnt[LBR_MNJ]; | ||||
|  | extern double maxRangeJnt[LBR_MNJ]; | ||||
| @ -0,0 +1,24 @@ | |||||
|  | #include <iostream> | ||||
|  | #include <sstream> | ||||
|  | #include "defines.h" | ||||
|  | #include "SocketObject.h" | ||||
|  | #include "SvrHandling.h" | ||||
|  | #include "StringTool.h" | ||||
|  | #include <string> | ||||
|  | #include "pthread.h" | ||||
|  | #include "friremote.h" | ||||
|  | #include "math.h" | ||||
|  | #include <cmath> | ||||
|  | #include "mat.h" | ||||
|  | #include "vec.h" | ||||
|  | //#include "opencv2\opencv.hpp" | ||||
|  | //#pragma comment (lib, "opencv_core248d.lib") | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | //debug | ||||
|  | #include <algorithm> | ||||
|  | //end debug | ||||
|  | 
 | ||||
|  | using namespace std; | ||||
|  | //using namespace cv; | ||||
|  | 
 | ||||
| @ -0,0 +1,354 @@ | |||||
|  | #ifndef _MAT_H_ | ||||
|  | #define _MAT_H_ | ||||
|  | #include <iostream> | ||||
|  | #include "vec.h" | ||||
|  | 
 | ||||
|  | template <class T, unsigned SIZE> class CVector; | ||||
|  | 
 | ||||
|  | // template square matrix class for SIMPLE data types  | ||||
|  | template <class T, unsigned SIZE> class Mat  | ||||
|  | { | ||||
|  | public: | ||||
|  | 
 | ||||
|  |     Mat<T, SIZE> () | ||||
|  |     { | ||||
|  |         for (unsigned int j=0; j<SIZE; j++) | ||||
|  |         { | ||||
|  |             for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             { | ||||
|  |                 m_aatData[i][j] = T(0); | ||||
|  |             } | ||||
|  |         } | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     ~Mat<T, SIZE> () | ||||
|  |     { | ||||
|  |         // nothing to do here ... | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     Mat<T, SIZE> (const T aatData[SIZE][SIZE]) | ||||
|  |     { | ||||
|  |         for (unsigned int j=0; j<SIZE; j++) | ||||
|  |         { | ||||
|  |             for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             { | ||||
|  |                 m_aatData[i][j] = aatData[i][j]; | ||||
|  |             } | ||||
|  |         } | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     Mat<T, SIZE> (const Mat<T, SIZE> &mat) | ||||
|  |     { | ||||
|  |         for (unsigned int j=0; j<SIZE; j++) | ||||
|  |         { | ||||
|  |             for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             { | ||||
|  |                 m_aatData[i][j] = mat.m_aatData[i][j]; | ||||
|  |             } | ||||
|  |         } | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     T &operator () (unsigned i, unsigned j) | ||||
|  |     { | ||||
|  |         if (i>=SIZE) | ||||
|  |             i = SIZE-1; | ||||
|  |         if (j>=SIZE) | ||||
|  |             j = SIZE-1; | ||||
|  |         return m_aatData[i][j]; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     T operator () (unsigned i, unsigned j) const | ||||
|  |     { | ||||
|  |         if (i>=SIZE) | ||||
|  |             i = SIZE-1; | ||||
|  |         if (j>=SIZE) | ||||
|  |             j = SIZE-1; | ||||
|  |         return m_aatData[i][j]; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     // CMatrix<T, SIZE>operator + (const Matrix<T, SIZE> &mat) | ||||
|  |     // CMatrix<T, SIZE>operator - (const Matrix<T, SIZE> &mat) | ||||
|  |     // ... | ||||
|  | 
 | ||||
|  |     Mat<T, SIZE> operator * (const Mat<T, SIZE> &mat) | ||||
|  |     { | ||||
|  |         Mat<T, SIZE> buf; | ||||
|  |         for (unsigned int i=0; i<SIZE; i++) // ZEILE i | ||||
|  |             for (unsigned int j=0; j<SIZE; j++) // Spalte j | ||||
|  |                 for (unsigned int a=0; a<SIZE; a++) // a | ||||
|  |                     buf(i,j) += m_aatData[i][a] * mat(a,j); | ||||
|  |         return buf; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     Vec<T, SIZE> operator * (const Vec<T, SIZE> &vec) | ||||
|  |     { | ||||
|  |         Vec<T, SIZE> buf; | ||||
|  |         for (unsigned int j=0; j<SIZE; j++) // SPALTE j | ||||
|  |             for (unsigned int i=0; i<SIZE; i++) // ZEILE i | ||||
|  |                 buf(i) += m_aatData[i][j]*vec(j); | ||||
|  |         return buf; | ||||
|  |     } | ||||
|  |     Mat<float, 4> inv() | ||||
|  |     { | ||||
|  |         Mat<float,4> invOut; | ||||
|  | 
 | ||||
|  |         long indxc[4], indxr[4], ipiv[4]; | ||||
|  |         long i, icol, irow, j, ir, ic; | ||||
|  |         long big, dum, pivinv,temp, bb; | ||||
|  | 
 | ||||
|  |         ipiv[0] = -1; | ||||
|  |         ipiv[1] = -1; | ||||
|  |         ipiv[2] = -1; | ||||
|  |         ipiv[3] = -1; | ||||
|  | 
 | ||||
|  |         invOut = *this; | ||||
|  | 
 | ||||
|  | 
 | ||||
|  |         for (i =0; i < 4 ; i++) { | ||||
|  |             big =0.0f; | ||||
|  |             for (j =0; j < 4 ; j++) { | ||||
|  |                 if (ipiv[j] != 0) { | ||||
|  |                     if (ipiv[0] == - 1) { | ||||
|  |                         if ((bb = (float) fabs(invOut(j,0))) > big) { | ||||
|  |                             big = bb; | ||||
|  |                             irow = j; | ||||
|  |                             icol = 0; | ||||
|  |                             } | ||||
|  |                     } else if (ipiv[0] > 0) { | ||||
|  |                         goto end; | ||||
|  |                     } | ||||
|  | 
 | ||||
|  |                     if (ipiv[1] == - 1) { | ||||
|  |                         if ((bb = (float) fabs(invOut(j,1))) > big) { | ||||
|  |                             big = bb; | ||||
|  |                             irow = j; | ||||
|  |                             icol = 1; | ||||
|  |                         } | ||||
|  |                     } else if (ipiv[1] > 0) { | ||||
|  |                         goto end; | ||||
|  |                     } | ||||
|  | 
 | ||||
|  |                     if (ipiv[2] == - 1) { | ||||
|  |                         if ((bb = (float) fabs(invOut(j,2))) > big) { | ||||
|  |                             big = bb; | ||||
|  |                             irow = j; | ||||
|  |                             icol = 2; | ||||
|  |                         } | ||||
|  |                     } else if (ipiv[2] > 0) { | ||||
|  |                         goto end; | ||||
|  |                     } | ||||
|  | 
 | ||||
|  |                     if (ipiv[3] == - 1) { | ||||
|  |                         if ((bb = (float) fabs(invOut(j,3))) > big) { | ||||
|  |                             big = bb; | ||||
|  |                             irow = j; | ||||
|  |                             icol = 3; | ||||
|  |                         } | ||||
|  |                     } else if (ipiv[3] > 0) { | ||||
|  |                         goto end; | ||||
|  |                     } | ||||
|  |                 } | ||||
|  |             } | ||||
|  |             ++(ipiv[icol]); | ||||
|  | 
 | ||||
|  |             if (irow != icol) { | ||||
|  |                 temp = invOut(irow,0); | ||||
|  |                 invOut(irow, 0) = invOut(icol, 0); | ||||
|  |                 invOut(icol, 0) = temp; | ||||
|  | 
 | ||||
|  |                 temp = invOut(irow,1); | ||||
|  |                 invOut(irow, 1) = invOut(icol, 1); | ||||
|  |                 invOut(icol,1) = temp; | ||||
|  | 
 | ||||
|  |                 temp = invOut(irow,2); | ||||
|  |                 invOut(irow,2) = invOut(icol,2); | ||||
|  |                 invOut(icol,2) = temp; | ||||
|  | 
 | ||||
|  |                 temp = invOut(irow,3); | ||||
|  |                 invOut(irow,3) = invOut(icol,3); | ||||
|  |                 invOut(icol,3) = temp; | ||||
|  |             } | ||||
|  | 
 | ||||
|  |             indxr[i] = irow; | ||||
|  |             indxc[i] = icol; | ||||
|  | 
 | ||||
|  |             if (invOut(icol,icol) ==0.0) { | ||||
|  |                 goto end; | ||||
|  |             } | ||||
|  | 
 | ||||
|  |             pivinv =1.0f / invOut(icol,icol); | ||||
|  |             invOut(icol,icol) =1.0f; | ||||
|  |             invOut(icol,0) *= pivinv; | ||||
|  |             invOut(icol,1) *= pivinv; | ||||
|  |             invOut(icol,2) *= pivinv; | ||||
|  |             invOut(icol,3) *= pivinv; | ||||
|  | 
 | ||||
|  |             if (icol != 0) { | ||||
|  |                 dum = invOut(0,icol); | ||||
|  |                 invOut(0,icol) =0.0f; | ||||
|  |                 invOut(0,0) -= invOut(icol,0) * dum; | ||||
|  |                 invOut(0,1) -= invOut(icol,1) * dum; | ||||
|  |                 invOut(0,2) -= invOut(icol,2) * dum; | ||||
|  |                 invOut(0,3) -= invOut(icol,3) * dum; | ||||
|  |             } | ||||
|  | 
 | ||||
|  |             if (icol != 1) { | ||||
|  |                 dum = invOut(1,icol); | ||||
|  |                 invOut(1,icol) =0.0f; | ||||
|  |                 invOut(1,0) -= invOut(icol,0) * dum; | ||||
|  |                 invOut(1,1) -= invOut(icol,1) * dum; | ||||
|  |                 invOut(1,2) -= invOut(icol,2) * dum; | ||||
|  |                 invOut(1,3) -= invOut(icol,3) * dum; | ||||
|  |             } | ||||
|  | 
 | ||||
|  |             if (icol != 2) { | ||||
|  |                 dum = invOut(2,icol); | ||||
|  |                 invOut(2,icol) =0.0f; | ||||
|  |                 invOut(2,0) -= invOut(icol,0) * dum; | ||||
|  |                 invOut(2,1) -= invOut(icol,1) * dum; | ||||
|  |                 invOut(2,2) -= invOut(icol,2) * dum; | ||||
|  |                 invOut(2,3) -= invOut(icol,3) * dum; | ||||
|  |             } | ||||
|  | 
 | ||||
|  |             if (icol != 3) { | ||||
|  |                 dum = invOut(3,icol); | ||||
|  |                 invOut(3,icol) =0.0f; | ||||
|  |                 invOut(3,0) -= invOut(icol,0) * dum; | ||||
|  |                 invOut(3,1) -= invOut(icol,1) * dum; | ||||
|  |                 invOut(3,2) -= invOut(icol,2) * dum; | ||||
|  |                 invOut(3,3) -= invOut(icol,3) * dum; | ||||
|  |             } | ||||
|  |         } | ||||
|  |         if (indxr[3] != indxc[3]) { | ||||
|  |             ir = indxr[3]; | ||||
|  |             ic = indxc[3]; | ||||
|  |             temp = invOut(0,ir); | ||||
|  |             invOut(0,ir) = invOut(0,ic); | ||||
|  |             invOut(0,ic) = temp; | ||||
|  |             temp = invOut(1,ir); | ||||
|  |             invOut(1,ir) = invOut(1,ic); | ||||
|  |             invOut(1,ic) = temp; | ||||
|  |             temp = invOut(2,ir); | ||||
|  |             invOut(2,ir) = invOut(2,ic); | ||||
|  |             invOut(2,ic) = temp; | ||||
|  |             temp = invOut(3,ir); | ||||
|  |             invOut(3,ir) = invOut(3,ic); | ||||
|  |             invOut(3,ic) = temp; | ||||
|  |         } | ||||
|  |         if (indxr[2] != indxc[2]) { | ||||
|  |             ir = indxr[2]; | ||||
|  |             ic = indxc[2]; | ||||
|  | 
 | ||||
|  |             temp = invOut(0,ir); | ||||
|  |             invOut(0,ir) = invOut(0,ic); | ||||
|  |             invOut(0,ic) = temp; | ||||
|  | 
 | ||||
|  |             temp = invOut(1,ir); | ||||
|  |             invOut(1,ir) = invOut(1,ic); | ||||
|  |             invOut(1,ic) = temp; | ||||
|  | 
 | ||||
|  |             temp = invOut(2,ir); | ||||
|  |             invOut(2,ir) = invOut(2,ic); | ||||
|  |             invOut(2,ic) = temp; | ||||
|  | 
 | ||||
|  |             temp = invOut(3,ir); | ||||
|  |             invOut(3,ir) = invOut(3,ic); | ||||
|  |             invOut(3,ic) = temp; | ||||
|  |         } | ||||
|  |         if (indxr[1] != indxc[1]) { | ||||
|  |             ir = indxr[1]; | ||||
|  |             ic = indxc[1]; | ||||
|  |             temp = invOut(0,ir); | ||||
|  |             invOut(0,ir) = invOut(0,ic); | ||||
|  |             invOut(0,ic) = temp; | ||||
|  |             temp = invOut(1,ir); | ||||
|  |             invOut(1,ir) = invOut(1,ic); | ||||
|  |             invOut(1,ic) = temp; | ||||
|  |             temp = invOut(2,ir); | ||||
|  |             invOut(2,ir) = invOut(2,ic); | ||||
|  |             invOut(2,ic) = temp; | ||||
|  |             temp = invOut(3,ir); | ||||
|  |             invOut(3,ir) = invOut(3,ic); | ||||
|  |             invOut(3,ic) = temp; | ||||
|  |         } | ||||
|  |         if (indxr[0] != indxc[0]) { | ||||
|  |             ir = indxr[0]; | ||||
|  |             ic = indxc[0]; | ||||
|  |             temp = invOut(0,ir); | ||||
|  |             invOut(0,ir) = invOut(0,ic); | ||||
|  |             invOut(0,ic) = temp; | ||||
|  |             temp = invOut(1,ir); | ||||
|  |             invOut(1,ir) = invOut(1,ic); | ||||
|  |             invOut(1,ic) = temp; | ||||
|  |             temp = invOut(2,ir); | ||||
|  |             invOut(2,ir) = invOut(2,ic); | ||||
|  |             invOut(2,ic) = temp; | ||||
|  |             temp = invOut(3,ir); | ||||
|  |             invOut(3,ir) = invOut(3,ic); | ||||
|  |             invOut(3,ic) = temp; | ||||
|  |         } | ||||
|  | end: | ||||
|  |         return invOut; | ||||
|  |     } | ||||
|  | 
 | ||||
|  | private: | ||||
|  |     T m_aatData[SIZE][SIZE]; | ||||
|  | }; | ||||
|  | // some common vector classes (abbr. names) | ||||
|  | typedef Mat<float, 2> Mat2f; | ||||
|  | typedef Mat<float, 3> Mat3f; | ||||
|  | typedef Mat<float, 4> Mat4f; | ||||
|  | 
 | ||||
|  | typedef Mat<double, 2> Mat2d; | ||||
|  | typedef Mat<double, 3> Mat3d; | ||||
|  | typedef Mat<double, 4> Mat4d; | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | template <class T, unsigned SIZE> | ||||
|  | static std::ostream& operator<< (std::ostream& output,const Mat<T,SIZE> &mat) | ||||
|  | { | ||||
|  |     output << "( "; | ||||
|  |     for(unsigned int j =0; j< SIZE; ++j) | ||||
|  |     { | ||||
|  |         output << "( "; | ||||
|  |         for(unsigned int i =0; i< SIZE; ++i) | ||||
|  |         { | ||||
|  |             output << mat(j,i); | ||||
|  |             if (i<4-1) | ||||
|  |                 output << " , "; | ||||
|  |             else | ||||
|  |                 output << " )"; | ||||
|  |         } | ||||
|  |         if (j<SIZE-1) | ||||
|  |             output << " ) ; "; | ||||
|  |         else | ||||
|  |             output << " ) )"; | ||||
|  |     } | ||||
|  |     return output; | ||||
|  | } | ||||
|  | static Mat<float, 4> getRotationMatrix(float x_angle,float y_angle, float z_angle) | ||||
|  | { | ||||
|  |     Mat<float,4> tempx,tempy,tempz; | ||||
|  |     float temp_x[4][4] = { { 1,            0,             0, 0}, | ||||
|  |                            { 0, cos(x_angle), -sin(x_angle), 0}, | ||||
|  |                            { 0, sin(x_angle),  cos(x_angle), 0}, | ||||
|  |                            { 0,            0,             0, 1} | ||||
|  |                          }; | ||||
|  | 
 | ||||
|  |     float temp_y[4][4] = { { cos(y_angle), 0, -sin(y_angle), 0}, | ||||
|  |                            {            0, 1,             0, 0}, | ||||
|  |                            { sin(y_angle), 0,  cos(y_angle), 0}, | ||||
|  |                            {            0, 0,             0, 1} | ||||
|  |                          }; | ||||
|  |     float temp_z[4][4] = { { cos(z_angle), -sin(z_angle), 0, 0}, | ||||
|  |                            { sin(z_angle),  cos(z_angle), 0, 0}, | ||||
|  |                            {            0,             0, 1, 0}, | ||||
|  |                            {            0,             0, 0, 1} | ||||
|  |                           }; | ||||
|  | 
 | ||||
|  |     tempx=temp_x; | ||||
|  |     tempy=temp_y; | ||||
|  |     tempz=temp_z; | ||||
|  |     return tempz*tempy*tempx; | ||||
|  | } | ||||
|  | #endif | ||||
| @ -0,0 +1,520 @@ | |||||
|  | #include "header.h"
 | ||||
|  | #include "global.h"
 | ||||
|  | #include "sgn.h"
 | ||||
|  | #include <error.h>
 | ||||
|  | #include <errno.h>
 | ||||
|  | 
 | ||||
|  | void printMat(Mat4f M) | ||||
|  | { | ||||
|  | #if 0
 | ||||
|  |     for (int i=0;i<M.rows;i++) | ||||
|  |     { | ||||
|  |         for (int j=0;j<M.cols;j++) | ||||
|  |         { | ||||
|  |             cout << M.at<float>(i,j) << " "; | ||||
|  |         } | ||||
|  |         cout << "\n\r"; | ||||
|  |     } | ||||
|  |     cout << "\n\r\n\r"; | ||||
|  | #else
 | ||||
|  |     cout << M << endl; | ||||
|  | #endif 
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | float* abctomat(float a, float b, float c) | ||||
|  | { | ||||
|  |     Mat4f rx; | ||||
|  |     float ca = cos(c); | ||||
|  |     float sa = sin(c); | ||||
|  | 
 | ||||
|  |     rx(0,0) = 1; | ||||
|  |     rx(1,1) = ca;  | ||||
|  |     rx(1,2) = -sa; | ||||
|  |     rx(2,1) = sa;  | ||||
|  |     rx(2,2) = ca;  | ||||
|  |     rx(3,3) = 1; | ||||
|  | 
 | ||||
|  |     Mat4f ry; | ||||
|  |     float cb = cos(b); | ||||
|  |     float sb = sin(b); | ||||
|  |     ry(0,0) = cb; | ||||
|  |     ry(0,2) = sb; | ||||
|  |     ry(1,1) = 1; | ||||
|  |     ry(2,0) = -sb; | ||||
|  |     ry(2,2) = cb;  | ||||
|  |     ry(3,3) = 1; | ||||
|  | 
 | ||||
|  |     Mat4f rz; | ||||
|  |     float cc = cos(a); | ||||
|  |     float sc = sin(a); | ||||
|  |     rz(0,0) = cc; | ||||
|  |     rz(0,1) = -sc; | ||||
|  |     rz(1,0) = sc; | ||||
|  |     rz(1,1) = cc; | ||||
|  |     rz(2,2) = 1;  | ||||
|  |     rz(3,3) = 1; | ||||
|  |      | ||||
|  |     Mat4f result; | ||||
|  |     Mat4f temp; | ||||
|  |     temp   = rz * ry; | ||||
|  |     result = temp * rx; | ||||
|  | 
 | ||||
|  | #ifdef __DEBUG__
 | ||||
|  |     printMat(rx); | ||||
|  |     printMat(ry); | ||||
|  |     printMat(rz); | ||||
|  |     printMat(result); | ||||
|  | #endif
 | ||||
|  | 
 | ||||
|  |     float *res = new float[12]; | ||||
|  |     //TODO simple converter for mat
 | ||||
|  |     for (int j=0;j<3;j++) | ||||
|  |     { | ||||
|  |         for (int k=0;k<4;k++) | ||||
|  |         { | ||||
|  |             res[j*4+k] = result(j,k); | ||||
|  |         } | ||||
|  |     } | ||||
|  |     return res; | ||||
|  | } | ||||
|  | 
 | ||||
|  | float* mattoabc(float M[12]) | ||||
|  | { | ||||
|  |     float norm; | ||||
|  |     float sa; | ||||
|  |     float ca; | ||||
|  |     float *abc = new float[3]; | ||||
|  | 
 | ||||
|  |     norm = sqrt((M[0]*M[0])+(M[4]*M[4])); | ||||
|  | 
 | ||||
|  |     if (norm>1e-5) | ||||
|  |     { | ||||
|  |         sa = M[4]/norm; | ||||
|  |         ca = M[0]/norm; | ||||
|  |         abc[0]  = atan2(sa,ca); | ||||
|  |     } | ||||
|  |     else  | ||||
|  |     { | ||||
|  |         sa = 0; | ||||
|  |         ca = 1; | ||||
|  |         abc[0] = 0; | ||||
|  |     } | ||||
|  |     abc[1] = atan2(-M[8],ca*M[0]+sa*M[4]); | ||||
|  |     abc[2] = atan2(sa*M[2]-ca*M[6],-sa*M[1]+ca*M[5]); | ||||
|  |     return abc; | ||||
|  | } | ||||
|  | 
 | ||||
|  | void doRalf()  | ||||
|  | { | ||||
|  |     // Global definitions
 | ||||
|  |     float lowStiff[6]  = {  0.01f,   0.01f,   0.01f,  0.01f,  0.01f,  0.01f}; | ||||
|  |     float highStiff[6] = {1000.0f, 1000.0f, 1000.0f,  10.0f,  10.0f,  10.0f}; | ||||
|  |     float slowDamp[6]  = { 0.007f,  0.007f,  0.007f, 0.007f, 0.007f, 0.007f}; | ||||
|  |     float fastDamp[6]  = {   0.7f,    0.7f,    0.7f,   0.7f,   0.7f,   0.7f}; | ||||
|  | 
 | ||||
|  |     float pos1[12] = { | ||||
|  |                         1.0f, 0.0f, 0.0f, 500.0f, | ||||
|  |                         0.0f, 1.0f, 0.0f,   0.0f, | ||||
|  |                         0.0f, 0.0f, 1.0f, 500.0f | ||||
|  |                      }; | ||||
|  |     float pos2[12] = { | ||||
|  |                         1.0f, 0.0f, 0.0f , 500.0f, | ||||
|  |                         0.0f, 1.0f, 0.0f ,   0.0f, | ||||
|  |                         0.0f, 0.0f ,1.0f , 500.0f | ||||
|  |                      }; | ||||
|  | 
 | ||||
|  |     friRemote friInst; | ||||
|  |     double timeCounter=0; | ||||
|  |     friInst.doDataExchange(); | ||||
|  | 
 | ||||
|  |     float* cartPos; | ||||
|  |     while(true) | ||||
|  |     { | ||||
|  |         // Time
 | ||||
|  |         timeCounter+=friInst.getSampleTime(); | ||||
|  | 
 | ||||
|  |         friInst.doReceiveData(); | ||||
|  | 
 | ||||
|  |         // Get all variables from FRI
 | ||||
|  |         float* jntPos = friInst.getMsrMsrJntPosition(); | ||||
|  |         float* jacobian = friInst.getJacobian(); | ||||
|  |         float* ftTcp = friInst.getFTTcp(); | ||||
|  | 
 | ||||
|  |         if (timeCounter < 20) | ||||
|  |             cartPos = friInst.getMsrCartPosition(); | ||||
|  |         //friInst.doDataExchange();
 | ||||
|  |         //friInst.doCartesianImpedanceControl(cartPos, highStiff, fastDamp, NULL, NULL, true);
 | ||||
|  | #if 0
 | ||||
|  |         if (timeCounter>10 && timeCounter<10)  | ||||
|  |         { | ||||
|  |             friInst.doCartesianImpedanceControl(cartPos, highStiff, fastDamp, NULL, NULL, false); | ||||
|  |         } else  | ||||
|  |         {    | ||||
|  |             friInst.doCartesianImpedanceControl(cartPos, highStiff, fastDamp, NULL, NULL, false); | ||||
|  |         } | ||||
|  | #endif
 | ||||
|  |         float npos[12]; | ||||
|  |         memcpy(npos,cartPos,12); | ||||
|  |         friInst.doCartesianImpedanceControl(npos, highStiff, fastDamp, NULL, NULL, false); | ||||
|  |          | ||||
|  | #if 0
 | ||||
|  |         if (timeCounter<20)  | ||||
|  |         { | ||||
|  |             friInst.doCartesianImpedanceControl(Test, highStiff, fastDamp, NULL, NULL, true); | ||||
|  |         } else if (timeCounter<30)  | ||||
|  |         { | ||||
|  |             friInst.doCartesianImpedanceControl(cartPos, highStiff, fastDamp, NULL, NULL, true); | ||||
|  |         } else if (timeCounter<40)  | ||||
|  |         { | ||||
|  |             friInst.doCartesianImpedanceControl(cartPos , highStiff, fastDamp, NULL, NULL, true); | ||||
|  |         } else  | ||||
|  |         { | ||||
|  |             friInst.doDataExchange(); | ||||
|  |         } | ||||
|  | #endif
 | ||||
|  |         friInst.doSendData(); | ||||
|  |     } | ||||
|  | } | ||||
|  | 
 | ||||
|  | Mat4f vecToMat2(float vec[12]) | ||||
|  | { | ||||
|  |     Mat4f result; | ||||
|  |     for (int i=0; i<3; i++) | ||||
|  |     { | ||||
|  |         for (int j=0; j<4; j++) | ||||
|  |         { | ||||
|  |             result(i,j) = (float)vec[i*4+j]; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     result(3,3)=(float)1; | ||||
|  |     return result; | ||||
|  | } | ||||
|  | 
 | ||||
|  | float* matToVec2(Mat4f mat) | ||||
|  | { | ||||
|  |     float* vec = new float[12]; | ||||
|  |     for (int j=0;j<3;j++) | ||||
|  |     { | ||||
|  |         for (int k=0;k<4;k++) | ||||
|  |         { | ||||
|  |             vec[j*4+k] = mat(j,k); | ||||
|  |         } | ||||
|  |     } | ||||
|  |     return vec; | ||||
|  | } | ||||
|  | 
 | ||||
|  | float* vectoquat(float vec[12]) | ||||
|  | { | ||||
|  |     float *quat = new float[4]; | ||||
|  |     float diag[3]; | ||||
|  |     int v; int w; int u; | ||||
|  |     diag[0] = vec[0]; | ||||
|  |     diag[1] = vec[5]; | ||||
|  |     diag[2] = vec[10]; | ||||
|  |     float u_ = *std::max_element(diag,diag+2); | ||||
|  | 
 | ||||
|  |     if (u_==diag[0]) | ||||
|  |     { | ||||
|  |         u = 1; | ||||
|  |         v = 2; | ||||
|  |         w = 3; | ||||
|  |     } else if (u_==diag[1]) | ||||
|  |     { | ||||
|  |         u = 2; | ||||
|  |         v = 3; | ||||
|  |         w = 1; | ||||
|  |     } else | ||||
|  |     { | ||||
|  |         u = 3; | ||||
|  |         v = 1; | ||||
|  |         w = 2; | ||||
|  |     } | ||||
|  |     float r = sqrt(1+vec[(u-1)*4+(u-1)] - vec[(v-1)*4+(v-1)] - vec[(w-1)*4+(w-1)]); | ||||
|  |     quat[0] = (vec[(w-1)*4+(v-1)] - vec[(v-1)*4+(w-1)]) / (2*r); | ||||
|  |     quat[u] = r/2; | ||||
|  |     quat[v] = (vec[(u-1)*4+(v-1)] + vec[(v-1)*4+(u-1)]) / (2*r); | ||||
|  |     quat[w] = (vec[(w-1)*4+(u-1)] + vec[(u-1)*4+(w-1)]) / (2*r); | ||||
|  | 
 | ||||
|  |     return quat; | ||||
|  | } | ||||
|  | 
 | ||||
|  | float* quattovec(float quat[4]) | ||||
|  | { | ||||
|  |     float *vec = new float[12]; | ||||
|  |     vec[0] = quat[0]*quat[0]+quat[1]*quat[1]-quat[2]*quat[2]-quat[3]*quat[3]; | ||||
|  |     vec[4] = 2*(quat[1]*quat[2]+quat[0]*quat[3]); | ||||
|  |     vec[8] = 2*(quat[1]*quat[3]-quat[0]*quat[2]); | ||||
|  |      | ||||
|  |     vec[1] = 2*(quat[1]*quat[2]-quat[0]*quat[3]); | ||||
|  |     vec[5] = quat[0]*quat[0]-quat[1]*quat[1]+quat[2]*quat[2]-quat[3]*quat[3]; | ||||
|  |     vec[9] = 2*(quat[2]*quat[3]+quat[0]*quat[1]); | ||||
|  |      | ||||
|  |     vec[2] = 2*(quat[1]*quat[3]+quat[0]*quat[2]); | ||||
|  |     vec[6] = 2*(quat[2]*quat[3]-quat[0]*quat[1]); | ||||
|  |     vec[10] = quat[0]*quat[0]-quat[1]*quat[1]-quat[2]*quat[2]+quat[3]*quat[3]; | ||||
|  | 
 | ||||
|  |     return vec; | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | void *threadFriDataExchange(void *arg) | ||||
|  | { | ||||
|  |     //doRalf();
 | ||||
|  | 
 | ||||
|  |     friRemote friInst; | ||||
|  | 
 | ||||
|  |     while (1) | ||||
|  |     { | ||||
|  |         //#######################################
 | ||||
|  |         // Communication loop
 | ||||
|  | 
 | ||||
|  |         // get current joint positions 
 | ||||
|  |         for ( int i= 0; i < LBR_MNJ; i++) | ||||
|  |         { | ||||
|  |             MSRMSRJNTPOS[i] = friInst.getMsrCmdJntPosition()[i] + friInst.getMsrCmdJntPositionOffset()[i]; | ||||
|  |             //MSRMSRJNTPOS[i] = friInst.getMsrMsrJntPosition()[i];
 | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         // get current jacobian
 | ||||
|  |         float* friJacobian = friInst.getJacobian(); | ||||
|  |         if ( friJacobian == NULL) | ||||
|  |         { | ||||
|  |             fprintf(stderr,"Failed: could not get jacobian\n"); | ||||
|  |             break; | ||||
|  |         } | ||||
|  |         for (int i = 0; i < FRI_CART_VEC*LBR_MNJ ; i++) | ||||
|  |         { | ||||
|  |             MSRMSRJACOBIAN[i] = friJacobian[i]; | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         // get current messured carthesian position
 | ||||
|  |         float* friMsrCartPosition = friInst.getMsrCartPosition(); | ||||
|  |         if ( friMsrCartPosition == NULL) | ||||
|  |         { | ||||
|  |             fprintf(stderr,"Failed: could not get Messurement in Carthesian Position\n"); | ||||
|  |             break; | ||||
|  |         } | ||||
|  |         for ( int i =0; i < FRI_CART_FRM_DIM; i++) | ||||
|  |         { | ||||
|  |             MSRMSRCARTPOS[i] = friMsrCartPosition[i]; | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         // get current force and torque
 | ||||
|  |         float* friFTTcp =  friInst.getFTTcp(); | ||||
|  |         for ( int i = 0; i < FRI_CART_VEC; i++) | ||||
|  |         { | ||||
|  |             MSRMSRFTTCP[i] = friFTTcp[i]; | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         //#########################################################
 | ||||
|  |         // PTP Joint Movement
 | ||||
|  |         if (__MSRCMDJNTPOS) | ||||
|  |         { | ||||
|  |             double maxVelJntLocal[LBR_MNJ]; | ||||
|  |             double maxAccJntLocal[LBR_MNJ]; | ||||
|  |             double delta[LBR_MNJ]; | ||||
|  |             double sampleTime = (double)0.005; | ||||
|  |             double deltaAbs[LBR_MNJ]; | ||||
|  |             double dMaxSpeed[LBR_MNJ]; | ||||
|  |             double lMaxSpeed[LBR_MNJ]; | ||||
|  |             double dGesamt[LBR_MNJ]; | ||||
|  |              | ||||
|  |             double currentInk[LBR_MNJ] = {0}; | ||||
|  |             double currentInkLast[LBR_MNJ] = {0}; | ||||
|  |             double currentDist [LBR_MNJ] = {0}; | ||||
|  |             double currentDistLast [LBR_MNJ] = {0}; | ||||
|  | 
 | ||||
|  |             // calculate delta positions of movement
 | ||||
|  |             for ( int i= 0; i < LBR_MNJ; i++) | ||||
|  |             { | ||||
|  |                 delta[i] = MSRCMDJNTPOS[i]-(MSRMSRJNTPOS[i]*180/M_PI); | ||||
|  |                 deltaAbs[i] = fabs(MSRCMDJNTPOS[i]-(MSRMSRJNTPOS[i]*180/M_PI)); | ||||
|  |                 maxVelJntLocal[i] = maxVelJnt[i]*sampleTime*(VELOCITY/100.0); | ||||
|  |                 maxAccJntLocal[i] = maxAccJnt[i]*sampleTime*(ACCELARATION/100.0); | ||||
|  |             } | ||||
|  |              | ||||
|  |             // calculate movement steps
 | ||||
|  |             for (int j=0; j<LBR_MNJ; j++) | ||||
|  |             { | ||||
|  |                 dMaxSpeed[j] = maxVelJntLocal[j]/maxAccJntLocal[j]; | ||||
|  |                 lMaxSpeed[j] = dMaxSpeed[j]*dMaxSpeed[j]*maxAccJntLocal[j]*0.5; | ||||
|  |                 if (lMaxSpeed[j] > deltaAbs[j]/(double)2.0) | ||||
|  |                 { | ||||
|  |                     dGesamt[j] = sqrt(deltaAbs[j]/maxAccJntLocal[j])*2.0; | ||||
|  |                 } else  | ||||
|  |                 { | ||||
|  |                     dGesamt[j] = dMaxSpeed[j]*2 + (deltaAbs[j]-lMaxSpeed[j]*2.0)/maxVelJntLocal[j]; | ||||
|  |                 } | ||||
|  |             } | ||||
|  |             int maxSteps =ceil(*max_element(dGesamt,(dGesamt+LBR_MNJ-1))); | ||||
|  | 
 | ||||
|  |             if (maxSteps == 0 || maxSteps == 1) | ||||
|  |                 goto end; | ||||
|  | 
 | ||||
|  |             for (int j=0; j<LBR_MNJ; j++) | ||||
|  |             { | ||||
|  |                 dMaxSpeed[j] = ceil(maxSteps/(double)2 - sqrt((maxSteps/(double)2)*(maxSteps/(double)2) - deltaAbs[j]/maxAccJntLocal[j])); | ||||
|  |                 double temp = maxSteps/(double)2 - sqrt((maxSteps/(double)2)*(maxSteps/(double)2) - deltaAbs[j]/maxAccJntLocal[j]);              | ||||
|  |                 if (dMaxSpeed[j]==0) | ||||
|  |                 { | ||||
|  |                     maxAccJntLocal[j] = 0; | ||||
|  |                 } else | ||||
|  |                 { | ||||
|  |                     maxAccJntLocal[j] = -deltaAbs[j]/(dMaxSpeed[j]*dMaxSpeed[j]-maxSteps*dMaxSpeed[j]); | ||||
|  |                 } | ||||
|  |                 maxVelJntLocal[j] = dMaxSpeed[j]*maxAccJntLocal[j]; | ||||
|  |             } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  |             for (int i=0;i<maxSteps;i++) | ||||
|  |             { | ||||
|  |                 for (int j=0;j<LBR_MNJ;j++) | ||||
|  |                 { | ||||
|  |                     if (i+1 <= maxSteps/(double)2) | ||||
|  |                     { | ||||
|  |                         currentInk[j] = min(currentInkLast[j]+maxAccJntLocal[j],maxVelJntLocal[j]); | ||||
|  |                     }else if (i+1 > maxSteps-dMaxSpeed[j]) | ||||
|  |                     { | ||||
|  |                         currentInk[j] = max(currentInkLast[j]-maxAccJntLocal[j],(double)0); | ||||
|  |                     }else | ||||
|  |                     { | ||||
|  |                         currentInk[j] = currentInkLast[j]; | ||||
|  |                     } | ||||
|  |                     currentDist[j] = currentDistLast[j] + sgn(delta[j])*currentInk[j]; | ||||
|  |                     currentInkLast[j] = currentInk[j]; | ||||
|  |                     currentDistLast[j] = currentDist[j]; | ||||
|  |                     MSRMSRJNTPOS[j]+= sgn(delta[j])*currentInk[j]*(1./180*M_PI); | ||||
|  |                 } | ||||
|  |                 friInst.doPositionControl(MSRMSRJNTPOS); | ||||
|  |             } | ||||
|  | end: | ||||
|  |             __MSRCMDJNTPOS = false; | ||||
|  | 
 | ||||
|  |         } else if (__CARTMOVE) | ||||
|  |         { | ||||
|  |             //##########################################################
 | ||||
|  |             //Cartesian Movement
 | ||||
|  | 
 | ||||
|  |             const float Stiff[6] = {1000.0, 1000.0, 1000.0, 150.0, 150.0, 150.0}; | ||||
|  |             const float Damp[6] = {0.7, 0.7, 0.7, 0.7, 0.7, 0.7}; | ||||
|  |             float th = 0.000; | ||||
|  |             float deltaCart[12]; | ||||
|  |             float Pos[12]; | ||||
|  |             float dist; | ||||
|  |             float rot; | ||||
|  |             float sum; | ||||
|  |             float b; | ||||
|  |             float c; | ||||
|  |             float t_fact = 1; | ||||
|  |             float t_outerT = 0.007; | ||||
|  |             float t_innerT = 0.000; | ||||
|  |             float t_outerR = 0.007; | ||||
|  |             float t_innerR = 0.000; | ||||
|  | 
 | ||||
|  |             while (true) | ||||
|  |             { | ||||
|  |                 for ( int i =0; i < FRI_CART_FRM_DIM; i++) | ||||
|  |                 { | ||||
|  |                     Pos[i] = friInst.getMsrCartPosition()[i]; | ||||
|  |                     MSRMSRCARTPOS[i] = friInst.getMsrCartPosition()[i]; | ||||
|  |                     deltaCart[i] = MSRCMDCARTPOS[i]-Pos[i]; | ||||
|  |                 } | ||||
|  |                 sum = 0; | ||||
|  |                 for (int i=0; i<3 ; i++) | ||||
|  |                 { | ||||
|  |                     sum = sum + (deltaCart[(i*4)+3]*deltaCart[(i*4)+3]); | ||||
|  |                 } | ||||
|  |                 dist = sqrt(sum); | ||||
|  |                 sum = 0; | ||||
|  |                 for (int i=0;i<12;i++) | ||||
|  |                 { | ||||
|  |                     if (i != 3 && i != 7 && i != 11) | ||||
|  |                     { | ||||
|  |                         sum = sum + deltaCart[i]*deltaCart[i]; | ||||
|  |                     } | ||||
|  |                 } | ||||
|  |                 rot = sqrt(sum); | ||||
|  |                 b = t_fact*max((float)0.0,(float)min((float)1.0,(t_outerT-dist+(t_innerT-t_outerT))*(1/(t_innerT-t_outerT)))); | ||||
|  |                 c = t_fact*max((float)0.0,(float)min((float)1.0,(float)(t_outerR-rot+(t_innerR-t_outerR))*(float)(1/(t_innerR-t_outerR)))); | ||||
|  | 
 | ||||
|  |                 if (dist < th) | ||||
|  |                 { | ||||
|  |                     for (int i=0; i<3; i++) | ||||
|  |                     { | ||||
|  |                         deltaCart[(i*4)+3] = 0; | ||||
|  |                     } | ||||
|  |                 }else  | ||||
|  |                 { | ||||
|  |                     for (int i=0; i<3; i++) | ||||
|  |                     { | ||||
|  |                         deltaCart[(i*4)+3] = (deltaCart[(i*4)+3] / dist)*b; | ||||
|  |                     } | ||||
|  |                 } | ||||
|  | 
 | ||||
|  |                 // check offset to point 
 | ||||
|  |                 if (rot < th) | ||||
|  |                 { | ||||
|  |                     for (int i=0;i<12;i++) | ||||
|  |                     { | ||||
|  |                         if (i != 3 && i != 7 && i != 11) | ||||
|  |                         { | ||||
|  |                             deltaCart[i] = 0; | ||||
|  |                         } | ||||
|  |                     } | ||||
|  |                 }else  | ||||
|  |                 { | ||||
|  |                     for (int i=0;i<12;i++) | ||||
|  |                     { | ||||
|  |                         if (i != 3 && i != 7 && i != 11) | ||||
|  |                         { | ||||
|  |                             deltaCart[i] = (deltaCart[i] / rot)*c; | ||||
|  |                         } | ||||
|  |                     } | ||||
|  |                 } | ||||
|  |                 for (int i=0;i<12;i++) | ||||
|  |                 { | ||||
|  |                     Pos[i]+= deltaCart[i]*0.02; | ||||
|  |                 } | ||||
|  |                 friInst.doCartesianImpedanceControl(Pos, Stiff,Damp,NULL,NULL, true); | ||||
|  | 
 | ||||
|  |             } | ||||
|  |         }  | ||||
|  |         //float Stiff[6] = {1000.0, 1000.0, 1000.0, 10.0, 10.0, 10.0};
 | ||||
|  |         //float Damp[6] = {0.7, 0.7, 0.7, 0.7, 0.7, 0.7};
 | ||||
|  |         //float Test[12] = {MSRMSRCARTPOS[0],MSRMSRCARTPOS[1],MSRMSRCARTPOS[2],MSRMSRCARTPOS[3],MSRMSRCARTPOS[4],MSRMSRCARTPOS[5],MSRMSRCARTPOS[6],MSRMSRCARTPOS[7],MSRMSRCARTPOS[8],MSRMSRCARTPOS[9],MSRMSRCARTPOS[10],MSRMSRCARTPOS[11]};
 | ||||
|  |         //friInst.doCartesianImpedanceControl(Test,Stiff, Damp, NULL, NULL, true);
 | ||||
|  | 
 | ||||
|  |         friInst.doPositionControl(MSRMSRJNTPOS); | ||||
|  | 
 | ||||
|  |         //i = 0;
 | ||||
|  |         //}
 | ||||
|  |         //friInst.doCartesianImpedanceControl(Test,Stiff, Damp, NULL, NULL, true);
 | ||||
|  |     } | ||||
|  |     return NULL; | ||||
|  | } | ||||
|  | 
 | ||||
|  | int main() | ||||
|  | { | ||||
|  |     int err = 0; | ||||
|  |     //Setting pthread for FRI interface
 | ||||
|  |     pthread_t fri_t; | ||||
|  |     //Start fri_thread
 | ||||
|  |     err = pthread_create(&fri_t,NULL,&threadFriDataExchange,NULL); | ||||
|  |     if (err > 0 ) | ||||
|  |     { | ||||
|  |         cerr << "Failed: could not create thread\n" << endl; | ||||
|  |         return err; | ||||
|  |     } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  |     //Start client handling
 | ||||
|  |     SvrHandling *svr = new SvrHandling(); | ||||
|  |     if (svr == NULL) | ||||
|  |     { | ||||
|  |         cerr << "Failed: could not create server \n" << endl; | ||||
|  |         return -ENOMEM; | ||||
|  |     } | ||||
|  |     svr->run(SVR_DEFAULT_PORT); | ||||
|  | 
 | ||||
|  |     return 0; | ||||
|  | } | ||||
						
							
						
						
							1368
	
						
						lwrserv/pthread/pthread.h
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				File diff suppressed because it is too large
							
							
								
									View File
								
							
						| @ -0,0 +1,183 @@ | |||||
|  | /* | ||||
|  |  * Module: sched.h | ||||
|  |  * | ||||
|  |  * Purpose: | ||||
|  |  *      Provides an implementation of POSIX realtime extensions | ||||
|  |  *      as defined in  | ||||
|  |  * | ||||
|  |  *              POSIX 1003.1b-1993      (POSIX.1b) | ||||
|  |  * | ||||
|  |  * -------------------------------------------------------------------------- | ||||
|  |  * | ||||
|  |  *      Pthreads-win32 - POSIX Threads Library for Win32 | ||||
|  |  *      Copyright(C) 1998 John E. Bossom | ||||
|  |  *      Copyright(C) 1999,2005 Pthreads-win32 contributors | ||||
|  |  *  | ||||
|  |  *      Contact Email: rpj@callisto.canberra.edu.au | ||||
|  |  *  | ||||
|  |  *      The current list of contributors is contained | ||||
|  |  *      in the file CONTRIBUTORS included with the source | ||||
|  |  *      code distribution. The list can also be seen at the | ||||
|  |  *      following World Wide Web location: | ||||
|  |  *      http://sources.redhat.com/pthreads-win32/contributors.html | ||||
|  |  *  | ||||
|  |  *      This library is free software; you can redistribute it and/or | ||||
|  |  *      modify it under the terms of the GNU Lesser General Public | ||||
|  |  *      License as published by the Free Software Foundation; either | ||||
|  |  *      version 2 of the License, or (at your option) any later version. | ||||
|  |  *  | ||||
|  |  *      This library is distributed in the hope that it will be useful, | ||||
|  |  *      but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  |  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  |  *      Lesser General Public License for more details. | ||||
|  |  *  | ||||
|  |  *      You should have received a copy of the GNU Lesser General Public | ||||
|  |  *      License along with this library in the file COPYING.LIB; | ||||
|  |  *      if not, write to the Free Software Foundation, Inc., | ||||
|  |  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||||
|  |  */ | ||||
|  | #if !defined(_SCHED_H) | ||||
|  | #define _SCHED_H | ||||
|  | 
 | ||||
|  | #undef PTW32_SCHED_LEVEL | ||||
|  | 
 | ||||
|  | #if defined(_POSIX_SOURCE) | ||||
|  | #define PTW32_SCHED_LEVEL 0 | ||||
|  | /* Early POSIX */ | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 | ||||
|  | #undef PTW32_SCHED_LEVEL | ||||
|  | #define PTW32_SCHED_LEVEL 1 | ||||
|  | /* Include 1b, 1c and 1d */ | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | #if defined(INCLUDE_NP) | ||||
|  | #undef PTW32_SCHED_LEVEL | ||||
|  | #define PTW32_SCHED_LEVEL 2 | ||||
|  | /* Include Non-Portable extensions */ | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | #define PTW32_SCHED_LEVEL_MAX 3 | ||||
|  | 
 | ||||
|  | #if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 )  || !defined(PTW32_SCHED_LEVEL) | ||||
|  | #define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX | ||||
|  | /* Include everything */ | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | #if defined(__GNUC__) && !defined(__declspec) | ||||
|  | # error Please upgrade your GNU compiler to one that supports __declspec. | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | /* | ||||
|  |  * When building the library, you should define PTW32_BUILD so that | ||||
|  |  * the variables/functions are exported correctly. When using the library, | ||||
|  |  * do NOT define PTW32_BUILD, and then the variables/functions will | ||||
|  |  * be imported correctly. | ||||
|  |  */ | ||||
|  | #if !defined(PTW32_STATIC_LIB) | ||||
|  | #  if defined(PTW32_BUILD) | ||||
|  | #    define PTW32_DLLPORT __declspec (dllexport) | ||||
|  | #  else | ||||
|  | #    define PTW32_DLLPORT __declspec (dllimport) | ||||
|  | #  endif | ||||
|  | #else | ||||
|  | #  define PTW32_DLLPORT | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | /* | ||||
|  |  * This is a duplicate of what is in the autoconf config.h, | ||||
|  |  * which is only used when building the pthread-win32 libraries. | ||||
|  |  */ | ||||
|  | 
 | ||||
|  | #if !defined(PTW32_CONFIG_H) | ||||
|  | #  if defined(WINCE) | ||||
|  | #    define NEED_ERRNO | ||||
|  | #    define NEED_SEM | ||||
|  | #  endif | ||||
|  | #  if defined(__MINGW64__) | ||||
|  | #    define HAVE_STRUCT_TIMESPEC | ||||
|  | #    define HAVE_MODE_T | ||||
|  | #  elif defined(_UWIN) || defined(__MINGW32__) | ||||
|  | #    define HAVE_MODE_T | ||||
|  | #  endif | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | /* | ||||
|  |  * | ||||
|  |  */ | ||||
|  | 
 | ||||
|  | #if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX | ||||
|  | #if defined(NEED_ERRNO) | ||||
|  | #include "need_errno.h" | ||||
|  | #else | ||||
|  | #include <errno.h> | ||||
|  | #endif | ||||
|  | #endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */ | ||||
|  | 
 | ||||
|  | #if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN) | ||||
|  | # if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX | ||||
|  | /* For pid_t */ | ||||
|  | #  include <sys/types.h> | ||||
|  | /* Required by Unix 98 */ | ||||
|  | #  include <time.h> | ||||
|  | # else | ||||
|  |    typedef int pid_t; | ||||
|  | # endif | ||||
|  | #else | ||||
|  |  typedef int pid_t; | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | /* Thread scheduling policies */ | ||||
|  | 
 | ||||
|  | enum { | ||||
|  |   SCHED_OTHER = 0, | ||||
|  |   SCHED_FIFO, | ||||
|  |   SCHED_RR, | ||||
|  |   SCHED_MIN   = SCHED_OTHER, | ||||
|  |   SCHED_MAX   = SCHED_RR | ||||
|  | }; | ||||
|  | 
 | ||||
|  | struct sched_param { | ||||
|  |   int sched_priority; | ||||
|  | }; | ||||
|  | 
 | ||||
|  | #if defined(__cplusplus) | ||||
|  | extern "C" | ||||
|  | { | ||||
|  | #endif                          /* __cplusplus */ | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sched_yield (void); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); | ||||
|  | 
 | ||||
|  | /* | ||||
|  |  * Note that this macro returns ENOTSUP rather than | ||||
|  |  * ENOSYS as might be expected. However, returning ENOSYS | ||||
|  |  * should mean that sched_get_priority_{min,max} are | ||||
|  |  * not implemented as well as sched_rr_get_interval. | ||||
|  |  * This is not the case, since we just don't support | ||||
|  |  * round-robin scheduling. Therefore I have chosen to | ||||
|  |  * return the same value as sched_setscheduler when | ||||
|  |  * SCHED_RR is passed to it. | ||||
|  |  */ | ||||
|  | #define sched_rr_get_interval(_pid, _interval) \ | ||||
|  |   ( errno = ENOTSUP, (int) -1 ) | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | #if defined(__cplusplus) | ||||
|  | }                               /* End of extern "C" */ | ||||
|  | #endif                          /* __cplusplus */ | ||||
|  | 
 | ||||
|  | #undef PTW32_SCHED_LEVEL | ||||
|  | #undef PTW32_SCHED_LEVEL_MAX | ||||
|  | 
 | ||||
|  | #endif                          /* !_SCHED_H */ | ||||
|  | 
 | ||||
| @ -0,0 +1,169 @@ | |||||
|  | /* | ||||
|  |  * Module: semaphore.h | ||||
|  |  * | ||||
|  |  * Purpose: | ||||
|  |  *	Semaphores aren't actually part of the PThreads standard. | ||||
|  |  *	They are defined by the POSIX Standard: | ||||
|  |  * | ||||
|  |  *		POSIX 1003.1b-1993	(POSIX.1b) | ||||
|  |  * | ||||
|  |  * -------------------------------------------------------------------------- | ||||
|  |  * | ||||
|  |  *      Pthreads-win32 - POSIX Threads Library for Win32 | ||||
|  |  *      Copyright(C) 1998 John E. Bossom | ||||
|  |  *      Copyright(C) 1999,2005 Pthreads-win32 contributors | ||||
|  |  *  | ||||
|  |  *      Contact Email: rpj@callisto.canberra.edu.au | ||||
|  |  *  | ||||
|  |  *      The current list of contributors is contained | ||||
|  |  *      in the file CONTRIBUTORS included with the source | ||||
|  |  *      code distribution. The list can also be seen at the | ||||
|  |  *      following World Wide Web location: | ||||
|  |  *      http://sources.redhat.com/pthreads-win32/contributors.html | ||||
|  |  *  | ||||
|  |  *      This library is free software; you can redistribute it and/or | ||||
|  |  *      modify it under the terms of the GNU Lesser General Public | ||||
|  |  *      License as published by the Free Software Foundation; either | ||||
|  |  *      version 2 of the License, or (at your option) any later version. | ||||
|  |  *  | ||||
|  |  *      This library is distributed in the hope that it will be useful, | ||||
|  |  *      but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  |  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  |  *      Lesser General Public License for more details. | ||||
|  |  *  | ||||
|  |  *      You should have received a copy of the GNU Lesser General Public | ||||
|  |  *      License along with this library in the file COPYING.LIB; | ||||
|  |  *      if not, write to the Free Software Foundation, Inc., | ||||
|  |  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||||
|  |  */ | ||||
|  | #if !defined( SEMAPHORE_H ) | ||||
|  | #define SEMAPHORE_H | ||||
|  | 
 | ||||
|  | #undef PTW32_SEMAPHORE_LEVEL | ||||
|  | 
 | ||||
|  | #if defined(_POSIX_SOURCE) | ||||
|  | #define PTW32_SEMAPHORE_LEVEL 0 | ||||
|  | /* Early POSIX */ | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 | ||||
|  | #undef PTW32_SEMAPHORE_LEVEL | ||||
|  | #define PTW32_SEMAPHORE_LEVEL 1 | ||||
|  | /* Include 1b, 1c and 1d */ | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | #if defined(INCLUDE_NP) | ||||
|  | #undef PTW32_SEMAPHORE_LEVEL | ||||
|  | #define PTW32_SEMAPHORE_LEVEL 2 | ||||
|  | /* Include Non-Portable extensions */ | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | #define PTW32_SEMAPHORE_LEVEL_MAX 3 | ||||
|  | 
 | ||||
|  | #if !defined(PTW32_SEMAPHORE_LEVEL) | ||||
|  | #define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX | ||||
|  | /* Include everything */ | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | #if defined(__GNUC__) && ! defined (__declspec) | ||||
|  | # error Please upgrade your GNU compiler to one that supports __declspec. | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | /* | ||||
|  |  * When building the library, you should define PTW32_BUILD so that | ||||
|  |  * the variables/functions are exported correctly. When using the library, | ||||
|  |  * do NOT define PTW32_BUILD, and then the variables/functions will | ||||
|  |  * be imported correctly. | ||||
|  |  */ | ||||
|  | #if !defined(PTW32_STATIC_LIB) | ||||
|  | #  if defined(PTW32_BUILD) | ||||
|  | #    define PTW32_DLLPORT __declspec (dllexport) | ||||
|  | #  else | ||||
|  | #    define PTW32_DLLPORT __declspec (dllimport) | ||||
|  | #  endif | ||||
|  | #else | ||||
|  | #  define PTW32_DLLPORT | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | /* | ||||
|  |  * This is a duplicate of what is in the autoconf config.h, | ||||
|  |  * which is only used when building the pthread-win32 libraries. | ||||
|  |  */ | ||||
|  | 
 | ||||
|  | #if !defined(PTW32_CONFIG_H) | ||||
|  | #  if defined(WINCE) | ||||
|  | #    define NEED_ERRNO | ||||
|  | #    define NEED_SEM | ||||
|  | #  endif | ||||
|  | #  if defined(__MINGW64__) | ||||
|  | #    define HAVE_STRUCT_TIMESPEC | ||||
|  | #    define HAVE_MODE_T | ||||
|  | #  elif defined(_UWIN) || defined(__MINGW32__) | ||||
|  | #    define HAVE_MODE_T | ||||
|  | #  endif | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | /* | ||||
|  |  * | ||||
|  |  */ | ||||
|  | 
 | ||||
|  | #if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX | ||||
|  | #if defined(NEED_ERRNO) | ||||
|  | #include "need_errno.h" | ||||
|  | #else | ||||
|  | #include <errno.h> | ||||
|  | #endif | ||||
|  | #endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */ | ||||
|  | 
 | ||||
|  | #define _POSIX_SEMAPHORES | ||||
|  | 
 | ||||
|  | #if defined(__cplusplus) | ||||
|  | extern "C" | ||||
|  | { | ||||
|  | #endif				/* __cplusplus */ | ||||
|  | 
 | ||||
|  | #if !defined(HAVE_MODE_T) | ||||
|  | typedef unsigned int mode_t; | ||||
|  | #endif | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | typedef struct sem_t_ * sem_t; | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, | ||||
|  | 			    int pshared, | ||||
|  | 			    unsigned int value); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, | ||||
|  | 				 const struct timespec * abstime); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, | ||||
|  | 				     int count); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sem_open (const char * name, | ||||
|  | 			    int oflag, | ||||
|  | 			    mode_t mode, | ||||
|  | 			    unsigned int value); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sem_unlink (const char * name); | ||||
|  | 
 | ||||
|  | PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, | ||||
|  | 				int * sval); | ||||
|  | 
 | ||||
|  | #if defined(__cplusplus) | ||||
|  | }				/* End of extern "C" */ | ||||
|  | #endif				/* __cplusplus */ | ||||
|  | 
 | ||||
|  | #undef PTW32_SEMAPHORE_LEVEL | ||||
|  | #undef PTW32_SEMAPHORE_LEVEL_MAX | ||||
|  | 
 | ||||
|  | #endif				/* !SEMAPHORE_H */ | ||||
| @ -0,0 +1,14 @@ | |||||
|  | //{{NO_DEPENDENCIES}} | ||||
|  | // Microsoft Visual C++ generated include file. | ||||
|  | // Used by lwrserv.rc | ||||
|  | 
 | ||||
|  | // Nächste Standardwerte für neue Objekte | ||||
|  | //  | ||||
|  | #ifdef APSTUDIO_INVOKED | ||||
|  | #ifndef APSTUDIO_READONLY_SYMBOLS | ||||
|  | #define _APS_NEXT_RESOURCE_VALUE        101 | ||||
|  | #define _APS_NEXT_COMMAND_VALUE         40001 | ||||
|  | #define _APS_NEXT_CONTROL_VALUE         1001 | ||||
|  | #define _APS_NEXT_SYMED_VALUE           101 | ||||
|  | #endif | ||||
|  | #endif | ||||
| @ -0,0 +1,13 @@ | |||||
|  | #ifndef __SGN_H__ | ||||
|  | #define __SGN_H__ | ||||
|  | inline float sgn(float x)  | ||||
|  | {  | ||||
|  |     if ( x == 0 )  | ||||
|  |         return 0.0f;  | ||||
|  | 
 | ||||
|  |     if ( x > 0) | ||||
|  |         return 1.0f; | ||||
|  |     else | ||||
|  |         return -1.0f;  | ||||
|  | } | ||||
|  | #endif | ||||
| @ -0,0 +1,234 @@ | |||||
|  | #ifndef _VEC_H_ | ||||
|  | #define _VEC_H_ | ||||
|  | #include <math.h> | ||||
|  | #include "mat.h" | ||||
|  | #include <ostream> | ||||
|  | 
 | ||||
|  | template<class T, unsigned SIZE> class Mat; | ||||
|  | template<class T, unsigned SIZE> class Vec; | ||||
|  | 
 | ||||
|  | // Vector class for SIMPLE data types | ||||
|  | template <class T, unsigned SIZE> class Vec  | ||||
|  | { | ||||
|  | public: | ||||
|  | 
 | ||||
|  |     // standard constructor | ||||
|  |     Vec<T,SIZE> ()   | ||||
|  |     {   // initialize all elements with zero | ||||
|  |         for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             m_atData[i] = T(0); | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     // construction with data array | ||||
|  |     Vec<T, SIZE> (const T atData[SIZE])  | ||||
|  |     { | ||||
|  |         for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             m_atData[i] = atData[i]; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     // copy constructor | ||||
|  |     Vec<T, SIZE> (const Vec<T, SIZE> &vec)  | ||||
|  |     { | ||||
|  |         if (this==&vec) | ||||
|  |             return; // nothing to do, it's me | ||||
|  |         for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             m_atData[i] = vec.m_atData[i]; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     // destructor | ||||
|  |     ~Vec ()  | ||||
|  |     {   // nothing to do here ... | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     void setData (const T atData[SIZE])  | ||||
|  |     { | ||||
|  |         for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             m_atData[i] = atData[i]; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     void getData (const T atData[SIZE])  | ||||
|  |     { | ||||
|  |         for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             atData[i] = m_atData[i]; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     unsigned getDimension ()  | ||||
|  |     { | ||||
|  |         return SIZE; | ||||
|  |     } | ||||
|  | 
 | ||||
|  | 
 | ||||
|  |     Vec<T, SIZE> &operator = (const Vec<T, SIZE> &vec)  | ||||
|  |     { | ||||
|  |         if (this==&vec) | ||||
|  |             return (*this); // ok, it's me, so no L-value action | ||||
|  |         for (unsigned int i=0; i<SIZE; i++)     // not me, so L-Value action: copy data | ||||
|  |             m_atData[i] = vec.m_atData[i]; | ||||
|  | 
 | ||||
|  |         return (*this); // also an R-value in e.g | ||||
|  |                         // vec1    =       vec2      = vec3; | ||||
|  |                         // L-Value = R-Value/L-Value = R-Value | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     Vec<T, SIZE> &operator = (const T atData[SIZE])  | ||||
|  |     { | ||||
|  |         for (unsigned int i=0; i<SIZE; i++) // not me, so L-Value action: copy data | ||||
|  |             m_atData[i] = atData[i]; | ||||
|  | 
 | ||||
|  |         return (*this); // also an R-value in e.g. | ||||
|  |                         // vec1  = vec2  +   (vec2=atData); // parenthesis () needed to evaluate expression vec2=atData | ||||
|  |                         // L-Val = R-Val +       R-Val | ||||
|  |                         //   "   =   "   + (L-Val = R-Val) | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     // usage of operator: | ||||
|  |     // vec(i) = var;    // 0 <= i <= SIZE-1 | ||||
|  |     // var = vec(i); | ||||
|  |     // vec1(i) = vec2(j); | ||||
|  |     T &operator () (unsigned i)  | ||||
|  |     { | ||||
|  |         if (i>=SIZE) | ||||
|  |             i = SIZE-1; // !!! operator clips index ... | ||||
|  |         return m_atData[i];         // ... so we can safely return a reference | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     T operator () (unsigned i) const  | ||||
|  |     { | ||||
|  |         if (i>=SIZE) | ||||
|  |             i = SIZE-1; | ||||
|  |         return m_atData[i]; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     void operator += (const Vec<T, SIZE> &vec)  | ||||
|  |     { | ||||
|  |         for (int i=0; i<SIZE; i++) | ||||
|  |             m_atData[i] += vec.m_atData[i]; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     Vec<T, SIZE> operator + (const Vec<T, SIZE> &vec)  | ||||
|  |     { | ||||
|  |         Vec<T, SIZE> buf (m_atData); | ||||
|  |         for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             buf.m_atData[i] += vec.m_atData[i]; | ||||
|  |         return buf; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     void operator -= (const Vec<T, SIZE> &vec)  | ||||
|  |     { | ||||
|  |         for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             m_atData[i] -= vec.m_atData[i]; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     // binary - | ||||
|  |     // vec1 - vec2 i.e. (*this) - vec | ||||
|  |     Vec<T, SIZE> operator - (const Vec<T, SIZE> &vec)  | ||||
|  |     { | ||||
|  |         Vec<T, SIZE> buf (m_atData); | ||||
|  |         for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             buf.m_atData[i] -= vec.m_atData[i]; | ||||
|  |         return buf; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     // unary - | ||||
|  |     // -vec i.e. -(*this) | ||||
|  |     Vec<T, SIZE> operator - ()  | ||||
|  |     { | ||||
|  |         T atBuffer[SIZE]; | ||||
|  |         for (int i=0; i<SIZE; i++) | ||||
|  |             atBuffer[i] = -m_atData[i]; | ||||
|  |         return Vec<T, SIZE> (atBuffer); | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     T operator * (const Vec<T, SIZE> & vec)  | ||||
|  |     { | ||||
|  |         T dp = T(0); | ||||
|  |         for (int i=0; i<SIZE; i++) | ||||
|  |             dp += m_atData[i]*vec.m_atData[i]; | ||||
|  |         return dp; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     void operator *= (T tScale)  | ||||
|  |     { | ||||
|  |         for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             m_atData[i] *= tScale; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     Vec<T, SIZE> operator * (T tScale)  | ||||
|  |     { | ||||
|  |         T atBuffer[SIZE]; | ||||
|  |         for (unsigned int i=0; i<SIZE; i++) | ||||
|  |             atBuffer[i] = m_atData[i]*tScale; | ||||
|  |         return Vec<T, SIZE> (atBuffer); | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     Vec<T, SIZE> operator * (const Mat<T, SIZE> &mat) | ||||
|  |     { | ||||
|  |         Vec<T, SIZE> vec; | ||||
|  |         for (unsigned int j=0; j<SIZE; j++) | ||||
|  |             for (unsigned int i=0; i<SIZE; i++) | ||||
|  |                vec(j) += m_atData[i]*mat(i,j); | ||||
|  |         return vec; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     T norm () | ||||
|  |     { | ||||
|  |         T retval = 0; | ||||
|  | 
 | ||||
|  |         // this * this | ||||
|  |         for (int i=0; i<SIZE; i++) | ||||
|  |             retval += m_atData[i] * m_atData[i]; | ||||
|  |         sqrt(retval); | ||||
|  |         return retval; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     Vec<T, SIZE> x(const Vec<T, SIZE> &vec) | ||||
|  |     { | ||||
|  |         T temp[SIZE]; | ||||
|  |         temp[0] = m_atData[1]*vec(2) - m_atData[2]*vec(1); | ||||
|  |         temp[1] = m_atData[2]*vec(0) - m_atData[0]*vec(2); | ||||
|  |         temp[2] = m_atData[0]*vec(1) - m_atData[1]*vec(0); | ||||
|  |         temp[3] = vec(3); | ||||
|  |         return Vec<T, SIZE> (temp); | ||||
|  |     } | ||||
|  | 
 | ||||
|  | private: | ||||
|  | 
 | ||||
|  |     T m_atData[SIZE]; | ||||
|  | 
 | ||||
|  | }; // class Vec | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | // some common vector classes (abbr. names) | ||||
|  | typedef Vec<float, 2> Vec2f; | ||||
|  | typedef Vec<float, 3> Vec3f; | ||||
|  | typedef Vec<float, 4> Vec4f; | ||||
|  | 
 | ||||
|  | typedef Vec<double, 2> Vec2d; | ||||
|  | typedef Vec<double, 3> Vec3d; | ||||
|  | typedef Vec<double, 4> Vec4d; | ||||
|  | 
 | ||||
|  | typedef Vec<int, 2> Vec2i; | ||||
|  | typedef Vec<int, 3> Vec3i; | ||||
|  | typedef Vec<int, 4> Vec4i; | ||||
|  | 
 | ||||
|  | typedef Vec<bool, 2> Vec2b; | ||||
|  | typedef Vec<bool, 3> Vec3b; | ||||
|  | typedef Vec<bool, 4> Vec4b; | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | template <class T, unsigned SIZE> | ||||
|  | static std::ostream& operator<< (std::ostream& output,const Vec<T,SIZE> &vec) | ||||
|  | { | ||||
|  |     output << "( "; | ||||
|  |     for(unsigned int i = 0 ; i< SIZE; ++i) | ||||
|  |     { | ||||
|  |         output << vec(i); | ||||
|  |         if (i<SIZE-1) | ||||
|  |             output << " , "; | ||||
|  |         else | ||||
|  |             output << " )"; | ||||
|  |     } | ||||
|  |     return output; | ||||
|  | } | ||||
|  | 
 | ||||
|  | #endif | ||||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue