Merge commit '814df25aba4acf5dbcae13639713e7532a587d47'
This commit is contained in:
		
						commit
						72c4657c74
					
				@ -1,11 +1,42 @@
 | 
				
			|||||||
#include "ArduinoUtils.h"
 | 
					#include "ArduinoUtils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(ARDUINO)
 | 
					#if defined(ARDUINO)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <Arduino.h>
 | 
					#include <Arduino.h>
 | 
				
			||||||
 | 
					#include <HTTPClient.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(ARDUINO_ARCH_ESP8266)
 | 
				
			||||||
#include <ESP8266WiFi.h>
 | 
					#include <ESP8266WiFi.h>
 | 
				
			||||||
#include <ESP8266httpUpdate.h>
 | 
					#include <ESP8266httpUpdate.h>
 | 
				
			||||||
 | 
					#elif defined(ESP32)
 | 
				
			||||||
 | 
					#include <HTTPUpdate.h>
 | 
				
			||||||
 | 
					#include <WiFi.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool StartWifi(const char *wifiSsid, const char *wifiPassword,
 | 
					const char* hotspotSSID = "Roboid";
 | 
				
			||||||
               bool hotspotFallback) {
 | 
					const char* hotspotPassword = "alchemy7000";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if ESP32
 | 
				
			||||||
 | 
					// Flash storage
 | 
				
			||||||
 | 
					#include "Preferences.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PREFERENCES_NAMESPACE "roboidControl"
 | 
				
			||||||
 | 
					Preferences wifiPreferences;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define STORAGE_KEY_WIFI "rc/wifi"
 | 
				
			||||||
 | 
					struct WifiCredentials {
 | 
				
			||||||
 | 
					  char ssid[32] = "\0";
 | 
				
			||||||
 | 
					  char password[32] = "\0";
 | 
				
			||||||
 | 
					} credentials;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define STORAGE_KEY_NSS "rc/nss"
 | 
				
			||||||
 | 
					struct NssServer {
 | 
				
			||||||
 | 
					  char ipAddress[16] = "127.0.0.1\0";
 | 
				
			||||||
 | 
					  unsigned short port = 7681;
 | 
				
			||||||
 | 
					} nssServer;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool StartWifi(const char* wifiSsid, const char* wifiPassword, bool hotspotFallback) {
 | 
				
			||||||
#if UNO_R4 || ARDUINO_ARCH_RP2040
 | 
					#if UNO_R4 || ARDUINO_ARCH_RP2040
 | 
				
			||||||
  if (WiFi.status() == WL_NO_MODULE) {
 | 
					  if (WiFi.status() == WL_NO_MODULE) {
 | 
				
			||||||
    Serial.println("WiFi not present, WiFiSync is disabled");
 | 
					    Serial.println("WiFi not present, WiFiSync is disabled");
 | 
				
			||||||
@ -83,10 +114,8 @@ bool StartWifi(const char *wifiSsid, const char *wifiPassword,
 | 
				
			|||||||
#if ESP32
 | 
					#if ESP32
 | 
				
			||||||
    printf("Checking credentials in flash\n");
 | 
					    printf("Checking credentials in flash\n");
 | 
				
			||||||
    wifiPreferences.begin(PREFERENCES_NAMESPACE);
 | 
					    wifiPreferences.begin(PREFERENCES_NAMESPACE);
 | 
				
			||||||
    wifiPreferences.getBytes(STORAGE_KEY_WIFI, &credentials,
 | 
					    wifiPreferences.getBytes(STORAGE_KEY_WIFI, &credentials, sizeof(credentials));
 | 
				
			||||||
                             sizeof(credentials));
 | 
					    if (strcmp(wifiSsid, credentials.ssid) != 0 || strcmp(wifiPassword, credentials.password) != 0) {
 | 
				
			||||||
    if (strcmp(wifiSsid, credentials.ssid) != 0 ||
 | 
					 | 
				
			||||||
        strcmp(wifiPassword, credentials.password) != 0) {
 | 
					 | 
				
			||||||
      printf("Updating credentials in flash...");
 | 
					      printf("Updating credentials in flash...");
 | 
				
			||||||
      const int ssidLen = strlen(wifiSsid);
 | 
					      const int ssidLen = strlen(wifiSsid);
 | 
				
			||||||
      if (ssidLen < 32) {
 | 
					      if (ssidLen < 32) {
 | 
				
			||||||
@ -99,8 +128,7 @@ bool StartWifi(const char *wifiSsid, const char *wifiPassword,
 | 
				
			|||||||
        memcpy(credentials.password, wifiPassword, pwdLen);
 | 
					        memcpy(credentials.password, wifiPassword, pwdLen);
 | 
				
			||||||
        credentials.password[pwdLen] = '\0';
 | 
					        credentials.password[pwdLen] = '\0';
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      wifiPreferences.putBytes(STORAGE_KEY_WIFI, &credentials,
 | 
					      wifiPreferences.putBytes(STORAGE_KEY_WIFI, &credentials, sizeof(credentials));
 | 
				
			||||||
                               sizeof(credentials));
 | 
					 | 
				
			||||||
      printf(" completed.\n");
 | 
					      printf(" completed.\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    wifiPreferences.end();
 | 
					    wifiPreferences.end();
 | 
				
			||||||
@ -132,12 +160,20 @@ void CheckFirmware(String url, String FIRMWARE_NAME, int FIRMWARE_VERSION) {
 | 
				
			|||||||
      Serial.println("Preparing to update firmware.");
 | 
					      Serial.println("Preparing to update firmware.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      String firmwareURL = url + FIRMWARE_NAME + ".bin";
 | 
					      String firmwareURL = url + FIRMWARE_NAME + ".bin";
 | 
				
			||||||
 | 
					#if defined(ESP32)
 | 
				
			||||||
 | 
					      t_httpUpdate_return ret = httpUpdate.update(client, firmwareURL);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
      t_httpUpdate_return ret = ESPhttpUpdate.update(client, firmwareURL);
 | 
					      t_httpUpdate_return ret = ESPhttpUpdate.update(client, firmwareURL);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
      switch (ret) {
 | 
					      switch (ret) {
 | 
				
			||||||
        case HTTP_UPDATE_FAILED:
 | 
					        case HTTP_UPDATE_FAILED:
 | 
				
			||||||
        Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s",
 | 
					#if defined(ESP32)
 | 
				
			||||||
                      ESPhttpUpdate.getLastError(),
 | 
					          Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s", httpUpdate.getLastError(),
 | 
				
			||||||
 | 
					                        httpUpdate.getLastErrorString().c_str());
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					          Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s", ESPhttpUpdate.getLastError(),
 | 
				
			||||||
                        ESPhttpUpdate.getLastErrorString().c_str());
 | 
					                        ESPhttpUpdate.getLastErrorString().c_str());
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case HTTP_UPDATE_NO_UPDATES:
 | 
					        case HTTP_UPDATE_NO_UPDATES:
 | 
				
			||||||
          Serial.println("HTTP_UPDATE_NO_UPDATES");
 | 
					          Serial.println("HTTP_UPDATE_NO_UPDATES");
 | 
				
			||||||
							
								
								
									
										0
									
								
								Arduino/Participant.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								Arduino/Participant.cpp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										22
									
								
								Arduino/Participant.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Arduino/Participant.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../Participant.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					namespace Arduino {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Participant : public RoboidControl::Participant {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  void Setup(int localPort, const char* remoteIpAddress, int remotePort);
 | 
				
			||||||
 | 
					  void Receive();
 | 
				
			||||||
 | 
					  bool Send(RemoteParticipant* remoteParticipant, int bufferSize);
 | 
				
			||||||
 | 
					  bool Publish(IMessage* msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 protected:
 | 
				
			||||||
 | 
					  void GetBroadcastAddress();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace Arduino
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
@ -27,7 +27,14 @@ else()
 | 
				
			|||||||
        .
 | 
					        .
 | 
				
			||||||
        LinearAlgebra
 | 
					        LinearAlgebra
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    file(GLOB srcs *.cpp Sensors/*.cpp Messages/*.cpp)
 | 
					    file(GLOB srcs 
 | 
				
			||||||
 | 
					        *.cpp
 | 
				
			||||||
 | 
					        Sensors/*.cpp
 | 
				
			||||||
 | 
					        Messages/*.cpp
 | 
				
			||||||
 | 
					        Arduino/*.cpp
 | 
				
			||||||
 | 
					        Posix/*.cpp
 | 
				
			||||||
 | 
					        Windows/*.cpp
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    add_library(ControlCore STATIC ${srcs})
 | 
					    add_library(ControlCore STATIC ${srcs})
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    enable_testing()
 | 
					    enable_testing()
 | 
				
			||||||
 | 
				
			|||||||
@ -42,7 +42,7 @@ DOXYFILE_ENCODING      = UTF-8
 | 
				
			|||||||
# title of most generated pages and in a few other places.
 | 
					# title of most generated pages and in a few other places.
 | 
				
			||||||
# The default value is: My Project.
 | 
					# The default value is: My Project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PROJECT_NAME           = "Control Core for C++"
 | 
					PROJECT_NAME           = "Roboid Control for C++"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
 | 
					# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
 | 
				
			||||||
# could be handy for archiving the generated documentation or if some version
 | 
					# could be handy for archiving the generated documentation or if some version
 | 
				
			||||||
@ -61,14 +61,14 @@ PROJECT_BRIEF          =
 | 
				
			|||||||
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
 | 
					# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
 | 
				
			||||||
# the logo to the output directory.
 | 
					# the logo to the output directory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PROJECT_LOGO           = //intranet/home/Afbeeldingen/PasserVR/Logos/Logo3NameRight100.png
 | 
					PROJECT_LOGO           = //intranet/home/Afbeeldingen/PasserVR/Logos/PasserLife/PasserLifeLogoLeft_300.png
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
 | 
					# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
 | 
				
			||||||
# into which the generated documentation will be written. If a relative path is
 | 
					# into which the generated documentation will be written. If a relative path is
 | 
				
			||||||
# entered, it will be relative to the location where doxygen was started. If
 | 
					# entered, it will be relative to the location where doxygen was started. If
 | 
				
			||||||
# left blank the current directory will be used.
 | 
					# left blank the current directory will be used.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OUTPUT_DIRECTORY       = //intranet/web/passer_life/apis/ControlCore/Cpp/
 | 
					OUTPUT_DIRECTORY       = //intranet/web/roboidcontrol_doc/Cpp/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096
 | 
					# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096
 | 
				
			||||||
# sub-directories (in 2 levels) under the output directory of each output format
 | 
					# sub-directories (in 2 levels) under the output directory of each output format
 | 
				
			||||||
@ -777,7 +777,7 @@ MAX_INITIALIZER_LINES  = 30
 | 
				
			|||||||
# list will mention the files that were used to generate the documentation.
 | 
					# list will mention the files that were used to generate the documentation.
 | 
				
			||||||
# The default value is: YES.
 | 
					# The default value is: YES.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SHOW_USED_FILES        = YES
 | 
					SHOW_USED_FILES        = NO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
 | 
					# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
 | 
				
			||||||
# will remove the Files entry from the Quick Index and from the Folder Tree View
 | 
					# will remove the Files entry from the Quick Index and from the Folder Tree View
 | 
				
			||||||
@ -1044,7 +1044,7 @@ RECURSIVE              = YES
 | 
				
			|||||||
# Note that relative paths are relative to the directory from which doxygen is
 | 
					# Note that relative paths are relative to the directory from which doxygen is
 | 
				
			||||||
# run.
 | 
					# run.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXCLUDE                =
 | 
					EXCLUDE                = ../LinearAlgebra
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
 | 
					# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
 | 
				
			||||||
# directories that are symbolic links (a Unix file system feature) are excluded
 | 
					# directories that are symbolic links (a Unix file system feature) are excluded
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,9 @@
 | 
				
			|||||||
#include "CustomMsg.h"
 | 
					#include "BinaryMsg.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CustomMsg::CustomMsg(char *buffer) {
 | 
					BinaryMsg::BinaryMsg(char *buffer) {
 | 
				
			||||||
  unsigned char ix = 1;
 | 
					  unsigned char ix = 1;
 | 
				
			||||||
  this->networkId = buffer[ix++];
 | 
					  this->networkId = buffer[ix++];
 | 
				
			||||||
  this->thingId = buffer[ix++];
 | 
					  this->thingId = buffer[ix++];
 | 
				
			||||||
@ -12,17 +12,17 @@ CustomMsg::CustomMsg(char *buffer) {
 | 
				
			|||||||
                   // lifetime is shorter than the buffer lifetime...
 | 
					                   // lifetime is shorter than the buffer lifetime...
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CustomMsg::CustomMsg(unsigned char networkId, Thing *thing) {
 | 
					BinaryMsg::BinaryMsg(unsigned char networkId, Thing *thing) {
 | 
				
			||||||
  this->networkId = networkId;
 | 
					  this->networkId = networkId;
 | 
				
			||||||
  this->thingId = thing->id;
 | 
					  this->thingId = thing->id;
 | 
				
			||||||
  this->thing = thing;
 | 
					  this->thing = thing;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CustomMsg::~CustomMsg() {}
 | 
					BinaryMsg::~BinaryMsg() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned char CustomMsg::Serialize(char *buffer) {
 | 
					unsigned char BinaryMsg::Serialize(char *buffer) {
 | 
				
			||||||
  unsigned char ix = this->length;
 | 
					  unsigned char ix = this->length;
 | 
				
			||||||
  this->thing->SendBytes(buffer, &ix);
 | 
					  this->thing->GenerateBinary(buffer, &ix);
 | 
				
			||||||
  if (ix <= this->length) // in this case, no data is actually sent
 | 
					  if (ix <= this->length) // in this case, no data is actually sent
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -32,10 +32,10 @@ unsigned char CustomMsg::Serialize(char *buffer) {
 | 
				
			|||||||
  return ix;
 | 
					  return ix;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CustomMsg CustomMsg::Receive(char *buffer, unsigned char bufferSize) {
 | 
					BinaryMsg BinaryMsg::Receive(char *buffer, unsigned char bufferSize) {
 | 
				
			||||||
  CustomMsg msg = CustomMsg(buffer);
 | 
					  BinaryMsg msg = BinaryMsg(buffer);
 | 
				
			||||||
  return msg;
 | 
					  return msg;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					} // namespace RoboidControl
 | 
				
			||||||
} // namespace Passer
 | 
					} // namespace Passer
 | 
				
			||||||
@ -3,9 +3,9 @@
 | 
				
			|||||||
#include "Messages.h"
 | 
					#include "Messages.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CustomMsg : public IMessage {
 | 
					class BinaryMsg : public IMessage {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  static const unsigned char id = 0xB1;
 | 
					  static const unsigned char id = 0xB1;
 | 
				
			||||||
  static const unsigned length = 3;
 | 
					  static const unsigned length = 3;
 | 
				
			||||||
@ -17,14 +17,14 @@ public:
 | 
				
			|||||||
  unsigned char bytesSize;
 | 
					  unsigned char bytesSize;
 | 
				
			||||||
  char *bytes = nullptr;
 | 
					  char *bytes = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CustomMsg(char *buffer);
 | 
					  BinaryMsg(char *buffer);
 | 
				
			||||||
  CustomMsg(unsigned char networkId, Thing *thing);
 | 
					  BinaryMsg(unsigned char networkId, Thing *thing);
 | 
				
			||||||
  virtual ~CustomMsg();
 | 
					  virtual ~BinaryMsg();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual unsigned char Serialize(char *buffer) override;
 | 
					  virtual unsigned char Serialize(char *buffer) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static CustomMsg Receive(char *buffer, unsigned char bufferSize);
 | 
					  static BinaryMsg Receive(char *buffer, unsigned char bufferSize);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					} // namespace RoboidControl
 | 
				
			||||||
} // namespace Passer
 | 
					} // namespace Passer
 | 
				
			||||||
@ -1,23 +0,0 @@
 | 
				
			|||||||
#include "ClientMsg.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Passer::Control {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ClientMsg::ClientMsg(char networkId) { this->networkId = networkId; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ClientMsg::ClientMsg(const char *buffer) { this->networkId = buffer[1]; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ClientMsg::~ClientMsg() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsigned char ClientMsg::Serialize(char *buffer) {
 | 
					 | 
				
			||||||
  unsigned char ix = 0;
 | 
					 | 
				
			||||||
  buffer[ix++] = this->id;
 | 
					 | 
				
			||||||
  buffer[ix++] = this->networkId;
 | 
					 | 
				
			||||||
  return ClientMsg::length;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// bool ClientMsg::Send(Participant *participant, unsigned char networkId) {
 | 
					 | 
				
			||||||
//   ClientMsg msg = ClientMsg()
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
// Client Msg
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace Passer::Control
 | 
					 | 
				
			||||||
@ -1,25 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "Messages.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Passer {
 | 
					 | 
				
			||||||
namespace Control {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// @brief A client message announces the presence of a participant
 | 
					 | 
				
			||||||
/// When received by another participant, it can be followed by a NetworkIdMsg
 | 
					 | 
				
			||||||
/// to announce that participant to this client such that it can join privately
 | 
					 | 
				
			||||||
class ClientMsg : public IMessage {
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
  static const unsigned char id = 0xA0;
 | 
					 | 
				
			||||||
  static const unsigned char length = 2;
 | 
					 | 
				
			||||||
  unsigned char networkId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ClientMsg(char networkId);
 | 
					 | 
				
			||||||
  ClientMsg(const char *buffer);
 | 
					 | 
				
			||||||
  virtual ~ClientMsg();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  virtual unsigned char Serialize(char *buffer) override;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace Control
 | 
					 | 
				
			||||||
} // namespace Passer
 | 
					 | 
				
			||||||
@ -1,13 +1,15 @@
 | 
				
			|||||||
#include "DestroyMsg.h"
 | 
					#include "DestroyMsg.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DestroyMsg::DestroyMsg(unsigned char networkId, Thing *thing) {
 | 
					DestroyMsg::DestroyMsg(unsigned char networkId, Thing *thing) {
 | 
				
			||||||
  this->networkId = networkId;
 | 
					  this->networkId = networkId;
 | 
				
			||||||
  this->thingId = thing->id;
 | 
					  this->thingId = thing->id;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DestroyMsg::DestroyMsg(char* buffer) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DestroyMsg::~DestroyMsg() {}
 | 
					DestroyMsg::~DestroyMsg() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned char DestroyMsg::Serialize(char *buffer) {
 | 
					unsigned char DestroyMsg::Serialize(char *buffer) {
 | 
				
			||||||
@ -18,5 +20,5 @@ unsigned char DestroyMsg::Serialize(char *buffer) {
 | 
				
			|||||||
  return ix;
 | 
					  return ix;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					} // namespace RoboidControl
 | 
				
			||||||
} // namespace Passer
 | 
					} // namespace Passer
 | 
				
			||||||
 | 
				
			|||||||
@ -1,19 +1,31 @@
 | 
				
			|||||||
#include "Messages.h"
 | 
					#include "Messages.h"
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief Message notifiying that a Thing no longer exists
 | 
				
			||||||
class DestroyMsg : public IMessage {
 | 
					class DestroyMsg : public IMessage {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					  /// @brief The message ID
 | 
				
			||||||
  static const unsigned char id = 0x20;
 | 
					  static const unsigned char id = 0x20;
 | 
				
			||||||
 | 
					  /// @brief The length of the message
 | 
				
			||||||
  static const unsigned length = 3;
 | 
					  static const unsigned length = 3;
 | 
				
			||||||
 | 
					  /// @brief The network ID of the thing
 | 
				
			||||||
  unsigned char networkId;
 | 
					  unsigned char networkId;
 | 
				
			||||||
 | 
					  /// @brief The ID of the thing
 | 
				
			||||||
  unsigned char thingId;
 | 
					  unsigned char thingId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief Create a message for sending
 | 
				
			||||||
 | 
					  /// @param networkId The network ID of the thing
 | 
				
			||||||
 | 
					  /// @param thing The ID of the thing
 | 
				
			||||||
  DestroyMsg(unsigned char networkId, Thing *thing);
 | 
					  DestroyMsg(unsigned char networkId, Thing *thing);
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::IMessage(char*)
 | 
				
			||||||
 | 
					  DestroyMsg(char * buffer);
 | 
				
			||||||
 | 
					  /// @brief Destructor for the message 
 | 
				
			||||||
  virtual ~DestroyMsg();
 | 
					  virtual ~DestroyMsg();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::Serialize
 | 
				
			||||||
  virtual unsigned char Serialize(char *buffer) override;
 | 
					  virtual unsigned char Serialize(char *buffer) override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					} // namespace RoboidControl
 | 
				
			||||||
} // namespace Passer
 | 
					} // namespace Passer
 | 
				
			||||||
@ -1,15 +1,32 @@
 | 
				
			|||||||
#include "Messages.h"
 | 
					#include "Messages.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief Message to request details for a Thing
 | 
				
			||||||
class InvestigateMsg : public IMessage {
 | 
					class InvestigateMsg : public IMessage {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
 | 
					  /// @brief The message ID
 | 
				
			||||||
  static const unsigned char id = 0x81;
 | 
					  static const unsigned char id = 0x81;
 | 
				
			||||||
 | 
					  /// @brief The length of the message
 | 
				
			||||||
  static const unsigned char length = 3;
 | 
					  static const unsigned char length = 3;
 | 
				
			||||||
 | 
					  /// @brief The network ID of the thing
 | 
				
			||||||
  unsigned char networkId;
 | 
					  unsigned char networkId;
 | 
				
			||||||
 | 
					  /// @brief the ID of the thing
 | 
				
			||||||
  unsigned char thingId;
 | 
					  unsigned char thingId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  InvestigateMsg(char *buffer);
 | 
					  /// @brief Create a new message for sending
 | 
				
			||||||
 | 
					  /// @param networkId The network ID for the thing
 | 
				
			||||||
 | 
					  /// @param thingId The ID of the thing
 | 
				
			||||||
  InvestigateMsg(unsigned char networkId, unsigned char thingId);
 | 
					  InvestigateMsg(unsigned char networkId, unsigned char thingId);
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::IMessage(char*)
 | 
				
			||||||
 | 
					  InvestigateMsg(char* buffer);
 | 
				
			||||||
 | 
					  /// @brief Destructor for the message
 | 
				
			||||||
  virtual ~InvestigateMsg();
 | 
					  virtual ~InvestigateMsg();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::Serialize
 | 
				
			||||||
  virtual unsigned char Serialize(char* buffer) override;
 | 
					  virtual unsigned char Serialize(char* buffer) override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
@ -57,7 +57,7 @@ Spherical16 LowLevelMessages::ReceiveSpherical16(const char *buffer,
 | 
				
			|||||||
  return s;
 | 
					  return s;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Passer::Control::LowLevelMessages::SendQuat32(char *buffer,
 | 
					void Passer::RoboidControl::LowLevelMessages::SendQuat32(char *buffer,
 | 
				
			||||||
                                                   unsigned char *ix,
 | 
					                                                   unsigned char *ix,
 | 
				
			||||||
                                                   SwingTwist16 rotation) {
 | 
					                                                   SwingTwist16 rotation) {
 | 
				
			||||||
  Quaternion q = rotation.ToQuaternion();
 | 
					  Quaternion q = rotation.ToQuaternion();
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@
 | 
				
			|||||||
#include "LinearAlgebra/SwingTwist.h"
 | 
					#include "LinearAlgebra/SwingTwist.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LowLevelMessages {
 | 
					class LowLevelMessages {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
@ -20,6 +20,6 @@ public:
 | 
				
			|||||||
  static SwingTwist16 ReceiveQuat32(const char *buffer, unsigned char *ix);
 | 
					  static SwingTwist16 ReceiveQuat32(const char *buffer, unsigned char *ix);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					} // namespace RoboidControl
 | 
				
			||||||
} // namespace Passer
 | 
					} // namespace Passer
 | 
				
			||||||
using namespace Passer::Control;
 | 
					using namespace Passer::RoboidControl;
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include "Messages.h"
 | 
					#include "Messages.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "LowLevelMessages.h"
 | 
					#include "LowLevelMessages.h"
 | 
				
			||||||
// #include "Messages/CustomMsg.h"
 | 
					// #include "Messages/BinaryMsg.h"
 | 
				
			||||||
#include "Participant.h"
 | 
					#include "Participant.h"
 | 
				
			||||||
#include "string.h"
 | 
					#include "string.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -11,7 +11,11 @@ IMessage::IMessage() {}
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// IMessage::IMessage(unsigned char *buffer) { Deserialize(buffer); }
 | 
					// IMessage::IMessage(unsigned char *buffer) { Deserialize(buffer); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned char IMessage::Serialize(char *buffer) { return 0; }
 | 
					IMessage::IMessage(char* buffer) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned char IMessage::Serialize(char* buffer) {
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// void IMessage::Deserialize(unsigned char *buffer) {}
 | 
					// void IMessage::Deserialize(unsigned char *buffer) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -20,9 +24,9 @@ unsigned char IMessage::Serialize(char *buffer) { return 0; }
 | 
				
			|||||||
//   return client->SendBuffer(msg.Serialize(client->buffer));
 | 
					//   return client->SendBuffer(msg.Serialize(client->buffer));
 | 
				
			||||||
// }
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned char *IMessage::ReceiveMsg(unsigned char packetSize) {
 | 
					// unsigned char *IMessage::ReceiveMsg(unsigned char packetSize) {
 | 
				
			||||||
  return nullptr;
 | 
					//   return nullptr;
 | 
				
			||||||
}
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// bool IMessage::Publish(Participant *participant) {
 | 
					// bool IMessage::Publish(Participant *participant) {
 | 
				
			||||||
//   return participant->PublishBuffer(Serialize(participant->buffer));
 | 
					//   return participant->PublishBuffer(Serialize(participant->buffer));
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ModelUrlMsg::ModelUrlMsg(unsigned char networkId, unsigned char thingId,
 | 
					// ModelUrlMsg::ModelUrlMsg(unsigned char networkId, unsigned char thingId,
 | 
				
			||||||
//                          unsigned char urlLength, const char *url,
 | 
					//                          unsigned char urlLength, const char *url,
 | 
				
			||||||
@ -51,5 +51,5 @@ unsigned char ModelUrlMsg::Serialize(char *buffer) {
 | 
				
			|||||||
  return ix;
 | 
					  return ix;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					} // namespace RoboidControl
 | 
				
			||||||
} // namespace Passer
 | 
					} // namespace Passer
 | 
				
			||||||
@ -1,25 +1,39 @@
 | 
				
			|||||||
#include "Messages.h"
 | 
					#include "Messages.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief Message for communicating the URL for a model of the thing
 | 
				
			||||||
class ModelUrlMsg : public IMessage {
 | 
					class ModelUrlMsg : public IMessage {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					  /// @brief The message ID
 | 
				
			||||||
  static const unsigned char id = 0x90;
 | 
					  static const unsigned char id = 0x90;
 | 
				
			||||||
 | 
					  /// @brief The length of the message without the URL string itself
 | 
				
			||||||
 | 
					  static const unsigned char length = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief The network ID of the thing
 | 
				
			||||||
  unsigned char networkId;
 | 
					  unsigned char networkId;
 | 
				
			||||||
 | 
					  /// @brief The ID of the thing
 | 
				
			||||||
  unsigned char thingId;
 | 
					  unsigned char thingId;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  float scale;
 | 
					  /// @brief The length of the url st5ring, excluding the null terminator
 | 
				
			||||||
  unsigned char urlLength;
 | 
					  unsigned char urlLength;
 | 
				
			||||||
 | 
					  /// @brief The url of the model, not terminated by a null character
 | 
				
			||||||
  const char *url;
 | 
					  const char *url;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ModelUrlMsg(const char *buffer);
 | 
					  /// @brief Create a new message for sending
 | 
				
			||||||
 | 
					  /// @param networkId The network ID of the thing
 | 
				
			||||||
 | 
					  /// @param thing The thing for which to send the mode URL
 | 
				
			||||||
  ModelUrlMsg(unsigned char networkId, Thing *thing);
 | 
					  ModelUrlMsg(unsigned char networkId, Thing *thing);
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::IMessage(char*)
 | 
				
			||||||
 | 
					  ModelUrlMsg(const char *buffer);
 | 
				
			||||||
  //   ModelUrlMsg(unsigned char networkId, unsigned char thingId,
 | 
					  //   ModelUrlMsg(unsigned char networkId, unsigned char thingId,
 | 
				
			||||||
  //               unsigned char urlLegth, const char *url, float scale = 1);
 | 
					  //               unsigned char urlLegth, const char *url, float scale = 1);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  /// @brief Destructor for the message
 | 
				
			||||||
  virtual ~ModelUrlMsg();
 | 
					  virtual ~ModelUrlMsg();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::Serialize
 | 
				
			||||||
  virtual unsigned char Serialize(char *buffer) override;
 | 
					  virtual unsigned char Serialize(char *buffer) override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,17 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NameMsg::NameMsg(unsigned char networkId, Thing *thing) {
 | 
				
			||||||
 | 
					  this->networkId = networkId;
 | 
				
			||||||
 | 
					  this->thingId = thing->id;
 | 
				
			||||||
 | 
					  if (thing->name == nullptr)
 | 
				
			||||||
 | 
					    this->nameLength = 0;
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    this->nameLength = strlen(thing->name);
 | 
				
			||||||
 | 
					  this->name = thing->name; // dangerous!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NameMsg::NameMsg(const char *buffer) {
 | 
					NameMsg::NameMsg(const char *buffer) {
 | 
				
			||||||
  unsigned char ix = 1; // first byte is msg id
 | 
					  unsigned char ix = 1; // first byte is msg id
 | 
				
			||||||
@ -18,16 +28,6 @@ NameMsg::NameMsg(const char *buffer) {
 | 
				
			|||||||
  this->name = name;
 | 
					  this->name = name;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NameMsg::NameMsg(unsigned char networkId, Thing *thing) {
 | 
					 | 
				
			||||||
  this->networkId = networkId;
 | 
					 | 
				
			||||||
  this->thingId = thing->id;
 | 
					 | 
				
			||||||
  if (thing->name == nullptr)
 | 
					 | 
				
			||||||
    this->nameLength = 0;
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    this->nameLength = strlen(thing->name);
 | 
					 | 
				
			||||||
  this->name = thing->name; // dangerous!
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
NameMsg::~NameMsg() {
 | 
					NameMsg::~NameMsg() {
 | 
				
			||||||
  delete[] this->name;
 | 
					  delete[] this->name;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,25 +1,39 @@
 | 
				
			|||||||
#include "Messages.h"
 | 
					#include "Messages.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief Message for communicating the name of a thing
 | 
				
			||||||
class NameMsg : public IMessage {
 | 
					class NameMsg : public IMessage {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
 | 
					  /// @brief The message ID
 | 
				
			||||||
  static const unsigned char id = 0x91;
 | 
					  static const unsigned char id = 0x91;
 | 
				
			||||||
 | 
					  /// @brief The length of the message
 | 
				
			||||||
  static const unsigned char length = 4;
 | 
					  static const unsigned char length = 4;
 | 
				
			||||||
 | 
					  /// @brief The network ID of the thing
 | 
				
			||||||
  unsigned char networkId;
 | 
					  unsigned char networkId;
 | 
				
			||||||
 | 
					  /// @brief The ID of the thing
 | 
				
			||||||
  unsigned char thingId;
 | 
					  unsigned char thingId;
 | 
				
			||||||
 | 
					  /// @brief The length of the name, excluding the null terminator
 | 
				
			||||||
  unsigned char nameLength;
 | 
					  unsigned char nameLength;
 | 
				
			||||||
 | 
					  /// @brief The name of the thing, not terminated with a null character
 | 
				
			||||||
  const char* name;
 | 
					  const char* name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  NameMsg(const char *buffer);
 | 
					  /// @brief Create a new message for sending
 | 
				
			||||||
 | 
					  /// @param networkId The network ID of the thing
 | 
				
			||||||
 | 
					  /// @param thing The ID of the thing
 | 
				
			||||||
  NameMsg(unsigned char networkId, Thing* thing);
 | 
					  NameMsg(unsigned char networkId, Thing* thing);
 | 
				
			||||||
  //   NameMsg(unsigned char networkId, unsigned char thingId, const char *name,
 | 
					  //   NameMsg(unsigned char networkId, unsigned char thingId, const char *name,
 | 
				
			||||||
  //           unsigned char nameLength);
 | 
					  //           unsigned char nameLength);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::IMessage(char*)
 | 
				
			||||||
 | 
					  NameMsg(const char* buffer);
 | 
				
			||||||
 | 
					  /// @brief Destructor for the message
 | 
				
			||||||
  virtual ~NameMsg();
 | 
					  virtual ~NameMsg();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::Serialize
 | 
				
			||||||
  virtual unsigned char Serialize(char* buffer) override;
 | 
					  virtual unsigned char Serialize(char* buffer) override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
}  // namespace Passer
 | 
					}  // namespace Passer
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include "NetworkIdMsg.h"
 | 
					#include "NetworkIdMsg.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NetworkIdMsg::NetworkIdMsg(const char *buffer) { this->networkId = buffer[1]; }
 | 
					NetworkIdMsg::NetworkIdMsg(const char *buffer) { this->networkId = buffer[1]; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,20 +1,28 @@
 | 
				
			|||||||
#include "Messages.h"
 | 
					#include "Messages.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief A message communicating the network ID for that participant
 | 
				
			||||||
class NetworkIdMsg : public IMessage {
 | 
					class NetworkIdMsg : public IMessage {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					  /// @brief The message ID
 | 
				
			||||||
  static const unsigned char id = 0xA1;
 | 
					  static const unsigned char id = 0xA1;
 | 
				
			||||||
 | 
					  /// @brief The length of the message
 | 
				
			||||||
  static const unsigned char length = 2;
 | 
					  static const unsigned char length = 2;
 | 
				
			||||||
 | 
					  /// @brief The network ID for the participant
 | 
				
			||||||
  unsigned char networkId;
 | 
					  unsigned char networkId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  NetworkIdMsg(const char *buffer);
 | 
					  /// @brief Create a new message for sending
 | 
				
			||||||
 | 
					  /// @param networkId The network ID for the participant
 | 
				
			||||||
  NetworkIdMsg(unsigned char networkId);
 | 
					  NetworkIdMsg(unsigned char networkId);
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::IMessage(char*)
 | 
				
			||||||
 | 
					  NetworkIdMsg(const char *buffer);
 | 
				
			||||||
 | 
					  /// @brief Destructor for the message
 | 
				
			||||||
  virtual ~NetworkIdMsg();
 | 
					  virtual ~NetworkIdMsg();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::Serialize
 | 
				
			||||||
  virtual unsigned char Serialize(char *buffer) override;
 | 
					  virtual unsigned char Serialize(char *buffer) override;
 | 
				
			||||||
  // static NetworkIdMsg Receive(char *buffer, unsigned char bufferSize);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					} // namespace Control
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										23
									
								
								Messages/ParticipantMsg.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								Messages/ParticipantMsg.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					#include "ParticipantMsg.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer::RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ParticipantMsg::ParticipantMsg(char networkId) { this->networkId = networkId; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ParticipantMsg::ParticipantMsg(const char *buffer) { this->networkId = buffer[1]; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ParticipantMsg::~ParticipantMsg() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned char ParticipantMsg::Serialize(char *buffer) {
 | 
				
			||||||
 | 
					  unsigned char ix = 0;
 | 
				
			||||||
 | 
					  buffer[ix++] = this->id;
 | 
				
			||||||
 | 
					  buffer[ix++] = this->networkId;
 | 
				
			||||||
 | 
					  return ParticipantMsg::length;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// bool ParticipantMsg::Send(Participant *participant, unsigned char networkId) {
 | 
				
			||||||
 | 
					//   ParticipantMsg msg = ParticipantMsg()
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					// Client Msg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Passer::RoboidControl
 | 
				
			||||||
							
								
								
									
										36
									
								
								Messages/ParticipantMsg.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Messages/ParticipantMsg.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Messages.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief A participant messages notifies other participants of its presence
 | 
				
			||||||
 | 
					/// When received by another participant, it can be followed by a NetworkIdMsg
 | 
				
			||||||
 | 
					/// to announce that participant to this client such that it can join privately
 | 
				
			||||||
 | 
					class ParticipantMsg : public IMessage {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  /// @brief The message ID
 | 
				
			||||||
 | 
					  static const unsigned char id = 0xA0;
 | 
				
			||||||
 | 
					  /// @brief The length of the message
 | 
				
			||||||
 | 
					  static const unsigned char length = 2;
 | 
				
			||||||
 | 
					  /// @brief The network ID known by the participant
 | 
				
			||||||
 | 
					  unsigned char networkId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief Create a new message for sending
 | 
				
			||||||
 | 
					  /// @param networkId The network ID known by the participant
 | 
				
			||||||
 | 
					  ParticipantMsg(char networkId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::IMessage(char*)
 | 
				
			||||||
 | 
					  ParticipantMsg(const char* buffer);
 | 
				
			||||||
 | 
					  /// @brief Destructor for the message
 | 
				
			||||||
 | 
					  virtual ~ParticipantMsg();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief Serialize the message into a byte array
 | 
				
			||||||
 | 
					  /// @param buffer The buffer to serialize into
 | 
				
			||||||
 | 
					  /// @return The length of the message in the buffer
 | 
				
			||||||
 | 
					  virtual unsigned char Serialize(char* buffer) override;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
@ -1,30 +1,66 @@
 | 
				
			|||||||
#include "Messages.h"
 | 
					#include "Messages.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief Message to communicate the pose of the thing
 | 
				
			||||||
 | 
					/// The pose is in local space relative to the parent. If there is not parent (the thing is a root thing), the pose will
 | 
				
			||||||
 | 
					/// be in world space.
 | 
				
			||||||
class PoseMsg : public IMessage {
 | 
					class PoseMsg : public IMessage {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
 | 
					  /// @brief The message ID
 | 
				
			||||||
  static const unsigned char id = 0x10;
 | 
					  static const unsigned char id = 0x10;
 | 
				
			||||||
 | 
					  /// @brief The length of the message
 | 
				
			||||||
  unsigned char length = 4 + 4 + 4;
 | 
					  unsigned char length = 4 + 4 + 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief The network ID of the thing
 | 
				
			||||||
  unsigned char networkId;
 | 
					  unsigned char networkId;
 | 
				
			||||||
 | 
					  /// @brief The ID of the thing
 | 
				
			||||||
  unsigned char thingId;
 | 
					  unsigned char thingId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief Bit pattern stating which pose components are available
 | 
				
			||||||
  unsigned char poseType;
 | 
					  unsigned char poseType;
 | 
				
			||||||
 | 
					  /// @brief Bit pattern for a pose with position
 | 
				
			||||||
  static const unsigned char Pose_Position = 0x01;
 | 
					  static const unsigned char Pose_Position = 0x01;
 | 
				
			||||||
 | 
					  /// @brief Bit pattern for a pose with orientation
 | 
				
			||||||
  static const unsigned char Pose_Orientation = 0x02;
 | 
					  static const unsigned char Pose_Orientation = 0x02;
 | 
				
			||||||
  static const unsigned char Pose_LinearVelocity = 0x04;  // For future use
 | 
					  /// @brief Bit pattern for a pose with linear velocity
 | 
				
			||||||
  static const unsigned char Pose_AngularVelocity = 0x08; // For future use
 | 
					  static const unsigned char Pose_LinearVelocity = 0x04;
 | 
				
			||||||
 | 
					  /// @brief Bit pattern for a pose with angular velocity
 | 
				
			||||||
 | 
					  static const unsigned char Pose_AngularVelocity = 0x08;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief The position of the thing in local space in meters
 | 
				
			||||||
  Spherical16 position;
 | 
					  Spherical16 position;
 | 
				
			||||||
 | 
					  /// @brief The orientation of the thing in local space
 | 
				
			||||||
  SwingTwist16 orientation;
 | 
					  SwingTwist16 orientation;
 | 
				
			||||||
 | 
					  /// @brief The linear velocity of the thing in local space in meters per second
 | 
				
			||||||
  Spherical16 linearVelocity;
 | 
					  Spherical16 linearVelocity;
 | 
				
			||||||
 | 
					  /// @brief The angular velocity of the thing in local space
 | 
				
			||||||
  Spherical16 angularVelocity;
 | 
					  Spherical16 angularVelocity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PoseMsg(unsigned char networkId, unsigned char thingId,
 | 
					  /// @brief Create a new message for sending
 | 
				
			||||||
          unsigned char poseType, Spherical16 position,
 | 
					  /// @param networkId The network ID of the thing
 | 
				
			||||||
          SwingTwist16 orientation, Spherical16 linearVelocity = Spherical16(),
 | 
					  /// @param thingId The ID of the thing
 | 
				
			||||||
 | 
					  /// @param poseType Bit pattern stating which pose components are available
 | 
				
			||||||
 | 
					  /// @param position The position of the thing in local space in meters
 | 
				
			||||||
 | 
					  /// @param orientation The orientation of the thing in local space
 | 
				
			||||||
 | 
					  /// @param linearVelocity The linear velocity of the thing in local space in meters per second
 | 
				
			||||||
 | 
					  /// @param angularVelocity The angular velocity of the thing in local space
 | 
				
			||||||
 | 
					  PoseMsg(unsigned char networkId,
 | 
				
			||||||
 | 
					          unsigned char thingId,
 | 
				
			||||||
 | 
					          unsigned char poseType,
 | 
				
			||||||
 | 
					          Spherical16 position,
 | 
				
			||||||
 | 
					          SwingTwist16 orientation,
 | 
				
			||||||
 | 
					          Spherical16 linearVelocity = Spherical16(),
 | 
				
			||||||
          Spherical16 angularVelocity = Spherical16());
 | 
					          Spherical16 angularVelocity = Spherical16());
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::IMessage(char*)
 | 
				
			||||||
  PoseMsg(const char* buffer);
 | 
					  PoseMsg(const char* buffer);
 | 
				
			||||||
 | 
					  /// @brief Destructor for the message
 | 
				
			||||||
  virtual ~PoseMsg();
 | 
					  virtual ~PoseMsg();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::Serialize
 | 
				
			||||||
  virtual unsigned char Serialize(char* buffer) override;
 | 
					  virtual unsigned char Serialize(char* buffer) override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
							
								
								
									
										37
									
								
								Messages/TextMsg.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Messages/TextMsg.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					#include "TextMsg.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TextMsg::TextMsg(const char* text, unsigned char textLength) {
 | 
				
			||||||
 | 
					  this->text = text;
 | 
				
			||||||
 | 
					  this->textLength = textLength;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TextMsg::TextMsg(char* buffer) {
 | 
				
			||||||
 | 
					  unsigned char ix = 1;  // first byte is msg id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  this->textLength = buffer[ix++];
 | 
				
			||||||
 | 
					  char* text = new char[this->textLength + 1];
 | 
				
			||||||
 | 
					  for (int i = 0; i < this->textLength; i++)
 | 
				
			||||||
 | 
					    text[i] = buffer[ix++];
 | 
				
			||||||
 | 
					  text[this->textLength] = '\0';
 | 
				
			||||||
 | 
					  this->text = text;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TextMsg::~TextMsg() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned char TextMsg::Serialize(char* buffer) {
 | 
				
			||||||
 | 
					    if (this->textLength == 0 || this->text == nullptr)
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  unsigned char ix = 0;
 | 
				
			||||||
 | 
					  buffer[ix++] = this->id;
 | 
				
			||||||
 | 
					  buffer[ix++] = this->textLength;
 | 
				
			||||||
 | 
					  for (int nameIx = 0; nameIx < this->textLength; nameIx++)
 | 
				
			||||||
 | 
					    buffer[ix++] = this->text[nameIx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return ix;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
							
								
								
									
										35
									
								
								Messages/TextMsg.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								Messages/TextMsg.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					#include "Messages.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief Message for sending generic text
 | 
				
			||||||
 | 
					class TextMsg : public IMessage {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  /// @brief The message ID
 | 
				
			||||||
 | 
					  static const unsigned char id = 0xB0;
 | 
				
			||||||
 | 
					  /// @brief The length of the message without the text itself
 | 
				
			||||||
 | 
					  static const unsigned char length = 2;
 | 
				
			||||||
 | 
					  /// @brief The network ID of the thing
 | 
				
			||||||
 | 
					  unsigned char networkId;
 | 
				
			||||||
 | 
					  /// @brief the ID of the thing
 | 
				
			||||||
 | 
					  unsigned char thingId;
 | 
				
			||||||
 | 
					  /// @brief The text without the null terminator
 | 
				
			||||||
 | 
					  const char* text;
 | 
				
			||||||
 | 
					  /// @brief The length of the text
 | 
				
			||||||
 | 
					  unsigned char textLength;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief Create a new message for sending
 | 
				
			||||||
 | 
					  /// @param text The text
 | 
				
			||||||
 | 
					  TextMsg(const char* text, unsigned char textLength);
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::IMessage(char*)
 | 
				
			||||||
 | 
					  TextMsg(char* buffer);
 | 
				
			||||||
 | 
					  /// @brief Destructor for the message
 | 
				
			||||||
 | 
					  virtual ~TextMsg();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::Serialize
 | 
				
			||||||
 | 
					  virtual unsigned char Serialize(char* buffer) override;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
#include "ThingMsg.h"
 | 
					#include "ThingMsg.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ThingMsg::ThingMsg(const char *buffer) {
 | 
					ThingMsg::ThingMsg(const char *buffer) {
 | 
				
			||||||
  unsigned char ix = 1; // first byte is msg id
 | 
					  unsigned char ix = 1; // first byte is msg id
 | 
				
			||||||
 | 
				
			|||||||
@ -1,25 +1,39 @@
 | 
				
			|||||||
#include "Messages.h"
 | 
					#include "Messages.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief  Message providing generic information about a Thing
 | 
				
			||||||
class ThingMsg : public IMessage {
 | 
					class ThingMsg : public IMessage {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
 | 
					  /// @brief The message ID
 | 
				
			||||||
  static const unsigned char id = 0x80;
 | 
					  static const unsigned char id = 0x80;
 | 
				
			||||||
 | 
					  /// @brief The length of the message
 | 
				
			||||||
  static const unsigned char length = 5;
 | 
					  static const unsigned char length = 5;
 | 
				
			||||||
 | 
					  /// @brief The network ID of the thing
 | 
				
			||||||
  unsigned char networkId;
 | 
					  unsigned char networkId;
 | 
				
			||||||
 | 
					  /// @brief The ID of the thing
 | 
				
			||||||
  unsigned char thingId;
 | 
					  unsigned char thingId;
 | 
				
			||||||
 | 
					  /// @brief The Thing.Type of the thing
 | 
				
			||||||
  unsigned char thingType;
 | 
					  unsigned char thingType;
 | 
				
			||||||
 | 
					  /// @brief The parent of the thing in the hierarachy. This is null for root Things
 | 
				
			||||||
  unsigned char parentId;
 | 
					  unsigned char parentId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ThingMsg(const char *buffer);
 | 
					  /// @brief Create a message for sending
 | 
				
			||||||
 | 
					  /// @param networkId The network ID of the thing</param>
 | 
				
			||||||
 | 
					  /// @param thing The thing
 | 
				
			||||||
  ThingMsg(unsigned char networkId, Thing* thing);
 | 
					  ThingMsg(unsigned char networkId, Thing* thing);
 | 
				
			||||||
  //   ThingMsg(unsigned char networkId, unsigned char thingId,
 | 
					  //   ThingMsg(unsigned char networkId, unsigned char thingId,
 | 
				
			||||||
  //            unsigned char thingType, unsigned char parentId);
 | 
					  //            unsigned char thingType, unsigned char parentId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::IMessage(char*)
 | 
				
			||||||
 | 
					  ThingMsg(const char* buffer);
 | 
				
			||||||
 | 
					  /// @brief Destructor for the message
 | 
				
			||||||
  virtual ~ThingMsg();
 | 
					  virtual ~ThingMsg();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @copydoc Passer::RoboidControl::IMessage::Serialize
 | 
				
			||||||
  virtual unsigned char Serialize(char* buffer) override;
 | 
					  virtual unsigned char Serialize(char* buffer) override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
}  // namespace Passer
 | 
					}  // namespace Passer
 | 
				
			||||||
@ -2,9 +2,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "Thing.h"
 | 
					#include "Thing.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "UdpArduino.h"
 | 
					#include "Arduino/Participant.h"
 | 
				
			||||||
#include "UdpPosix.h"
 | 
					#include "Posix/Participant.h"
 | 
				
			||||||
#include "UdpWindows.h"
 | 
					#include "Windows/Participant.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					#if defined(_WIN32) || defined(_WIN64)
 | 
				
			||||||
#include <winsock2.h>
 | 
					#include <winsock2.h>
 | 
				
			||||||
@ -12,15 +12,15 @@
 | 
				
			|||||||
#pragma comment(lib, "ws2_32.lib")
 | 
					#pragma comment(lib, "ws2_32.lib")
 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					#elif defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
#include <arpa/inet.h>
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
#include <chrono>
 | 
					 | 
				
			||||||
#include <fcntl.h>  // For fcntl
 | 
					#include <fcntl.h>  // For fcntl
 | 
				
			||||||
#include <netinet/in.h>
 | 
					#include <netinet/in.h>
 | 
				
			||||||
#include <sys/socket.h>
 | 
					#include <sys/socket.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <chrono>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Participant::Participant() {}
 | 
					Participant::Participant() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -28,6 +28,7 @@ Participant::Participant(int port) {
 | 
				
			|||||||
  this->ipAddress = "0.0.0.0";
 | 
					  this->ipAddress = "0.0.0.0";
 | 
				
			||||||
  this->port = port;
 | 
					  this->port = port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  this->senders.push_back(this);
 | 
				
			||||||
  this->senders.push_back(this);
 | 
					  this->senders.push_back(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // int randomPort = (rand() % (65535 - 49152 + 1)) + 49152;
 | 
					  // int randomPort = (rand() % (65535 - 49152 + 1)) + 49152;
 | 
				
			||||||
@ -50,16 +51,15 @@ void Participant::begin() {
 | 
				
			|||||||
  SetupUDP(this->localPort, this->ipAddress, this->port);
 | 
					  SetupUDP(this->localPort, this->ipAddress, this->port);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Participant::SetupUDP(int localPort, const char *remoteIpAddress,
 | 
					void Participant::SetupUDP(int localPort, const char* remoteIpAddress, int remotePort) {
 | 
				
			||||||
                           int remotePort) {
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					#if defined(_WIN32) || defined(_WIN64)
 | 
				
			||||||
  UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
 | 
					  Windows::Participant* thisWindows = static_cast<Windows::Participant*>(this);
 | 
				
			||||||
  thisWindows->Setup(localPort, remoteIpAddress, remotePort);
 | 
					  thisWindows->Setup(localPort, remoteIpAddress, remotePort);
 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					#elif defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
  UdpPosix *thisPosix = static_cast<UdpPosix *>(this);
 | 
					  Posix::Participant* thisPosix = static_cast<Posix::Participant*>(this);
 | 
				
			||||||
  thisPosix->Setup(localPort, remoteIpAddress, remotePort);
 | 
					  thisPosix->Setup(localPort, remoteIpAddress, remotePort);
 | 
				
			||||||
#elif defined(ARDUINO)
 | 
					#elif defined(ARDUINO)
 | 
				
			||||||
  UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
 | 
					  Arduino::Participant* thisArduino = static_cast<Arduino::Participant*>(this);
 | 
				
			||||||
  thisArduino->Setup(localPort, remoteIpAddress, remotePort);
 | 
					  thisArduino->Setup(localPort, remoteIpAddress, remotePort);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
  this->connected = true;
 | 
					  this->connected = true;
 | 
				
			||||||
@ -71,8 +71,7 @@ void Participant::Update(unsigned long currentTimeMs) {
 | 
				
			|||||||
    currentTimeMs = millis();
 | 
					    currentTimeMs = millis();
 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					#elif defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
    auto now = std::chrono::steady_clock::now();
 | 
					    auto now = std::chrono::steady_clock::now();
 | 
				
			||||||
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
 | 
					    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
 | 
				
			||||||
        now.time_since_epoch());
 | 
					 | 
				
			||||||
    currentTimeMs = static_cast<unsigned long>(ms.count());
 | 
					    currentTimeMs = static_cast<unsigned long>(ms.count());
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -81,26 +80,29 @@ void Participant::Update(unsigned long currentTimeMs) {
 | 
				
			|||||||
    begin();
 | 
					    begin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (this->publishInterval > 0 && currentTimeMs > this->nextPublishMe) {
 | 
					  if (this->publishInterval > 0 && currentTimeMs > this->nextPublishMe) {
 | 
				
			||||||
    ClientMsg *msg = new ClientMsg(this->networkId);
 | 
					    ParticipantMsg* msg = new ParticipantMsg(this->networkId);
 | 
				
			||||||
    this->Publish(msg);
 | 
					    this->Publish(msg);
 | 
				
			||||||
    delete msg;
 | 
					    delete msg;
 | 
				
			||||||
    std::cout << this->name << " published ClientMsg\n";
 | 
					    std::cout << this->name << " published ParticipantMsg\n";
 | 
				
			||||||
    this->nextPublishMe = currentTimeMs + this->publishInterval;
 | 
					    this->nextPublishMe = currentTimeMs + this->publishInterval;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  this->ReceiveUDP();
 | 
					  this->ReceiveUDP();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  this->UpdateAll(currentTimeMs);
 | 
					  for (Thing* thing : this->things) {
 | 
				
			||||||
 | 
					    if (thing != nullptr)  //} && thing->GetParent() == nullptr)   // update all root things
 | 
				
			||||||
 | 
					      thing->Update(currentTimeMs);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Participant::ReceiveUDP() {
 | 
					void Participant::ReceiveUDP() {
 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					#if defined(_WIN32) || defined(_WIN64)
 | 
				
			||||||
  UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
 | 
					  Windows::Participant* thisWindows = static_cast<Windows::Participant*>(this);
 | 
				
			||||||
  thisWindows->Receive();
 | 
					  thisWindows->Receive();
 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					#elif defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
  UdpPosix *thisPosix = static_cast<UdpPosix *>(this);
 | 
					  Posix::Participant* thisPosix = static_cast<Posix::Participant*>(this);
 | 
				
			||||||
  thisPosix->Receive();
 | 
					  thisPosix->Receive();
 | 
				
			||||||
#elif defined(ARDUINO)
 | 
					#elif defined(ARDUINO)
 | 
				
			||||||
  UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
 | 
					  Arduino::Participant* thisArduino = static_cast<Arduino::Participant*>(this);
 | 
				
			||||||
  thisArduino->Receive();
 | 
					  thisArduino->Receive();
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -123,8 +125,7 @@ Participant *Participant::AddParticipant(const char *ipAddress, int port) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma region Send
 | 
					#pragma region Send
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Participant::SendThingInfo(RemoteParticipant *remoteParticipant,
 | 
					void Participant::SendThingInfo(RemoteParticipant* remoteParticipant, Thing* thing) {
 | 
				
			||||||
                                Thing *thing) {
 | 
					 | 
				
			||||||
  std::cout << "Send thing info\n";
 | 
					  std::cout << "Send thing info\n";
 | 
				
			||||||
  ThingMsg* thingMsg = new ThingMsg(this->networkId, thing);
 | 
					  ThingMsg* thingMsg = new ThingMsg(this->networkId, thing);
 | 
				
			||||||
  this->Send(remoteParticipant, thingMsg);
 | 
					  this->Send(remoteParticipant, thingMsg);
 | 
				
			||||||
@ -137,7 +138,7 @@ void Participant::SendThingInfo(RemoteParticipant *remoteParticipant,
 | 
				
			|||||||
  delete modelMsg;
 | 
					  delete modelMsg;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Passer::Control::Participant::PublishThingInfo(Thing *thing) {
 | 
					void Passer::RoboidControl::Participant::PublishThingInfo(Thing* thing) {
 | 
				
			||||||
  // std::cout << "Publish thing info" << thing->networkId << "\n";
 | 
					  // std::cout << "Publish thing info" << thing->networkId << "\n";
 | 
				
			||||||
  //  Strange, when publishing, the network id is irrelevant, because it is
 | 
					  //  Strange, when publishing, the network id is irrelevant, because it is
 | 
				
			||||||
  //  connected to a specific site...
 | 
					  //  connected to a specific site...
 | 
				
			||||||
@ -150,7 +151,7 @@ void Passer::Control::Participant::PublishThingInfo(Thing *thing) {
 | 
				
			|||||||
  ModelUrlMsg* modelMsg = new ModelUrlMsg(this->networkId, thing);
 | 
					  ModelUrlMsg* modelMsg = new ModelUrlMsg(this->networkId, thing);
 | 
				
			||||||
  this->Publish(modelMsg);
 | 
					  this->Publish(modelMsg);
 | 
				
			||||||
  delete modelMsg;
 | 
					  delete modelMsg;
 | 
				
			||||||
  CustomMsg *customMsg = new CustomMsg(this->networkId, thing);
 | 
					  BinaryMsg* customMsg = new BinaryMsg(this->networkId, thing);
 | 
				
			||||||
  this->Publish(customMsg);
 | 
					  this->Publish(customMsg);
 | 
				
			||||||
  delete customMsg;
 | 
					  delete customMsg;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -161,26 +162,26 @@ bool Participant::Send(RemoteParticipant *remoteParticipant, IMessage *msg) {
 | 
				
			|||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					#if defined(_WIN32) || defined(_WIN64)
 | 
				
			||||||
  UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
 | 
					  Windows::Participant* thisWindows = static_cast<Windows::Participant*>(this);
 | 
				
			||||||
  return thisWindows->Send(remoteParticipant, bufferSize);
 | 
					  return thisWindows->Send(remoteParticipant, bufferSize);
 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					#elif defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
  UdpPosix *thisPosix = static_cast<UdpPosix *>(this);
 | 
					  Posix::Participant* thisPosix = static_cast<Posix::Particiapant*>(this);
 | 
				
			||||||
  return thisPosix->Send(remoteParticipant, bufferSize);
 | 
					  return thisPosix->Send(remoteParticipant, bufferSize);
 | 
				
			||||||
#elif defined(ARDUINO)
 | 
					#elif defined(ARDUINO)
 | 
				
			||||||
  UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
 | 
					  Arduino::Participant* thisArduino = static_cast<Arduino::Participant*>(this);
 | 
				
			||||||
  return thisArduino->Send(remoteParticipant, bufferSize);
 | 
					  return thisArduino->Send(remoteParticipant, bufferSize);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Participant::Publish(IMessage* msg) {
 | 
					bool Participant::Publish(IMessage* msg) {
 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					#if defined(_WIN32) || defined(_WIN64)
 | 
				
			||||||
  UdpWindows *thisWindows = static_cast<UdpWindows *>(this);
 | 
					  Windows::Participant* thisWindows = static_cast<Windows::Participant*>(this);
 | 
				
			||||||
  return thisWindows->Publish(msg);
 | 
					  return thisWindows->Publish(msg);
 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					#elif defined(__unix__) || defined(__APPLE__)
 | 
				
			||||||
  UdpPosix *thisPosix = static_cast<UdpPosix *>(this);
 | 
					  Posix::Participant* thisPosix = static_cast<Posix::Participant*>(this);
 | 
				
			||||||
  return thisPosix->Publish(msg);
 | 
					  return thisPosix->Publish(msg);
 | 
				
			||||||
#elif defined(ARDUINO)
 | 
					#elif defined(ARDUINO)
 | 
				
			||||||
  UdpArduino *thisArduino = static_cast<UdpArduino *>(this);
 | 
					  Arduino::Participant* thisArduino = static_cast<Arduino::Participant*>(this);
 | 
				
			||||||
  return thisArduino->Publish(msg);
 | 
					  return thisArduino->Publish(msg);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -190,13 +191,12 @@ bool Participant::Publish(IMessage *msg) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma region Receive
 | 
					#pragma region Receive
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Participant::ReceiveData(unsigned char bufferSize,
 | 
					void Participant::ReceiveData(unsigned char bufferSize, RemoteParticipant* remoteParticipant) {
 | 
				
			||||||
                              RemoteParticipant *remoteParticipant) {
 | 
					 | 
				
			||||||
  unsigned char msgId = this->buffer[0];
 | 
					  unsigned char msgId = this->buffer[0];
 | 
				
			||||||
  // std::cout << "receive msg " << (int)msgId << "\n";
 | 
					  // std::cout << "receive msg " << (int)msgId << "\n";
 | 
				
			||||||
  switch (msgId) {
 | 
					  switch (msgId) {
 | 
				
			||||||
  case ClientMsg::id: {
 | 
					    case ParticipantMsg::id: {
 | 
				
			||||||
    ClientMsg *msg = new ClientMsg(this->buffer);
 | 
					      ParticipantMsg* msg = new ParticipantMsg(this->buffer);
 | 
				
			||||||
      Process(remoteParticipant, msg);
 | 
					      Process(remoteParticipant, msg);
 | 
				
			||||||
      delete msg;
 | 
					      delete msg;
 | 
				
			||||||
    } break;
 | 
					    } break;
 | 
				
			||||||
@ -225,19 +225,18 @@ void Participant::ReceiveData(unsigned char bufferSize,
 | 
				
			|||||||
      Process(remoteParticipant, msg);
 | 
					      Process(remoteParticipant, msg);
 | 
				
			||||||
      delete msg;
 | 
					      delete msg;
 | 
				
			||||||
    } break;
 | 
					    } break;
 | 
				
			||||||
  case CustomMsg::id: {
 | 
					    case BinaryMsg::id: {
 | 
				
			||||||
    CustomMsg *msg = new CustomMsg(this->buffer);
 | 
					      BinaryMsg* msg = new BinaryMsg(this->buffer);
 | 
				
			||||||
      Process(remoteParticipant, msg);
 | 
					      Process(remoteParticipant, msg);
 | 
				
			||||||
      delete msg;
 | 
					      delete msg;
 | 
				
			||||||
    } break;
 | 
					    } break;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Participant::Process(RemoteParticipant *sender, ClientMsg *msg) {}
 | 
					void Participant::Process(RemoteParticipant* sender, ParticipantMsg* msg) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Participant::Process(RemoteParticipant* sender, NetworkIdMsg* msg) {
 | 
					void Participant::Process(RemoteParticipant* sender, NetworkIdMsg* msg) {
 | 
				
			||||||
  std::cout << this->name << ": process NetworkId [" << (int)this->networkId
 | 
					  std::cout << this->name << ": process NetworkId [" << (int)this->networkId << "/" << (int)msg->networkId << "]\n";
 | 
				
			||||||
            << "/" << (int)msg->networkId << "]\n";
 | 
					 | 
				
			||||||
  if (this->networkId != msg->networkId) {
 | 
					  if (this->networkId != msg->networkId) {
 | 
				
			||||||
    this->networkId = msg->networkId;
 | 
					    this->networkId = msg->networkId;
 | 
				
			||||||
    for (Thing* thing : this->things)
 | 
					    for (Thing* thing : this->things)
 | 
				
			||||||
@ -257,26 +256,24 @@ void Participant::Process(RemoteParticipant *sender, NameMsg *msg) {
 | 
				
			|||||||
    strcpy(thingName, msg->name);
 | 
					    strcpy(thingName, msg->name);
 | 
				
			||||||
    thingName[nameLength] = '\0';
 | 
					    thingName[nameLength] = '\0';
 | 
				
			||||||
    thing->name = thingName;
 | 
					    thing->name = thingName;
 | 
				
			||||||
    std::cout << "thing name = " << thing->name << " length = " << nameLength
 | 
					    std::cout << "thing name = " << thing->name << " length = " << nameLength << "\n";
 | 
				
			||||||
              << "\n";
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Participant::Process(RemoteParticipant* sender, PoseMsg* msg) {}
 | 
					void Participant::Process(RemoteParticipant* sender, PoseMsg* msg) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Participant::Process(RemoteParticipant *sender, CustomMsg *msg) {
 | 
					void Participant::Process(RemoteParticipant* sender, BinaryMsg* msg) {
 | 
				
			||||||
  // std::cout << this->name << ": process Binary [" << (int)this->networkId << "/"
 | 
					  // std::cout << this->name << ": process Binary [" << (int)this->networkId << "/"
 | 
				
			||||||
  //           << (int)msg->networkId << "]\n";
 | 
					  //           << (int)msg->networkId << "]\n";
 | 
				
			||||||
  Thing* thing = sender->Get(msg->networkId, msg->thingId);
 | 
					  Thing* thing = sender->Get(msg->networkId, msg->thingId);
 | 
				
			||||||
  if (thing != nullptr)
 | 
					  if (thing != nullptr)
 | 
				
			||||||
    thing->ProcessBytes(msg->bytes);
 | 
					    thing->ProcessBinary(msg->bytes);
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    std::cout << "custom msg for unknown thing " << (int)msg->networkId << ":"
 | 
					    std::cout << "custom msg for unknown thing " << (int)msg->networkId << ":" << (int)msg->thingId << "\n";
 | 
				
			||||||
              << (int)msg->thingId << "\n";
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Receive
 | 
					// Receive
 | 
				
			||||||
#pragma endregion
 | 
					#pragma endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
}  // namespace Passer
 | 
					}  // namespace Passer
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//#include "Messages/"
 | 
					//#include "Messages/"
 | 
				
			||||||
#include "Messages/ClientMsg.h"
 | 
					#include "Messages/ParticipantMsg.h"
 | 
				
			||||||
#include "Messages/CustomMsg.h"
 | 
					#include "Messages/BinaryMsg.h"
 | 
				
			||||||
#include "Messages/InvestigateMsg.h"
 | 
					#include "Messages/InvestigateMsg.h"
 | 
				
			||||||
#include "Messages/ModelUrlMsg.h"
 | 
					#include "Messages/ModelUrlMsg.h"
 | 
				
			||||||
#include "Messages/NameMsg.h"
 | 
					#include "Messages/NameMsg.h"
 | 
				
			||||||
@ -25,12 +25,12 @@
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// @brief A participant is device which can communicate with other participants
 | 
					/// @brief A participant is device which can communicate with other participants
 | 
				
			||||||
class Participant : public RemoteParticipant {
 | 
					class Participant : public RemoteParticipant {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  char buffer[1024];
 | 
					  unsigned char buffer[1024];
 | 
				
			||||||
  long publishInterval = 3000; // 3 seconds
 | 
					  long publishInterval = 3000; // 3 seconds
 | 
				
			||||||
  // unsigned char networkId = 0;
 | 
					  // unsigned char networkId = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -94,15 +94,15 @@ protected:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  void ReceiveUDP();
 | 
					  void ReceiveUDP();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void Process(RemoteParticipant *sender, ClientMsg *msg);
 | 
					  virtual void Process(RemoteParticipant *sender, ParticipantMsg *msg);
 | 
				
			||||||
  virtual void Process(RemoteParticipant *sender, NetworkIdMsg *msg);
 | 
					  virtual void Process(RemoteParticipant *sender, NetworkIdMsg *msg);
 | 
				
			||||||
  virtual void Process(RemoteParticipant* sender, InvestigateMsg *msg);
 | 
					  virtual void Process(RemoteParticipant* sender, InvestigateMsg *msg);
 | 
				
			||||||
  virtual void Process(RemoteParticipant* sender, ThingMsg *msg);
 | 
					  virtual void Process(RemoteParticipant* sender, ThingMsg *msg);
 | 
				
			||||||
  virtual void Process(RemoteParticipant* sender, NameMsg *msg);
 | 
					  virtual void Process(RemoteParticipant* sender, NameMsg *msg);
 | 
				
			||||||
  virtual void Process(RemoteParticipant* sender, PoseMsg *msg);
 | 
					  virtual void Process(RemoteParticipant* sender, PoseMsg *msg);
 | 
				
			||||||
  virtual void Process(RemoteParticipant* sender, CustomMsg *msg);
 | 
					  virtual void Process(RemoteParticipant* sender, BinaryMsg *msg);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					} // namespace Control
 | 
				
			||||||
} // namespace Passer
 | 
					} // namespace Passer
 | 
				
			||||||
using namespace Passer::Control;
 | 
					using namespace Passer::RoboidControl;
 | 
				
			||||||
							
								
								
									
										0
									
								
								Posix/Participant.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								Posix/Participant.cpp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										19
									
								
								Posix/Participant.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Posix/Participant.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../Participant.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					namespace Posix {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Participant : public RoboidControl::Participant {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  void Setup(int localPort, const char* remoteIpAddress, int remotePort);
 | 
				
			||||||
 | 
					  void Receive();
 | 
				
			||||||
 | 
					  bool Send(RemoteParticipant* remoteParticipant, int bufferSize);
 | 
				
			||||||
 | 
					  bool Publish(IMessage* msg);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace Posix
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
							
								
								
									
										15
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								README.md
									
									
									
									
									
								
							@ -1,3 +1,14 @@
 | 
				
			|||||||
\mainpage Control Core for C++
 | 
					\mainpage Roboid Control for C++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Control Core contains generic functionality for Controlling Things.
 | 
					Roboid Control support for C++ applications.
 | 
				
			||||||
 | 
					Supporting:
 | 
				
			||||||
 | 
					- Windows
 | 
				
			||||||
 | 
					- MacOS
 | 
				
			||||||
 | 
					- Linux
 | 
				
			||||||
 | 
					- Arduino (using PlatformIO)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Basic components
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Passer::RoboidControl::Thing
 | 
				
			||||||
 | 
					- Passer::RoboidControl::Participant
 | 
				
			||||||
 | 
					- Passer::RoboidControl::SiteServer
 | 
				
			||||||
							
								
								
									
										11
									
								
								Sensors/DigitalSensor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Sensors/DigitalSensor.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					#include "DigitalSensor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DigitalSensor::DigitalSensor() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DigitalSensor::DigitalSensor(unsigned char networkId, unsigned char thingId) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
							
								
								
									
										23
									
								
								Sensors/DigitalSensor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								Sensors/DigitalSensor.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Thing.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief A digital (on/off, 1/0, true/false) sensor
 | 
				
			||||||
 | 
					class DigitalSensor : public Thing {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  /// @brief The sigital state
 | 
				
			||||||
 | 
					  bool state = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief The default constructor
 | 
				
			||||||
 | 
					  DigitalSensor();
 | 
				
			||||||
 | 
					  /// @brief Create a temperature sensor with the given ID
 | 
				
			||||||
 | 
					  /// @param networkId The network ID of the sensor
 | 
				
			||||||
 | 
					  /// @param thingId The ID of the thing
 | 
				
			||||||
 | 
					  DigitalSensor(unsigned char networkId, unsigned char thingId);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
#include "Messages/LowLevelMessages.h"
 | 
					#include "Messages/LowLevelMessages.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TemperatureSensor::TemperatureSensor() : Thing(Type::TemperatureSensor) {}
 | 
					// TemperatureSensor::TemperatureSensor() : Thing(Type::TemperatureSensor) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -13,16 +13,16 @@ TemperatureSensor::TemperatureSensor(unsigned char networkId,
 | 
				
			|||||||
                                     unsigned char thingId)
 | 
					                                     unsigned char thingId)
 | 
				
			||||||
    : Thing(nullptr, networkId, thingId, Type::TemperatureSensor) {}
 | 
					    : Thing(nullptr, networkId, thingId, Type::TemperatureSensor) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TemperatureSensor::SetTemperature(float temp) { this->temp = temp; }
 | 
					void TemperatureSensor::SetTemperature(float temp) { this->temperature = temp; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TemperatureSensor::SendBytes(char *buffer, unsigned char *ix) {
 | 
					void TemperatureSensor::GenerateBinary(char *buffer, unsigned char *ix) {
 | 
				
			||||||
  std::cout << "Send temperature: " << this->temp << "\n";
 | 
					  std::cout << "Send temperature: " << this->temperature << "\n";
 | 
				
			||||||
  LowLevelMessages::SendFloat16(buffer, ix, this->temp);
 | 
					  LowLevelMessages::SendFloat16(buffer, ix, this->temperature);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TemperatureSensor::ProcessBytes(char *bytes) {
 | 
					void TemperatureSensor::ProcessBinary(char *bytes) {
 | 
				
			||||||
  unsigned char ix = 0;
 | 
					  unsigned char ix = 0;
 | 
				
			||||||
  this->temp = LowLevelMessages::ReceiveFloat16(bytes, &ix);
 | 
					  this->temperature = LowLevelMessages::ReceiveFloat16(bytes, &ix);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					} // namespace Control
 | 
				
			||||||
 | 
				
			|||||||
@ -3,21 +3,33 @@
 | 
				
			|||||||
#include "Thing.h"
 | 
					#include "Thing.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief A temperature sensor
 | 
				
			||||||
class TemperatureSensor : public Thing {
 | 
					class TemperatureSensor : public Thing {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
 | 
					  /// @brief The measured temperature
 | 
				
			||||||
 | 
					  float temperature = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief The default constructor
 | 
				
			||||||
  TemperatureSensor();
 | 
					  TemperatureSensor();
 | 
				
			||||||
 | 
					  /// @brief Create a temperature sensor with the given ID
 | 
				
			||||||
 | 
					  /// @param networkId The network ID of the sensor
 | 
				
			||||||
 | 
					  /// @param thingId The ID of the thing
 | 
				
			||||||
  TemperatureSensor(unsigned char networkId, unsigned char thingId);
 | 
					  TemperatureSensor(unsigned char networkId, unsigned char thingId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void SetTemperature(float temp);
 | 
					  /// @brief Manually override the measured temperature
 | 
				
			||||||
 | 
					  /// @param temperature The new temperature
 | 
				
			||||||
 | 
					  virtual void SetTemperature(float temperature);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void SendBytes(char *buffer, unsigned char *ix) override;
 | 
					  /// @brief Function to create a binary message with the temperature
 | 
				
			||||||
  virtual void ProcessBytes(char *bytes) override;
 | 
					  /// @param buffer The byte array for thw binary data
 | 
				
			||||||
 | 
					  /// @param ix The starting position for writing the binary data
 | 
				
			||||||
protected:
 | 
					  void GenerateBinary(char* bytes, unsigned char* ix) override;
 | 
				
			||||||
  float temp = 0;
 | 
					  /// @brief Function to extract the temperature received in the binary message
 | 
				
			||||||
 | 
					  /// @param bytes The binary data
 | 
				
			||||||
 | 
					  virtual void ProcessBinary(char* bytes) override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
}  // namespace Passer
 | 
					}  // namespace Passer
 | 
				
			||||||
@ -6,7 +6,7 @@
 | 
				
			|||||||
#include <memory>
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SiteServer::SiteServer(int port) {
 | 
					SiteServer::SiteServer(int port) {
 | 
				
			||||||
  this->name = "Site Server";
 | 
					  this->name = "Site Server";
 | 
				
			||||||
@ -22,7 +22,7 @@ SiteServer::SiteServer(int port) {
 | 
				
			|||||||
  Register<TemperatureSensor>((unsigned char)Thing::Type::TemperatureSensor);
 | 
					  Register<TemperatureSensor>((unsigned char)Thing::Type::TemperatureSensor);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SiteServer::Process(RemoteParticipant *sender, ClientMsg *msg) {
 | 
					void SiteServer::Process(RemoteParticipant *sender, ParticipantMsg *msg) {
 | 
				
			||||||
  if (msg->networkId == 0) {
 | 
					  if (msg->networkId == 0) {
 | 
				
			||||||
    std::cout << this->name << " received New Client -> " << sender->ipAddress
 | 
					    std::cout << this->name << " received New Client -> " << sender->ipAddress
 | 
				
			||||||
              << "  " << (int)sender->networkId << "\n";
 | 
					              << "  " << (int)sender->networkId << "\n";
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@
 | 
				
			|||||||
#include <unordered_map>
 | 
					#include <unordered_map>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// @brief A participant is device which can communicate with other participants
 | 
					/// @brief A participant is device which can communicate with other participants
 | 
				
			||||||
class SiteServer : public Participant {
 | 
					class SiteServer : public Participant {
 | 
				
			||||||
@ -26,7 +26,7 @@ public:
 | 
				
			|||||||
protected:
 | 
					protected:
 | 
				
			||||||
  unsigned long nextPublishMe = 0;
 | 
					  unsigned long nextPublishMe = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void Process(RemoteParticipant *sender, ClientMsg *msg) override;
 | 
					  virtual void Process(RemoteParticipant *sender, ParticipantMsg *msg) override;
 | 
				
			||||||
  virtual void Process(RemoteParticipant *sender, NetworkIdMsg *msg) override;
 | 
					  virtual void Process(RemoteParticipant *sender, NetworkIdMsg *msg) override;
 | 
				
			||||||
  virtual void Process(RemoteParticipant* sender, ThingMsg *msg) override;
 | 
					  virtual void Process(RemoteParticipant* sender, ThingMsg *msg) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -37,4 +37,4 @@ protected:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					} // namespace Control
 | 
				
			||||||
} // namespace Passer
 | 
					} // namespace Passer
 | 
				
			||||||
using namespace Passer::Control;
 | 
					using namespace Passer::RoboidControl;
 | 
				
			||||||
							
								
								
									
										24
									
								
								Thing.cpp
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								Thing.cpp
									
									
									
									
									
								
							@ -6,6 +6,9 @@
 | 
				
			|||||||
#include <list>
 | 
					#include <list>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					  namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Thing::Thing(Type thingType) : Thing((unsigned char)thingType) {}
 | 
					Thing::Thing(Type thingType) : Thing((unsigned char)thingType) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Thing::Thing(unsigned char thingType) {
 | 
					Thing::Thing(unsigned char thingType) {
 | 
				
			||||||
@ -20,7 +23,7 @@ Thing::Thing(unsigned char thingType) {
 | 
				
			|||||||
  this->angularVelocity = Spherical16::zero;
 | 
					  this->angularVelocity = Spherical16::zero;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Passer::Control::Thing::Thing(RemoteParticipant *participant, unsigned char networkId,
 | 
					Thing::Thing(RemoteParticipant *participant, unsigned char networkId,
 | 
				
			||||||
                              unsigned char thingId, Type thingType) {
 | 
					                              unsigned char thingId, Type thingType) {
 | 
				
			||||||
  // no participant reference yet..
 | 
					  // no participant reference yet..
 | 
				
			||||||
  this->participant = participant;
 | 
					  this->participant = participant;
 | 
				
			||||||
@ -121,7 +124,7 @@ Thing *Thing::RemoveChild(Thing *child) {
 | 
				
			|||||||
  return child;
 | 
					  return child;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Thing *Passer::Control::Thing::GetChild(unsigned char id, bool recursive) {
 | 
					Thing *Thing::GetChild(unsigned char id, bool recursive) {
 | 
				
			||||||
  for (unsigned char childIx = 0; childIx < this->childCount; childIx++) {
 | 
					  for (unsigned char childIx = 0; childIx < this->childCount; childIx++) {
 | 
				
			||||||
    Thing *child = this->children[childIx];
 | 
					    Thing *child = this->children[childIx];
 | 
				
			||||||
    if (child == nullptr)
 | 
					    if (child == nullptr)
 | 
				
			||||||
@ -138,12 +141,22 @@ Thing *Passer::Control::Thing::GetChild(unsigned char id, bool recursive) {
 | 
				
			|||||||
  return nullptr;
 | 
					  return nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Thing *Passer::Control::Thing::GetChildByIndex(unsigned char ix) {
 | 
					Thing *Thing::GetChildByIndex(unsigned char ix) { return this->children[ix]; }
 | 
				
			||||||
  return this->children[ix];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Thing::SetModel(const char *url) { this->modelUrl = url; }
 | 
					void Thing::SetModel(const char *url) { this->modelUrl = url; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(ARDUINO)
 | 
				
			||||||
 | 
					void Thing::Update() {
 | 
				
			||||||
 | 
					  Update(millis());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Thing::GenerateBinary(char *buffer, unsigned char *ix) {
 | 
				
			||||||
 | 
					  (void)buffer;
 | 
				
			||||||
 | 
					  (void)ix;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void Thing::ProcessBinary(char *bytes) { (void)bytes; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Thing::SetPosition(Spherical16 position) {
 | 
					void Thing::SetPosition(Spherical16 position) {
 | 
				
			||||||
  this->position = position;
 | 
					  this->position = position;
 | 
				
			||||||
  this->positionUpdated = true;
 | 
					  this->positionUpdated = true;
 | 
				
			||||||
@ -207,3 +220,4 @@ Spherical16 Thing::GetAngularVelocity() { return this->angularVelocity; }
 | 
				
			|||||||
//     }
 | 
					//     }
 | 
				
			||||||
//   }
 | 
					//   }
 | 
				
			||||||
//}
 | 
					//}
 | 
				
			||||||
 | 
					  }}
 | 
				
			||||||
							
								
								
									
										76
									
								
								Thing.h
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								Thing.h
									
									
									
									
									
								
							@ -5,7 +5,7 @@
 | 
				
			|||||||
#include <list>
 | 
					#include <list>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Passer {
 | 
					namespace Passer {
 | 
				
			||||||
namespace Control {
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RemoteParticipant;
 | 
					class RemoteParticipant;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -13,15 +13,15 @@ class RemoteParticipant;
 | 
				
			|||||||
// IMPORTANT: values higher than 256 will need to change the Thing::id type
 | 
					// IMPORTANT: values higher than 256 will need to change the Thing::id type
 | 
				
			||||||
// to 16-bit or higher, breaking the networking protocol!
 | 
					// to 16-bit or higher, breaking the networking protocol!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// @brief A thing is the basic building block
 | 
					/// @brief A thing is the primitive building block
 | 
				
			||||||
class Thing {
 | 
					class Thing {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  RemoteParticipant *participant;
 | 
					  RemoteParticipant *participant;
 | 
				
			||||||
  unsigned char networkId = 0;
 | 
					  unsigned char networkId = 0;
 | 
				
			||||||
  /// @char The id of the thing
 | 
					  /// @brief The ID of the thing
 | 
				
			||||||
  unsigned char id = 0;
 | 
					  unsigned char id = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// @brief Basic Thing types
 | 
					  /// @brief Predefined thing types
 | 
				
			||||||
  enum class Type {
 | 
					  enum class Type {
 | 
				
			||||||
    Undetermined,
 | 
					    Undetermined,
 | 
				
			||||||
    // Sensor,
 | 
					    // Sensor,
 | 
				
			||||||
@ -38,14 +38,27 @@ public:
 | 
				
			|||||||
    Humanoid,
 | 
					    Humanoid,
 | 
				
			||||||
    ExternalSensor,
 | 
					    ExternalSensor,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					  /// @brief The type of Thing
 | 
				
			||||||
 | 
					  unsigned char type = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief Create a new thing of the given type
 | 
				
			||||||
 | 
					  /// @param thingType The predefined type of thing
 | 
				
			||||||
  Thing(Type thingType = Type::Undetermined);
 | 
					  Thing(Type thingType = Type::Undetermined);
 | 
				
			||||||
 | 
					  /// @brief Create a new thing of the give type
 | 
				
			||||||
 | 
					  /// @param thingType The custom type of the thing
 | 
				
			||||||
  Thing(unsigned char thingType);
 | 
					  Thing(unsigned char thingType);
 | 
				
			||||||
 | 
					  /// @brief Create a new thing for the given participant
 | 
				
			||||||
 | 
					  /// @param participant The participant for which this thing is created
 | 
				
			||||||
 | 
					  /// @param networkId The network ID of the thing
 | 
				
			||||||
 | 
					  /// @param thingId The ID of the thing
 | 
				
			||||||
 | 
					  /// @param thingType The type of thing
 | 
				
			||||||
  Thing(RemoteParticipant *participant, unsigned char networkId,
 | 
					  Thing(RemoteParticipant *participant, unsigned char networkId,
 | 
				
			||||||
        unsigned char thingId, Type thingType = Type::Undetermined);
 | 
					        unsigned char thingId, Type thingType = Type::Undetermined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief Find a thing by name
 | 
				
			||||||
 | 
					  /// @param name Rhe name of the thing
 | 
				
			||||||
 | 
					  /// @return The found thing or nullptr when nothing is found
 | 
				
			||||||
  Thing *FindThing(const char *name);
 | 
					  Thing *FindThing(const char *name);
 | 
				
			||||||
  //  Thing *FindChild(unsigned char id);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// @brief Sets the parent Thing
 | 
					  /// @brief Sets the parent Thing
 | 
				
			||||||
  /// @param parent The Thing which should become the parnet
 | 
					  /// @param parent The Thing which should become the parnet
 | 
				
			||||||
@ -60,10 +73,21 @@ public:
 | 
				
			|||||||
  /// @param child The Thing which should become a child
 | 
					  /// @param child The Thing which should become a child
 | 
				
			||||||
  /// @remark When the Thing is already a child, it will not be added again
 | 
					  /// @remark When the Thing is already a child, it will not be added again
 | 
				
			||||||
  virtual void AddChild(Thing *child);
 | 
					  virtual void AddChild(Thing *child);
 | 
				
			||||||
 | 
					  /// @brief Remove the given thing as a child of this thing
 | 
				
			||||||
 | 
					  /// @param child The child to remove
 | 
				
			||||||
 | 
					  /// @return The removed child or nullptr if the child could not be found
 | 
				
			||||||
  Thing *RemoveChild(Thing *child);
 | 
					  Thing *RemoveChild(Thing *child);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief The number of children
 | 
				
			||||||
  unsigned char childCount = 0;
 | 
					  unsigned char childCount = 0;
 | 
				
			||||||
 | 
					  /// @brief Get a child by thing Id
 | 
				
			||||||
 | 
					  /// @param id The thing ID to find
 | 
				
			||||||
 | 
					  /// @param recursive Look recursively through all descendants
 | 
				
			||||||
 | 
					  /// @return The found thing of nullptr when nothing is found
 | 
				
			||||||
  Thing *GetChild(unsigned char id, bool recursive = false);
 | 
					  Thing *GetChild(unsigned char id, bool recursive = false);
 | 
				
			||||||
 | 
					  /// @brief Get a child by index
 | 
				
			||||||
 | 
					  /// @param ix The child index
 | 
				
			||||||
 | 
					  /// @return The found thing of nullptr when nothing is found
 | 
				
			||||||
  Thing *GetChildByIndex(unsigned char ix);
 | 
					  Thing *GetChildByIndex(unsigned char ix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
@ -71,20 +95,31 @@ protected:
 | 
				
			|||||||
  Thing **children = nullptr;
 | 
					  Thing **children = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  /// @brief The type of Thing
 | 
					  /// @brief The name of the thing
 | 
				
			||||||
  unsigned char type = 0;
 | 
					 | 
				
			||||||
  const char *name = nullptr;
 | 
					  const char *name = nullptr;
 | 
				
			||||||
 | 
					  /// @brief An URL pointing to the location where a model of the thing can be found
 | 
				
			||||||
  const char *modelUrl = nullptr;
 | 
					  const char *modelUrl = nullptr;
 | 
				
			||||||
 | 
					  /// @brief The scale of the model (deprecated I think)
 | 
				
			||||||
  float modelScale = 1;
 | 
					  float modelScale = 1;
 | 
				
			||||||
  // protected Sensor sensor;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief Set the position of the thing
 | 
				
			||||||
 | 
					  /// @param position The new position in local space, in meters
 | 
				
			||||||
  void SetPosition(Spherical16 position);
 | 
					  void SetPosition(Spherical16 position);
 | 
				
			||||||
 | 
					  /// @brief Get the position of the thing
 | 
				
			||||||
 | 
					  /// @return The position in local space, in meters
 | 
				
			||||||
  Spherical16 GetPosition();
 | 
					  Spherical16 GetPosition();
 | 
				
			||||||
 | 
					  /// @brief Set the orientation of the thing
 | 
				
			||||||
 | 
					  /// @param orientation The new orientation in local space
 | 
				
			||||||
  void SetOrientation(SwingTwist16 orientation);
 | 
					  void SetOrientation(SwingTwist16 orientation);
 | 
				
			||||||
 | 
					  /// @brief Get the orientation of the thing
 | 
				
			||||||
 | 
					  /// @return The orienation in local space
 | 
				
			||||||
  SwingTwist16 GetOrientation();
 | 
					  SwingTwist16 GetOrientation();
 | 
				
			||||||
 | 
					  /// @brief The scale of the thing (deprecated I think)
 | 
				
			||||||
  float scale = 1; // assuming uniform scale
 | 
					  float scale = 1; // assuming uniform scale
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief boolean indicating if the position was updated
 | 
				
			||||||
  bool positionUpdated = false;
 | 
					  bool positionUpdated = false;
 | 
				
			||||||
 | 
					  /// @brief boolean indicating if the orientation was updated
 | 
				
			||||||
  bool orientationUpdated = false;
 | 
					  bool orientationUpdated = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
@ -100,11 +135,16 @@ protected:
 | 
				
			|||||||
public:
 | 
					public:
 | 
				
			||||||
  Spherical16 linearVelocity;
 | 
					  Spherical16 linearVelocity;
 | 
				
			||||||
  Spherical16 angularVelocity;
 | 
					  Spherical16 angularVelocity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// @brief Get the linear velocity of the thing
 | 
				
			||||||
 | 
					  /// @return The linear velocity in local space, in meters per second
 | 
				
			||||||
  virtual Spherical16 GetLinearVelocity();
 | 
					  virtual Spherical16 GetLinearVelocity();
 | 
				
			||||||
 | 
					  /// @brief Get the angular velocity of the thing
 | 
				
			||||||
 | 
					  /// @return The angular velocity in local space
 | 
				
			||||||
  virtual Spherical16 GetAngularVelocity();
 | 
					  virtual Spherical16 GetAngularVelocity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  /// @brief Terminated thins are no longer updated
 | 
					  /// @brief Terminated things are no longer updated
 | 
				
			||||||
  void Terminate();
 | 
					  void Terminate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// @brief Sets the location from where the 3D model of this Thing can be
 | 
					  /// @brief Sets the location from where the 3D model of this Thing can be
 | 
				
			||||||
@ -114,18 +154,24 @@ public:
 | 
				
			|||||||
  /// the only official supported model format is .obj
 | 
					  /// the only official supported model format is .obj
 | 
				
			||||||
  void SetModel(const char *url);
 | 
					  void SetModel(const char *url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #if defined(ARDUINO)
 | 
				
			||||||
 | 
					  void Update();
 | 
				
			||||||
 | 
					  #endif
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  /// @brief Updates the state of the thing
 | 
					  /// @brief Updates the state of the thing
 | 
				
			||||||
  /// @param currentTimeMs The current clock time in milliseconds
 | 
					  /// @param currentTimeMs The current clock time in milliseconds
 | 
				
			||||||
  virtual void Update(unsigned long currentTimeMs) { (void)currentTimeMs; };
 | 
					  virtual void Update(unsigned long currentTimeMs) { (void)currentTimeMs; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void SendBytes(char *buffer, unsigned char *ix) {
 | 
					  /// @brief Function used to generate binary data for this thing
 | 
				
			||||||
    (void)buffer;
 | 
					  /// @param buffer The byte array for thw binary data
 | 
				
			||||||
    (void)ix;
 | 
					  /// @param ix The starting position for writing the binary data
 | 
				
			||||||
  };
 | 
					  virtual void GenerateBinary(char *buffer, unsigned char *ix);
 | 
				
			||||||
  virtual void ProcessBytes(char *bytes) { (void)bytes; };
 | 
					  // /// @brief FUnction used to process binary data received for this thing
 | 
				
			||||||
 | 
					  /// @param bytes The binary data
 | 
				
			||||||
 | 
					  virtual void ProcessBinary(char *bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Control
 | 
					} // namespace Control
 | 
				
			||||||
} // namespace Passer
 | 
					} // namespace Passer
 | 
				
			||||||
using namespace Passer::Control;
 | 
					using namespace Passer::RoboidControl;
 | 
				
			||||||
@ -1,95 +0,0 @@
 | 
				
			|||||||
#include "UdpArduino.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(ARDUINO)
 | 
					 | 
				
			||||||
#include <ESP8266WiFi.h>
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
namespace Passer {
 | 
					 | 
				
			||||||
namespace Control {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void UdpArduino::Setup(int localPort, const char *remoteIpAddress,
 | 
					 | 
				
			||||||
                       int remotePort) {
 | 
					 | 
				
			||||||
#if ARDUINO
 | 
					 | 
				
			||||||
  this->remoteIpAddress = remoteIpAddress;
 | 
					 | 
				
			||||||
  this->remotePort = remotePort;
 | 
					 | 
				
			||||||
  GetBroadcastAddress();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (WiFi.isConnected() == false) {
 | 
					 | 
				
			||||||
    std::cout << "No network available!\n";
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  udp.begin(this->localPort);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  std::cout << "Wifi sync started to port " << this->remotePort << "\n";
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void UdpArduino::GetBroadcastAddress() {
 | 
					 | 
				
			||||||
#if ARDUINO
 | 
					 | 
				
			||||||
  IPAddress broadcastAddress = WiFi.localIP();
 | 
					 | 
				
			||||||
  broadcastAddress[3] = 255;
 | 
					 | 
				
			||||||
  String broadcastIpString = broadcastAddress.toString();
 | 
					 | 
				
			||||||
  this->broadcastIpAddress = new char[broadcastIpString.length() + 1];
 | 
					 | 
				
			||||||
  broadcastIpString.toCharArray(this->broadcastIpAddress,
 | 
					 | 
				
			||||||
                                broadcastIpString.length() + 1);
 | 
					 | 
				
			||||||
  std::cout << "Broadcast address: " << broadcastIpAddress << "\n";
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void UdpArduino::Receive() {
 | 
					 | 
				
			||||||
#if ARDUINO
 | 
					 | 
				
			||||||
  int packetSize = udp.parsePacket();
 | 
					 | 
				
			||||||
  while (packetSize > 0) {
 | 
					 | 
				
			||||||
    udp.read(buffer, packetSize);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    String senderAddress = udp.remoteIP().toString();
 | 
					 | 
				
			||||||
    char sender_ipAddress[16];
 | 
					 | 
				
			||||||
    senderAddress.toCharArray(sender_ipAddress, 16);
 | 
					 | 
				
			||||||
    int sender_port = udp.remotePort();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Participant *remoteParticipant =
 | 
					 | 
				
			||||||
        this->GetParticipant(sender_ipAddress, sender_port);
 | 
					 | 
				
			||||||
    if (remoteParticipant == nullptr) {
 | 
					 | 
				
			||||||
      remoteParticipant = this->AddParticipant(sender_ipAddress, sender_port);
 | 
					 | 
				
			||||||
      // std::cout << "New sender " << sender_ipAddress << ":" << sender_port
 | 
					 | 
				
			||||||
      //           << "\n";
 | 
					 | 
				
			||||||
      // std::cout << "New remote participant " << remoteParticipant->ipAddress
 | 
					 | 
				
			||||||
      //           << ":" << remoteParticipant->port << " "
 | 
					 | 
				
			||||||
      //           << (int)remoteParticipant->networkId << "\n";
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ReceiveData(packetSize, remoteParticipant);
 | 
					 | 
				
			||||||
    packetSize = udp.parsePacket();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool UdpArduino::Send(RemoteParticipant* remoteParticipant, int bufferSize) {
 | 
					 | 
				
			||||||
#if ARDUINO
 | 
					 | 
				
			||||||
  udp.beginPacket(remoteParticipant->ipAddress, remoteParticipant->port);
 | 
					 | 
				
			||||||
  udp.write(buffer, bufferSize);
 | 
					 | 
				
			||||||
  udp.endPacket();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //   std::cout << "Sent to " << this->remoteIpAddress << ":"
 | 
					 | 
				
			||||||
  //             << this->remotePort << "\n";
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool UdpArduino::Publish(IMessage *msg) {
 | 
					 | 
				
			||||||
#ifdef ARDUINO
 | 
					 | 
				
			||||||
  int bufferSize = msg->Serialize(this->buffer);
 | 
					 | 
				
			||||||
  if (bufferSize <= 0)
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  udp.beginPacket(this->broadcastIpAddress, this->remotePort);
 | 
					 | 
				
			||||||
  udp.write(buffer, bufferSize);
 | 
					 | 
				
			||||||
  udp.endPacket();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //   std::cout << "Publish to " << this->broadcastIpAddress << ":"
 | 
					 | 
				
			||||||
  //             << this->remotePort << "\n";
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  return true;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace Control
 | 
					 | 
				
			||||||
} // namespace Passer
 | 
					 | 
				
			||||||
							
								
								
									
										20
									
								
								UdpArduino.h
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								UdpArduino.h
									
									
									
									
									
								
							@ -1,20 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "Participant.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Passer {
 | 
					 | 
				
			||||||
namespace Control {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class UdpArduino : public Participant {
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
  void Setup(int localPort, const char *remoteIpAddress, int remotePort);
 | 
					 | 
				
			||||||
  void Receive();
 | 
					 | 
				
			||||||
  bool Send(RemoteParticipant* remoteParticipant, int bufferSize);
 | 
					 | 
				
			||||||
  bool Publish(IMessage *msg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
protected:
 | 
					 | 
				
			||||||
  void GetBroadcastAddress();
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace Control
 | 
					 | 
				
			||||||
} // namespace Passer
 | 
					 | 
				
			||||||
							
								
								
									
										145
									
								
								UdpPosix.cpp
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								UdpPosix.cpp
									
									
									
									
									
								
							@ -1,145 +0,0 @@
 | 
				
			|||||||
#include "UdpPosix.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
#include <fcntl.h> // For fcntl
 | 
					 | 
				
			||||||
#include <netinet/in.h>
 | 
					 | 
				
			||||||
#include <sys/socket.h>
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Passer {
 | 
					 | 
				
			||||||
namespace Control {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void UdpPosix::Setup(int localPort, const char *remoteIpAddress,
 | 
					 | 
				
			||||||
                     int remotePort) {
 | 
					 | 
				
			||||||
#if defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Create a UDP socket
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  this->sock = socket(AF_INET, SOCK_DGRAM, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (this->sock < 0) {
 | 
					 | 
				
			||||||
    std::cerr << "Error creating socket" << std::endl;
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set the socket to non-blocking mode
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
  u_long mode = 1; // 1 to enable non-blocking socket
 | 
					 | 
				
			||||||
  ioctlsocket(this->sock, FIONBIO, &mode);
 | 
					 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
  int flags = fcntl(this->sock, F_GETFL, 0);
 | 
					 | 
				
			||||||
  fcntl(this->sock, F_SETFL, flags | O_NONBLOCK);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (remotePort != 0) {
 | 
					 | 
				
			||||||
    // Set up the address to send to
 | 
					 | 
				
			||||||
    memset(&remote_addr, 0, sizeof(remote_addr));
 | 
					 | 
				
			||||||
    remote_addr.sin_family = AF_INET;
 | 
					 | 
				
			||||||
    remote_addr.sin_port = htons(remotePort);
 | 
					 | 
				
			||||||
    if (inet_pton(AF_INET, remoteIpAddress, &remote_addr.sin_addr) <= 0) {
 | 
					 | 
				
			||||||
      std::cerr << "Invalid address" << std::endl;
 | 
					 | 
				
			||||||
      close(sock);
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Set up the receiving address
 | 
					 | 
				
			||||||
  memset(&server_addr, 0, sizeof(server_addr));
 | 
					 | 
				
			||||||
  server_addr.sin_family = AF_INET;
 | 
					 | 
				
			||||||
  server_addr.sin_port = htons(localPort);
 | 
					 | 
				
			||||||
  if (inet_pton(AF_INET, "0.0.0.0", &server_addr.sin_addr) <= 0) {
 | 
					 | 
				
			||||||
    std::cerr << "Invalid address" << std::endl;
 | 
					 | 
				
			||||||
    close(sock);
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Bind the socket to the specified port
 | 
					 | 
				
			||||||
  if (bind(this->sock, (const struct sockaddr *)&server_addr,
 | 
					 | 
				
			||||||
           sizeof(server_addr)) < 0) {
 | 
					 | 
				
			||||||
    std::cerr << "Bind failed" << std::endl;
 | 
					 | 
				
			||||||
    close(sock);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void UdpPosix::Receive() {
 | 
					 | 
				
			||||||
#if defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
  sockaddr_in client_addr;
 | 
					 | 
				
			||||||
  socklen_t len = sizeof(client_addr);
 | 
					 | 
				
			||||||
  int packetSize = recvfrom(this->sock, buffer, sizeof(buffer), 0,
 | 
					 | 
				
			||||||
                            (struct sockaddr *)&client_addr, &len);
 | 
					 | 
				
			||||||
  if (packetSize > 0) {
 | 
					 | 
				
			||||||
    char sender_ipAddress[INET_ADDRSTRLEN];
 | 
					 | 
				
			||||||
    inet_ntop(AF_INET, &(client_addr.sin_addr), sender_ipAddress,
 | 
					 | 
				
			||||||
              INET_ADDRSTRLEN);
 | 
					 | 
				
			||||||
    int sender_port = ntohs(client_addr.sin_port);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Participant *remoteParticipant =
 | 
					 | 
				
			||||||
        this->GetParticipant(sender_ipAddress, sender_port);
 | 
					 | 
				
			||||||
    if (remoteParticipant == nullptr) {
 | 
					 | 
				
			||||||
      remoteParticipant = this->AddParticipant(sender_ipAddress, sender_port);
 | 
					 | 
				
			||||||
      // std::cout << "New sender " << sender_ipAddress << ":" << sender_port
 | 
					 | 
				
			||||||
      //           << "\n";
 | 
					 | 
				
			||||||
      // std::cout << "New remote participant " << remoteParticipant->ipAddress
 | 
					 | 
				
			||||||
      //           << ":" << remoteParticipant->port << " "
 | 
					 | 
				
			||||||
      //           << (int)remoteParticipant->networkId << "\n";
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ReceiveData(packetSize, remoteParticipant);
 | 
					 | 
				
			||||||
    // std::cout << "Received data\n";
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool UdpPosix::Send(RemoteParticipant *remoteParticipant, int bufferSize) {
 | 
					 | 
				
			||||||
#if defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
  // Set up the destination address
 | 
					 | 
				
			||||||
  // char ip_str[INET_ADDRSTRLEN];
 | 
					 | 
				
			||||||
  // inet_ntop(AF_INET, &(remote_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
 | 
					 | 
				
			||||||
  // std::cout << "Send to " << ip_str << ":" << ntohs(remote_addr.sin_port)
 | 
					 | 
				
			||||||
  //           << "\n";
 | 
					 | 
				
			||||||
  struct sockaddr_in dest_addr;
 | 
					 | 
				
			||||||
  memset(&dest_addr, 0, sizeof(dest_addr));
 | 
					 | 
				
			||||||
  dest_addr.sin_family = AF_INET;
 | 
					 | 
				
			||||||
  dest_addr.sin_port = htons(remoteParticipant->port);
 | 
					 | 
				
			||||||
  dest_addr.sin_addr.s_addr = inet_addr(remoteParticipant->ipAddress);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Send the message
 | 
					 | 
				
			||||||
  int sent_bytes = sendto(sock, this->buffer, bufferSize, 0,
 | 
					 | 
				
			||||||
                          (struct sockaddr *)&remote_addr, sizeof(remote_addr));
 | 
					 | 
				
			||||||
  if (sent_bytes < 0) {
 | 
					 | 
				
			||||||
    std::cerr << "sendto failed with error: " << sent_bytes << std::endl;
 | 
					 | 
				
			||||||
    close(sock);
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool UdpPosix::Publish(IMessage *msg) {
 | 
					 | 
				
			||||||
#if defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
  int bufferSize = msg->Serialize(this->buffer);
 | 
					 | 
				
			||||||
  if (bufferSize <= 0)
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  char ip_str[INET_ADDRSTRLEN];
 | 
					 | 
				
			||||||
  inet_ntop(AF_INET, &(broadcast_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
 | 
					 | 
				
			||||||
  std::cout << "Publish to " << ip_str << ":" << ntohs(broadcast_addr.sin_port)
 | 
					 | 
				
			||||||
            << "\n";
 | 
					 | 
				
			||||||
  int sent_bytes =
 | 
					 | 
				
			||||||
      sendto(sock, this->buffer, bufferSize, 0,
 | 
					 | 
				
			||||||
             (struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr));
 | 
					 | 
				
			||||||
  if (sent_bytes < 0) {
 | 
					 | 
				
			||||||
    std::cerr << "sendto failed with error: " << sent_bytes << std::endl;
 | 
					 | 
				
			||||||
    close(sock);
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace Control
 | 
					 | 
				
			||||||
} // namespace Passer
 | 
					 | 
				
			||||||
							
								
								
									
										17
									
								
								UdpPosix.h
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								UdpPosix.h
									
									
									
									
									
								
							@ -1,17 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "Participant.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Passer {
 | 
					 | 
				
			||||||
namespace Control {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class UdpPosix : public Participant {
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
  void Setup(int localPort, const char *remoteIpAddress, int remotePort);
 | 
					 | 
				
			||||||
  void Receive();
 | 
					 | 
				
			||||||
  bool Send(RemoteParticipant* remoteParticipant, int bufferSize);
 | 
					 | 
				
			||||||
  bool Publish(IMessage *msg);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace Control
 | 
					 | 
				
			||||||
} // namespace Passer
 | 
					 | 
				
			||||||
							
								
								
									
										207
									
								
								UdpWindows.cpp
									
									
									
									
									
								
							
							
						
						
									
										207
									
								
								UdpWindows.cpp
									
									
									
									
									
								
							@ -1,207 +0,0 @@
 | 
				
			|||||||
#include "UdpWindows.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
#include <winsock2.h>
 | 
					 | 
				
			||||||
#include <ws2tcpip.h>
 | 
					 | 
				
			||||||
#pragma comment(lib, "ws2_32.lib")
 | 
					 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
#include <arpa/inet.h>
 | 
					 | 
				
			||||||
#include <fcntl.h> // For fcntl
 | 
					 | 
				
			||||||
#include <netinet/in.h>
 | 
					 | 
				
			||||||
#include <sys/socket.h>
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Passer {
 | 
					 | 
				
			||||||
namespace Control {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void UdpWindows::Setup(int localPort, const char *remoteIpAddress,
 | 
					 | 
				
			||||||
                       int remotePort) {
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Create a UDP socket
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
  // Windows-specific Winsock initialization
 | 
					 | 
				
			||||||
  WSADATA wsaData;
 | 
					 | 
				
			||||||
  if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
 | 
					 | 
				
			||||||
    std::cerr << "WSAStartup failed" << std::endl;
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
  this->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 | 
					 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
  this->sock = socket(AF_INET, SOCK_DGRAM, 0);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (this->sock < 0) {
 | 
					 | 
				
			||||||
    std::cerr << "Error creating socket" << std::endl;
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set the socket to non-blocking mode
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
  u_long mode = 1; // 1 to enable non-blocking socket
 | 
					 | 
				
			||||||
  ioctlsocket(this->sock, FIONBIO, &mode);
 | 
					 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
  int flags = fcntl(this->sock, F_GETFL, 0);
 | 
					 | 
				
			||||||
  fcntl(this->sock, F_SETFL, flags | O_NONBLOCK);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (remotePort != 0) {
 | 
					 | 
				
			||||||
    // Set up the address to send to
 | 
					 | 
				
			||||||
    memset(&remote_addr, 0, sizeof(remote_addr));
 | 
					 | 
				
			||||||
    remote_addr.sin_family = AF_INET;
 | 
					 | 
				
			||||||
    remote_addr.sin_port = htons((u_short)remotePort);
 | 
					 | 
				
			||||||
    if (inet_pton(AF_INET, remoteIpAddress, &remote_addr.sin_addr) <= 0) {
 | 
					 | 
				
			||||||
      std::cerr << "Invalid address" << std::endl;
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
      closesocket(sock);
 | 
					 | 
				
			||||||
      WSACleanup();
 | 
					 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
      close(sock);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Set up the receiving address
 | 
					 | 
				
			||||||
  memset(&server_addr, 0, sizeof(server_addr));
 | 
					 | 
				
			||||||
  server_addr.sin_family = AF_INET;
 | 
					 | 
				
			||||||
  server_addr.sin_port = htons((u_short)localPort);
 | 
					 | 
				
			||||||
  if (inet_pton(AF_INET, "0.0.0.0", &server_addr.sin_addr) <= 0) {
 | 
					 | 
				
			||||||
    std::cerr << "Invalid address" << std::endl;
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
    closesocket(sock);
 | 
					 | 
				
			||||||
    WSACleanup();
 | 
					 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
    close(sock);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Bind the socket to the specified port
 | 
					 | 
				
			||||||
  if (bind(this->sock, (const struct sockaddr *)&server_addr,
 | 
					 | 
				
			||||||
           sizeof(server_addr)) < 0) {
 | 
					 | 
				
			||||||
    std::cerr << "Bind failed" << std::endl;
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
    closesocket(sock);
 | 
					 | 
				
			||||||
    WSACleanup();
 | 
					 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
    close(sock);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void UdpWindows::Receive() {
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
  // char ip_str[INET_ADDRSTRLEN];
 | 
					 | 
				
			||||||
  // inet_ntop(AF_INET, &(server_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
 | 
					 | 
				
			||||||
  // std::cout << this->name << " Receive on " << ip_str << ":"
 | 
					 | 
				
			||||||
  //           << ntohs(server_addr.sin_port) << "\n";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  sockaddr_in client_addr;
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
  int len = sizeof(client_addr);
 | 
					 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
  socklen_t len = sizeof(client_addr);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  int packetSize = recvfrom(this->sock, buffer, sizeof(buffer), 0,
 | 
					 | 
				
			||||||
                            (struct sockaddr *)&client_addr, &len);
 | 
					 | 
				
			||||||
  // std::cout << "received data " << packetSize << "\n";
 | 
					 | 
				
			||||||
  if (packetSize < 0) {
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
    int error_code = WSAGetLastError(); // Get the error code on Windows
 | 
					 | 
				
			||||||
    if (error_code != WSAEWOULDBLOCK)
 | 
					 | 
				
			||||||
      std::cerr << "recvfrom failed with error: " << error_code << std::endl;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    // std::cerr << "recvfrom failed with error: " << packetSize << std::endl;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  } else if (packetSize > 0) {
 | 
					 | 
				
			||||||
    char sender_ipAddress[INET_ADDRSTRLEN];
 | 
					 | 
				
			||||||
    inet_ntop(AF_INET, &(client_addr.sin_addr), sender_ipAddress,
 | 
					 | 
				
			||||||
              INET_ADDRSTRLEN);
 | 
					 | 
				
			||||||
    int sender_port = ntohs(client_addr.sin_port);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Participant *remoteParticipant =
 | 
					 | 
				
			||||||
        this->GetParticipant(sender_ipAddress, sender_port);
 | 
					 | 
				
			||||||
    if (remoteParticipant == nullptr) {
 | 
					 | 
				
			||||||
      remoteParticipant = this->AddParticipant(sender_ipAddress, sender_port);
 | 
					 | 
				
			||||||
      // std::cout << "New sender " << sender_ipAddress << ":"
 | 
					 | 
				
			||||||
      //           << sender_port << "\n";
 | 
					 | 
				
			||||||
      // std::cout << "New remote participant " <<
 | 
					 | 
				
			||||||
      // remoteParticipant->ipAddress
 | 
					 | 
				
			||||||
      // << ":"
 | 
					 | 
				
			||||||
      //           << remoteParticipant->port << " "
 | 
					 | 
				
			||||||
      //           << (int)remoteParticipant->networkId << "\n";
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ReceiveData(packetSize, remoteParticipant);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool UdpWindows::Send(RemoteParticipant *remoteParticipant, int bufferSize) {
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
  char ip_str[INET_ADDRSTRLEN];
 | 
					 | 
				
			||||||
  inet_ntop(AF_INET, &(remote_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
 | 
					 | 
				
			||||||
  std::cout << "Send to " << ip_str << ":" << ntohs(remote_addr.sin_port)
 | 
					 | 
				
			||||||
            << "\n";
 | 
					 | 
				
			||||||
  int sent_bytes = sendto(sock, this->buffer, bufferSize, 0,
 | 
					 | 
				
			||||||
                          (struct sockaddr *)&remote_addr, sizeof(remote_addr));
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
  if (sent_bytes <= SOCKET_ERROR) {
 | 
					 | 
				
			||||||
    int error_code = WSAGetLastError(); // Get the error code on Windows
 | 
					 | 
				
			||||||
    std::cerr << "sendto failed with error: " << error_code << std::endl;
 | 
					 | 
				
			||||||
    closesocket(sock);
 | 
					 | 
				
			||||||
    WSACleanup();
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
  if (sent_bytes < 0) {
 | 
					 | 
				
			||||||
    std::cerr << "sendto failed with error: " << sent_bytes << std::endl;
 | 
					 | 
				
			||||||
    close(sock);
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool UdpWindows::Publish(IMessage *msg) {
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
  int bufferSize = msg->Serialize(this->buffer);
 | 
					 | 
				
			||||||
  if (bufferSize <= 0)
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  char ip_str[INET_ADDRSTRLEN];
 | 
					 | 
				
			||||||
  inet_ntop(AF_INET, &(broadcast_addr.sin_addr), ip_str, INET_ADDRSTRLEN);
 | 
					 | 
				
			||||||
  std::cout << "Publish to " << ip_str << ":" << ntohs(broadcast_addr.sin_port)
 | 
					 | 
				
			||||||
            << "\n";
 | 
					 | 
				
			||||||
  int sent_bytes =
 | 
					 | 
				
			||||||
      sendto(sock, this->buffer, bufferSize, 0,
 | 
					 | 
				
			||||||
             (struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr));
 | 
					 | 
				
			||||||
#if defined(_WIN32) || defined(_WIN64)
 | 
					 | 
				
			||||||
  if (sent_bytes <= SOCKET_ERROR) {
 | 
					 | 
				
			||||||
    int error_code = WSAGetLastError(); // Get the error code on Windows
 | 
					 | 
				
			||||||
    std::cerr << "sendto failed with error: " << error_code << std::endl;
 | 
					 | 
				
			||||||
    closesocket(sock);
 | 
					 | 
				
			||||||
    WSACleanup();
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
					 | 
				
			||||||
  if (sent_bytes < 0) {
 | 
					 | 
				
			||||||
    std::cerr << "sendto failed with error: " << sent_bytes << std::endl;
 | 
					 | 
				
			||||||
    close(sock);
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace Control
 | 
					 | 
				
			||||||
} // namespace Passer
 | 
					 | 
				
			||||||
							
								
								
									
										17
									
								
								UdpWindows.h
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								UdpWindows.h
									
									
									
									
									
								
							@ -1,17 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "Participant.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Passer {
 | 
					 | 
				
			||||||
namespace Control {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class UdpWindows : public Participant {
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
  void Setup(int localPort, const char *remoteIpAddress, int remotePort);
 | 
					 | 
				
			||||||
  void Receive();
 | 
					 | 
				
			||||||
  bool Send(RemoteParticipant* remoteParticipant, int bufferSize);
 | 
					 | 
				
			||||||
  bool Publish(IMessage *msg);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace Control
 | 
					 | 
				
			||||||
} // namespace Passer
 | 
					 | 
				
			||||||
							
								
								
									
										0
									
								
								Windows/Participant.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								Windows/Participant.cpp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										19
									
								
								Windows/Participant.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Windows/Participant.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../Participant.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Passer {
 | 
				
			||||||
 | 
					namespace RoboidControl {
 | 
				
			||||||
 | 
					namespace Windows {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Participant : public RoboidControl::Participant {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  void Setup(int localPort, const char* remoteIpAddress, int remotePort);
 | 
				
			||||||
 | 
					  void Receive();
 | 
				
			||||||
 | 
					  bool Send(RemoteParticipant* remoteParticipant, int bufferSize);
 | 
				
			||||||
 | 
					  bool Publish(IMessage* msg);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace Windows
 | 
				
			||||||
 | 
					}  // namespace RoboidControl
 | 
				
			||||||
 | 
					}  // namespace Passer
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user