Fixes to make it work againg, but failing at udp.begin()
This commit is contained in:
		
							parent
							
								
									0317ac5094
								
							
						
					
					
						commit
						a17c933908
					
				@ -19,12 +19,8 @@
 | 
			
		||||
namespace RoboidControl {
 | 
			
		||||
namespace Arduino {
 | 
			
		||||
 | 
			
		||||
void ParticipantUDP::Setup(int localPort,
 | 
			
		||||
                             const char* remoteIpAddress,
 | 
			
		||||
                             int remotePort) {
 | 
			
		||||
void ParticipantUDP::Setup() {
 | 
			
		||||
#if defined(ARDUINO) && defined(HAS_WIFI)
 | 
			
		||||
  this->remoteIpAddress = remoteIpAddress;
 | 
			
		||||
  this->remotePort = remotePort;
 | 
			
		||||
  GetBroadcastAddress();
 | 
			
		||||
 | 
			
		||||
#if defined(UNO_R4)
 | 
			
		||||
@ -38,9 +34,14 @@ void ParticipantUDP::Setup(int localPort,
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  udp.begin(localPort);
 | 
			
		||||
  std::cout << "UDP.begin " << this->port << std::endl;
 | 
			
		||||
 | 
			
		||||
  std::cout << "Wifi sync started to port " << this->remotePort << "\n";
 | 
			
		||||
  udp.begin(this->port);
 | 
			
		||||
 | 
			
		||||
  std::cout << "Wifi sync started local " << this->port;
 | 
			
		||||
  if (this->remoteSite != nullptr)
 | 
			
		||||
    std::cout << ", remote " << this->remoteSite->ipAddress << ":"
 | 
			
		||||
              << this->remoteSite->port << "\n";
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -112,7 +113,7 @@ bool ParticipantUDP::Publish(IMessage* msg) {
 | 
			
		||||
  if (bufferSize <= 0)
 | 
			
		||||
    return true;
 | 
			
		||||
 | 
			
		||||
  udp.beginPacket(this->broadcastIpAddress, this->remotePort);
 | 
			
		||||
  udp.beginPacket(this->broadcastIpAddress, this->port);
 | 
			
		||||
  udp.write((unsigned char*)buffer, bufferSize);
 | 
			
		||||
  udp.endPacket();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -11,15 +11,13 @@ namespace Arduino {
 | 
			
		||||
 | 
			
		||||
class ParticipantUDP : public RoboidControl::ParticipantUDP {
 | 
			
		||||
 public:
 | 
			
		||||
  void Setup(int localPort, const char* remoteIpAddress, int remotePort);
 | 
			
		||||
  void Setup();
 | 
			
		||||
  void Receive();
 | 
			
		||||
  bool Send(Participant* remoteParticipant, int bufferSize);
 | 
			
		||||
  bool Publish(IMessage* msg);
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
#if defined(HAS_WIFI)
 | 
			
		||||
  const char* remoteIpAddress = nullptr;
 | 
			
		||||
  unsigned short remotePort = 0;
 | 
			
		||||
  char* broadcastIpAddress = nullptr;
 | 
			
		||||
 | 
			
		||||
  WiFiUDP udp;
 | 
			
		||||
 | 
			
		||||
@ -5,18 +5,27 @@
 | 
			
		||||
namespace RoboidControl {
 | 
			
		||||
namespace Arduino {
 | 
			
		||||
 | 
			
		||||
DRV8833Motor::DRV8833Motor(Participant* participant, unsigned char pinIn1, unsigned char pinIn2, bool reverse)
 | 
			
		||||
#if (ESP32)
 | 
			
		||||
uint8_t DRV8833Motor::nextAvailablePwmChannel = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
DRV8833Motor::DRV8833Motor(Participant* participant,
 | 
			
		||||
                           unsigned char pinIn1,
 | 
			
		||||
                           unsigned char pinIn2,
 | 
			
		||||
                           bool reverse)
 | 
			
		||||
    : Thing(participant) {
 | 
			
		||||
  this->pinIn1 = pinIn1;
 | 
			
		||||
  this->pinIn2 = pinIn2;
 | 
			
		||||
 | 
			
		||||
#if (ESP32)
 | 
			
		||||
  in1Ch = nextAvailablePwmChannel++;
 | 
			
		||||
  in1Ch = DRV8833Motor::nextAvailablePwmChannel++;
 | 
			
		||||
  ledcSetup(in1Ch, 500, 8);
 | 
			
		||||
  ledcAttachPin(pinIn1, in1Ch);
 | 
			
		||||
  in2Ch = nextAvailablePwmChannel++;
 | 
			
		||||
 | 
			
		||||
  in2Ch = DRV8833Motor::nextAvailablePwmChannel++;
 | 
			
		||||
  ledcSetup(in2Ch, 500, 8);
 | 
			
		||||
  ledcAttachPin(pinIn2, in2Ch);
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
  pinMode(pinIn1, OUTPUT);  // configure the in1 pin to output mode
 | 
			
		||||
  pinMode(pinIn2, OUTPUT);  // configure the in1 pin to output mode
 | 
			
		||||
@ -47,7 +56,8 @@ void DRV8833Motor::SetAngularVelocity(Spherical velocity) {
 | 
			
		||||
  if (this->reverse)
 | 
			
		||||
    motorSpeed = -motorSpeed;
 | 
			
		||||
 | 
			
		||||
  // std::cout << "ang speed " << this->name << " = " << angularSpeed << "   rpm " << rpm
 | 
			
		||||
  // std::cout << "ang speed " << this->name << " = " << angularSpeed << "   rpm
 | 
			
		||||
  // " << rpm
 | 
			
		||||
  //           << ", motor signal = " << (int)motorSignal << "\n";
 | 
			
		||||
 | 
			
		||||
#if (ESP32)
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <Arduino.h>
 | 
			
		||||
#include "Thing.h"
 | 
			
		||||
#include "Things/DifferentialDrive.h"
 | 
			
		||||
 | 
			
		||||
@ -16,7 +17,10 @@ class DRV8833Motor : public Thing {
 | 
			
		||||
  /// @param pinIn1 the pin number for the in1 signal
 | 
			
		||||
  /// @param pinIn2 the pin number for the in2 signal
 | 
			
		||||
  /// @param direction the forward turning direction of the motor
 | 
			
		||||
  DRV8833Motor(Participant* participant, unsigned char pinIn1, unsigned char pinIn2, bool reverse = false);
 | 
			
		||||
  DRV8833Motor(Participant* participant,
 | 
			
		||||
               unsigned char pinIn1,
 | 
			
		||||
               unsigned char pinIn2,
 | 
			
		||||
               bool reverse = false);
 | 
			
		||||
  void SetMaxRPM(unsigned int rpm);
 | 
			
		||||
 | 
			
		||||
  virtual void SetAngularVelocity(Spherical velocity) override;
 | 
			
		||||
@ -27,6 +31,12 @@ class DRV8833Motor : public Thing {
 | 
			
		||||
  unsigned char pinIn1 = 255;
 | 
			
		||||
  unsigned char pinIn2 = 255;
 | 
			
		||||
  unsigned int maxRpm = 200;
 | 
			
		||||
 | 
			
		||||
#if (ESP32)
 | 
			
		||||
  uint8_t in1Ch;
 | 
			
		||||
  uint8_t in2Ch;
 | 
			
		||||
  static uint8_t nextAvailablePwmChannel;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class DRV8833 : public Thing {
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
#include "Matrix.h"
 | 
			
		||||
#if !defined(NO_STD) 
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace LinearAlgebra {
 | 
			
		||||
 | 
			
		||||
@ -61,7 +63,9 @@ Matrix2::Matrix2(const Matrix2& m)
 | 
			
		||||
    this->data = nullptr;
 | 
			
		||||
  else {
 | 
			
		||||
    this->data = new float[this->nValues];
 | 
			
		||||
    std::copy(m.data, m.data + nValues, this->data);
 | 
			
		||||
 | 
			
		||||
    for (int ix = 0; ix < this->nValues; ++ix)
 | 
			
		||||
      this->data[ix] = m.data[ix];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -76,7 +80,8 @@ Matrix2& Matrix2::operator=(const Matrix2& m) {
 | 
			
		||||
      this->data = nullptr;
 | 
			
		||||
    else {
 | 
			
		||||
      this->data = new float[this->nValues];
 | 
			
		||||
      std::copy(m.data, m.data + this->nValues, this->data);
 | 
			
		||||
      for (int ix = 0; ix < this->nValues; ++ix)
 | 
			
		||||
        this->data[ix] = m.data[ix];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return *this;
 | 
			
		||||
@ -89,7 +94,8 @@ Matrix2::~Matrix2() {
 | 
			
		||||
 | 
			
		||||
Matrix2 Matrix2::Clone() const {
 | 
			
		||||
  Matrix2 r = Matrix2(this->nRows, this->nCols);
 | 
			
		||||
  std::copy(this->data, this->data + this->nValues, r.data);
 | 
			
		||||
  for (int ix = 0; ix < this->nValues; ++ix)
 | 
			
		||||
    r.data[ix] = this->data[ix];
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -158,8 +164,8 @@ Matrix2 Matrix2::SkewMatrix(const Vector3& v) {
 | 
			
		||||
Matrix2 Matrix2::Transpose() const {
 | 
			
		||||
  Matrix2 r = Matrix2(this->nCols, this->nRows);
 | 
			
		||||
 | 
			
		||||
  for (uint rowIx = 0; rowIx < this->nRows; rowIx++) {
 | 
			
		||||
    for (uint colIx = 0; colIx < this->nCols; colIx++)
 | 
			
		||||
  for (int rowIx = 0; rowIx < this->nRows; rowIx++) {
 | 
			
		||||
    for (int colIx = 0; colIx < this->nCols; colIx++)
 | 
			
		||||
      r.data[colIx * this->nCols + rowIx] =
 | 
			
		||||
          this->data[rowIx * this->nCols + colIx];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,366 +0,0 @@
 | 
			
		||||
#include "LocalParticipant.h"
 | 
			
		||||
 | 
			
		||||
#include "Thing.h"
 | 
			
		||||
 | 
			
		||||
#include "Arduino/ArduinoParticipant.h"
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
#include <winsock2.h>
 | 
			
		||||
#include <ws2tcpip.h>
 | 
			
		||||
#include "Windows/WindowsParticipant.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>
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include "Posix/PosixParticipant.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
namespace RoboidControl {
 | 
			
		||||
 | 
			
		||||
// LocalParticipant::LocalParticipant() {}
 | 
			
		||||
 | 
			
		||||
LocalParticipant::LocalParticipant(int port) {
 | 
			
		||||
  this->ipAddress = "0.0.0.0";
 | 
			
		||||
  this->port = port;
 | 
			
		||||
  if (this->port == 0)
 | 
			
		||||
    this->isIsolated = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LocalParticipant::LocalParticipant(const char* ipAddress, int port) {
 | 
			
		||||
  this->ipAddress = "0.0.0.0";  // ipAddress;  // maybe this is not needed
 | 
			
		||||
                                // anymore, keeping it to "0.0.0.0"
 | 
			
		||||
  this->port = port;
 | 
			
		||||
  if (this->port == 0)
 | 
			
		||||
    this->isIsolated = true;
 | 
			
		||||
  else
 | 
			
		||||
    this->remoteSite = new Participant(ipAddress, port);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static LocalParticipant* isolatedParticipant = nullptr;
 | 
			
		||||
 | 
			
		||||
LocalParticipant* LocalParticipant::Isolated() {
 | 
			
		||||
  if (isolatedParticipant == nullptr)
 | 
			
		||||
    isolatedParticipant = new LocalParticipant(0);
 | 
			
		||||
  return isolatedParticipant;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::begin() {
 | 
			
		||||
  if (this->isIsolated)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  SetupUDP(this->port, this->ipAddress, this->port);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::SetupUDP(int localPort,
 | 
			
		||||
                                const char* remoteIpAddress,
 | 
			
		||||
                                int remotePort) {
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
  Windows::LocalParticipant* thisWindows =
 | 
			
		||||
      static_cast<Windows::LocalParticipant*>(this);
 | 
			
		||||
  thisWindows->Setup(localPort, remoteIpAddress, remotePort);
 | 
			
		||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
			
		||||
  Posix::LocalParticipant* thisPosix =
 | 
			
		||||
      static_cast<Posix::LocalParticipant*>(this);
 | 
			
		||||
  thisPosix->Setup(localPort, remoteIpAddress, remotePort);
 | 
			
		||||
#elif defined(ARDUINO)
 | 
			
		||||
  Arduino::LocalParticipant* thisArduino =
 | 
			
		||||
      static_cast<Arduino::LocalParticipant*>(this);
 | 
			
		||||
  thisArduino->Setup(localPort, remoteIpAddress, remotePort);
 | 
			
		||||
#endif
 | 
			
		||||
  this->connected = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::Update(unsigned long currentTimeMs) {
 | 
			
		||||
  if (currentTimeMs == 0) {
 | 
			
		||||
    currentTimeMs = Thing::GetTimeMs();
 | 
			
		||||
    // #if defined(ARDUINO)
 | 
			
		||||
    //     currentTimeMs = millis();
 | 
			
		||||
    // #elif defined(__unix__) || defined(__APPLE__)
 | 
			
		||||
    //     auto now = std::chrono::steady_clock::now();
 | 
			
		||||
    //     auto ms =
 | 
			
		||||
    //     std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
 | 
			
		||||
    //     currentTimeMs = static_cast<unsigned long>(ms.count());
 | 
			
		||||
    // #endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (this->isIsolated == false) {
 | 
			
		||||
    if (this->connected == false)
 | 
			
		||||
      begin();
 | 
			
		||||
 | 
			
		||||
    if (this->publishInterval > 0 && currentTimeMs > this->nextPublishMe) {
 | 
			
		||||
      ParticipantMsg* msg = new ParticipantMsg(this->networkId);
 | 
			
		||||
      if (this->remoteSite == nullptr)
 | 
			
		||||
        this->Publish(msg);
 | 
			
		||||
      else
 | 
			
		||||
        this->Send(this->remoteSite, msg);
 | 
			
		||||
      delete msg;
 | 
			
		||||
 | 
			
		||||
      this->nextPublishMe = currentTimeMs + this->publishInterval;
 | 
			
		||||
    }
 | 
			
		||||
    this->ReceiveUDP();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (Thing* thing : this->things) {
 | 
			
		||||
    if (thing != nullptr) {
 | 
			
		||||
      thing->Update(currentTimeMs);
 | 
			
		||||
      if (this->isIsolated == false) {
 | 
			
		||||
        PoseMsg* poseMsg = new PoseMsg(this->networkId, thing);
 | 
			
		||||
        for (Participant* sender : this->senders)
 | 
			
		||||
          this->Send(sender, poseMsg);
 | 
			
		||||
        delete poseMsg;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::ReceiveUDP() {
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
  Windows::LocalParticipant* thisWindows =
 | 
			
		||||
      static_cast<Windows::LocalParticipant*>(this);
 | 
			
		||||
  thisWindows->Receive();
 | 
			
		||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
			
		||||
  Posix::LocalParticipant* thisPosix =
 | 
			
		||||
      static_cast<Posix::LocalParticipant*>(this);
 | 
			
		||||
  thisPosix->Receive();
 | 
			
		||||
#elif defined(ARDUINO)
 | 
			
		||||
  Arduino::LocalParticipant* thisArduino =
 | 
			
		||||
      static_cast<Arduino::LocalParticipant*>(this);
 | 
			
		||||
  thisArduino->Receive();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Participant* LocalParticipant::GetParticipant(const char* ipAddress, int port) {
 | 
			
		||||
  for (Participant* sender : this->senders) {
 | 
			
		||||
    if (strcmp(sender->ipAddress, ipAddress) == 0 && sender->port == port)
 | 
			
		||||
      return sender;
 | 
			
		||||
  }
 | 
			
		||||
  return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Participant* LocalParticipant::AddParticipant(const char* ipAddress, int port) {
 | 
			
		||||
  // std::cout << "New Participant " << ipAddress << ":" << port << "\n";
 | 
			
		||||
  Participant* participant = new Participant(ipAddress, port);
 | 
			
		||||
#if defined(NO_STD)
 | 
			
		||||
  participant->networkId = this->senderCount;
 | 
			
		||||
  this->senders[this->senderCount++] = participant;
 | 
			
		||||
#else
 | 
			
		||||
  participant->networkId = (unsigned char)this->senders.size();
 | 
			
		||||
  this->senders.push_back(participant);
 | 
			
		||||
#endif
 | 
			
		||||
  return participant;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma region Send
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::SendThingInfo(Participant* remoteParticipant,
 | 
			
		||||
                                     Thing* thing) {
 | 
			
		||||
  // std::cout << "Send thing info " << (int)thing->id << " \n";
 | 
			
		||||
  ThingMsg* thingMsg = new ThingMsg(this->networkId, thing);
 | 
			
		||||
  this->Send(remoteParticipant, thingMsg);
 | 
			
		||||
  delete thingMsg;
 | 
			
		||||
  NameMsg* nameMsg = new NameMsg(this->networkId, thing);
 | 
			
		||||
  this->Send(remoteParticipant, nameMsg);
 | 
			
		||||
  delete nameMsg;
 | 
			
		||||
  ModelUrlMsg* modelMsg = new ModelUrlMsg(this->networkId, thing);
 | 
			
		||||
  this->Send(remoteParticipant, modelMsg);
 | 
			
		||||
  delete modelMsg;
 | 
			
		||||
  PoseMsg* poseMsg = new PoseMsg(this->networkId, thing, true);
 | 
			
		||||
  this->Send(remoteParticipant, poseMsg);
 | 
			
		||||
  delete poseMsg;
 | 
			
		||||
  BinaryMsg* customMsg = new BinaryMsg(this->networkId, thing);
 | 
			
		||||
  this->Send(remoteParticipant, customMsg);
 | 
			
		||||
  delete customMsg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool LocalParticipant::Send(Participant* remoteParticipant, IMessage* msg) {
 | 
			
		||||
  int bufferSize = msg->Serialize(this->buffer);
 | 
			
		||||
  if (bufferSize <= 0)
 | 
			
		||||
    return true;
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
  Windows::LocalParticipant* thisWindows =
 | 
			
		||||
      static_cast<Windows::LocalParticipant*>(this);
 | 
			
		||||
  return thisWindows->Send(remoteParticipant, bufferSize);
 | 
			
		||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
			
		||||
  Posix::LocalParticipant* thisPosix =
 | 
			
		||||
      static_cast<Posix::LocalParticipant*>(this);
 | 
			
		||||
  return thisPosix->Send(remoteParticipant, bufferSize);
 | 
			
		||||
#elif defined(ARDUINO)
 | 
			
		||||
  Arduino::LocalParticipant* thisArduino =
 | 
			
		||||
      static_cast<Arduino::LocalParticipant*>(this);
 | 
			
		||||
  return thisArduino->Send(remoteParticipant, bufferSize);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::PublishThingInfo(Thing* thing) {
 | 
			
		||||
  // std::cout << "Publish thing info" << thing->networkId << "\n";
 | 
			
		||||
  //  Strange, when publishing, the network id is irrelevant, because it is
 | 
			
		||||
  //  connected to a specific site...
 | 
			
		||||
  ThingMsg* thingMsg = new ThingMsg(this->networkId, thing);
 | 
			
		||||
  this->Publish(thingMsg);
 | 
			
		||||
  delete thingMsg;
 | 
			
		||||
  NameMsg* nameMsg = new NameMsg(this->networkId, thing);
 | 
			
		||||
  this->Publish(nameMsg);
 | 
			
		||||
  delete nameMsg;
 | 
			
		||||
  ModelUrlMsg* modelMsg = new ModelUrlMsg(this->networkId, thing);
 | 
			
		||||
  this->Publish(modelMsg);
 | 
			
		||||
  delete modelMsg;
 | 
			
		||||
  PoseMsg* poseMsg = new PoseMsg(this->networkId, thing, true);
 | 
			
		||||
  this->Publish(poseMsg);
 | 
			
		||||
  delete poseMsg;
 | 
			
		||||
  BinaryMsg* customMsg = new BinaryMsg(this->networkId, thing);
 | 
			
		||||
  this->Publish(customMsg);
 | 
			
		||||
  delete customMsg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool LocalParticipant::Publish(IMessage* msg) {
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
  Windows::LocalParticipant* thisWindows =
 | 
			
		||||
      static_cast<Windows::LocalParticipant*>(this);
 | 
			
		||||
  return thisWindows->Publish(msg);
 | 
			
		||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
			
		||||
  Posix::LocalParticipant* thisPosix =
 | 
			
		||||
      static_cast<Posix::LocalParticipant*>(this);
 | 
			
		||||
  return thisPosix->Publish(msg);
 | 
			
		||||
#elif defined(ARDUINO)
 | 
			
		||||
  Arduino::LocalParticipant* thisArduino =
 | 
			
		||||
      static_cast<Arduino::LocalParticipant*>(this);
 | 
			
		||||
  return thisArduino->Publish(msg);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Send
 | 
			
		||||
#pragma endregion
 | 
			
		||||
 | 
			
		||||
#pragma region Receive
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::ReceiveData(unsigned char packetSize,
 | 
			
		||||
                                   char* senderIpAddress,
 | 
			
		||||
                                   unsigned int senderPort) {
 | 
			
		||||
  Participant* remoteParticipant =
 | 
			
		||||
      this->GetParticipant(senderIpAddress, senderPort);
 | 
			
		||||
  if (remoteParticipant == nullptr) {
 | 
			
		||||
    remoteParticipant = this->AddParticipant(senderIpAddress, senderPort);
 | 
			
		||||
    // 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::ReceiveData(unsigned char bufferSize,
 | 
			
		||||
                                   Participant* remoteParticipant) {
 | 
			
		||||
  unsigned char msgId = this->buffer[0];
 | 
			
		||||
  // std::cout << "receive msg " << (int)msgId << "\n";
 | 
			
		||||
  switch (msgId) {
 | 
			
		||||
    case ParticipantMsg::id: {
 | 
			
		||||
      ParticipantMsg* msg = new ParticipantMsg(this->buffer);
 | 
			
		||||
      Process(remoteParticipant, msg);
 | 
			
		||||
      delete msg;
 | 
			
		||||
    } break;
 | 
			
		||||
    case SiteMsg::id: {
 | 
			
		||||
      SiteMsg* msg = new SiteMsg(this->buffer);
 | 
			
		||||
      Process(remoteParticipant, msg);
 | 
			
		||||
      delete msg;
 | 
			
		||||
    } break;
 | 
			
		||||
    case InvestigateMsg::id: {
 | 
			
		||||
      InvestigateMsg* msg = new InvestigateMsg(this->buffer);
 | 
			
		||||
      Process(remoteParticipant, msg);
 | 
			
		||||
      delete msg;
 | 
			
		||||
    } break;
 | 
			
		||||
    case ThingMsg::id: {
 | 
			
		||||
      ThingMsg* msg = new ThingMsg(this->buffer);
 | 
			
		||||
      Process(remoteParticipant, msg);
 | 
			
		||||
      delete msg;
 | 
			
		||||
    } break;
 | 
			
		||||
    case NameMsg::id: {
 | 
			
		||||
      NameMsg* msg = new NameMsg(this->buffer);
 | 
			
		||||
      Process(remoteParticipant, msg);
 | 
			
		||||
      delete msg;
 | 
			
		||||
    } break;
 | 
			
		||||
    case PoseMsg::id: {
 | 
			
		||||
      PoseMsg* msg = new PoseMsg(this->buffer);
 | 
			
		||||
      Process(remoteParticipant, msg);
 | 
			
		||||
      delete msg;
 | 
			
		||||
    } break;
 | 
			
		||||
    case BinaryMsg::id: {
 | 
			
		||||
      BinaryMsg* msg = new BinaryMsg(this->buffer);
 | 
			
		||||
      Process(remoteParticipant, msg);
 | 
			
		||||
      delete msg;
 | 
			
		||||
    } break;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::Process(Participant* sender, ParticipantMsg* msg) {}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::Process(Participant* sender, SiteMsg* msg) {
 | 
			
		||||
  // std::cout << this->name << ": process NetworkId [" << (int)this->networkId
 | 
			
		||||
  //           << "/" << (int)msg->networkId << "]\n";
 | 
			
		||||
  if (this->networkId != msg->networkId) {
 | 
			
		||||
    this->networkId = msg->networkId;
 | 
			
		||||
    // std::cout << this->things.size() << " things\n";
 | 
			
		||||
    for (Thing* thing : this->things)
 | 
			
		||||
      this->SendThingInfo(sender, thing);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::Process(Participant* sender, InvestigateMsg* msg) {}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::Process(Participant* sender, ThingMsg* msg) {}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::Process(Participant* sender, NameMsg* msg) {
 | 
			
		||||
  Thing* thing = sender->Get(msg->networkId, msg->thingId);
 | 
			
		||||
  if (thing != nullptr) {
 | 
			
		||||
    int nameLength = msg->nameLength;
 | 
			
		||||
    int stringLen = nameLength + 1;
 | 
			
		||||
    char* thingName = new char[stringLen];
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
    strncpy_s(thingName, stringLen, msg->name,
 | 
			
		||||
              stringLen - 1);  // Leave space for null terminator
 | 
			
		||||
#else
 | 
			
		||||
    // Use strncpy with bounds checking for other platforms (Arduino, POSIX,
 | 
			
		||||
    // ESP-IDF)
 | 
			
		||||
    strncpy(thingName, msg->name,
 | 
			
		||||
            stringLen - 1);           // Leave space for null terminator
 | 
			
		||||
    thingName[stringLen - 1] = '\0';  // Ensure null termination
 | 
			
		||||
#endif
 | 
			
		||||
    thingName[nameLength] = '\0';
 | 
			
		||||
    thing->name = thingName;
 | 
			
		||||
    // std::cout << "thing name = " << thing->name << " length = " << nameLength
 | 
			
		||||
    //           << "\n";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::Process(Participant* sender, PoseMsg* msg) {}
 | 
			
		||||
 | 
			
		||||
void LocalParticipant::Process(Participant* sender, BinaryMsg* msg) {
 | 
			
		||||
  // std::cout << this->name << ": process Binary [" << (int)this->networkId <<
 | 
			
		||||
  // "/"
 | 
			
		||||
  //           << (int)msg->networkId << "]\n";
 | 
			
		||||
  Thing* thing = sender->Get(msg->networkId, msg->thingId);
 | 
			
		||||
  if (thing != nullptr)
 | 
			
		||||
    thing->ProcessBinary(msg->bytes);
 | 
			
		||||
  else {
 | 
			
		||||
    thing = this->Get(msg->networkId, msg->thingId);
 | 
			
		||||
    if (thing != nullptr)
 | 
			
		||||
      thing->ProcessBinary(msg->bytes);
 | 
			
		||||
    // else
 | 
			
		||||
    //   std::cout << "custom msg for unknown thing [" << (int)msg->networkId
 | 
			
		||||
    //             << "/" << (int)msg->thingId << "]\n";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Receive
 | 
			
		||||
#pragma endregion
 | 
			
		||||
 | 
			
		||||
}  // namespace RoboidControl
 | 
			
		||||
@ -1,140 +0,0 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Messages/BinaryMsg.h"
 | 
			
		||||
#include "Messages/InvestigateMsg.h"
 | 
			
		||||
#include "Messages/ModelUrlMsg.h"
 | 
			
		||||
#include "Messages/NameMsg.h"
 | 
			
		||||
#include "Messages/ParticipantMsg.h"
 | 
			
		||||
#include "Messages/PoseMsg.h"
 | 
			
		||||
#include "Messages/SiteMsg.h"
 | 
			
		||||
#include "Messages/ThingMsg.h"
 | 
			
		||||
#include "Participant.h"
 | 
			
		||||
 | 
			
		||||
#if !defined(NO_STD)
 | 
			
		||||
#include <list>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
#include <winsock2.h>
 | 
			
		||||
#elif defined(__unix__) || defined(__APPLE__)
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#elif defined(ARDUINO)
 | 
			
		||||
// #include <WiFiUdp.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace RoboidControl {
 | 
			
		||||
 | 
			
		||||
constexpr int MAX_SENDER_COUNT = 256;
 | 
			
		||||
 | 
			
		||||
/// @brief A local participant is the local device which can communicate with
 | 
			
		||||
/// other participants It manages all local things and communcation with other
 | 
			
		||||
/// participants. Each application has a local participant which is usually
 | 
			
		||||
/// explicit in the code. An participant can be isolated. In that case it is
 | 
			
		||||
/// standalong and does not communicate with other participants.
 | 
			
		||||
///
 | 
			
		||||
/// It is possible to work with an hidden participant by creating things without
 | 
			
		||||
/// specifying a participant in the constructor. In that case an hidden isolated
 | 
			
		||||
/// participant is created which can be obtained using
 | 
			
		||||
/// RoboidControl::LocalParticipant::Isolated().
 | 
			
		||||
/// @sa RoboidControl::Thing::Thing()
 | 
			
		||||
class LocalParticipant : public Participant {
 | 
			
		||||
 public:
 | 
			
		||||
  /// @brief Create a participant without connecting to a site
 | 
			
		||||
  /// @param port The port on which the participant communicates
 | 
			
		||||
  /// These participant typically broadcast Participant messages to let site
 | 
			
		||||
  /// servers on the local network know their presence. Alternatively they can
 | 
			
		||||
  /// broadcast information which can be used directly by other participants.
 | 
			
		||||
  LocalParticipant(int port = 7681);
 | 
			
		||||
  /// @brief Create a participant which will try to connect to a site.
 | 
			
		||||
  /// @param ipAddress The IP address of the site
 | 
			
		||||
  /// @param port The port used by the site
 | 
			
		||||
  LocalParticipant(const char* ipAddress, int port = 7681);
 | 
			
		||||
  // Note to self: one cannot specify the port used by the local participant
 | 
			
		||||
  // now!!
 | 
			
		||||
 | 
			
		||||
  /// @brief Isolated participant is used when the application is run without
 | 
			
		||||
  /// networking
 | 
			
		||||
  /// @return A participant without networking support
 | 
			
		||||
  static LocalParticipant* Isolated();
 | 
			
		||||
 | 
			
		||||
  /// @brief True if the participant is running isolated.
 | 
			
		||||
  /// Isolated participants do not communicate with other participants
 | 
			
		||||
  bool isIsolated = false;
 | 
			
		||||
 | 
			
		||||
  /// The interval in milliseconds for publishing (broadcasting) data on the
 | 
			
		||||
  /// local network
 | 
			
		||||
  long publishInterval = 3000;  // 3 seconds
 | 
			
		||||
 | 
			
		||||
  /// @brief The name of the participant
 | 
			
		||||
  const char* name = "LocalParticipant";
 | 
			
		||||
 | 
			
		||||
  // int localPort = 0;
 | 
			
		||||
 | 
			
		||||
  /// @brief The remote site when this participant is connected to a site
 | 
			
		||||
  Participant* remoteSite = nullptr;
 | 
			
		||||
 | 
			
		||||
#if defined(ARDUINO)
 | 
			
		||||
  // const char* remoteIpAddress = nullptr;
 | 
			
		||||
  // unsigned short remotePort = 0;
 | 
			
		||||
  // char* broadcastIpAddress = nullptr;
 | 
			
		||||
 | 
			
		||||
  // WiFiUDP udp;
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#if defined(__unix__) || defined(__APPLE__)
 | 
			
		||||
  int sock;
 | 
			
		||||
#endif
 | 
			
		||||
  sockaddr_in remote_addr;
 | 
			
		||||
  sockaddr_in server_addr;
 | 
			
		||||
  sockaddr_in broadcast_addr;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  void begin();
 | 
			
		||||
  bool connected = false;
 | 
			
		||||
 | 
			
		||||
  virtual void Update(unsigned long currentTimeMs = 0);
 | 
			
		||||
 | 
			
		||||
  void SendThingInfo(Participant* remoteParticipant, Thing* thing);
 | 
			
		||||
  void PublishThingInfo(Thing* thing);
 | 
			
		||||
 | 
			
		||||
  bool Send(Participant* remoteParticipant, IMessage* msg);
 | 
			
		||||
  bool Publish(IMessage* msg);
 | 
			
		||||
 | 
			
		||||
  void ReceiveData(unsigned char bufferSize,
 | 
			
		||||
                   char* senderIpAddress,
 | 
			
		||||
                   unsigned int senderPort);
 | 
			
		||||
  void ReceiveData(unsigned char bufferSize, Participant* remoteParticipant);
 | 
			
		||||
 | 
			
		||||
#if defined(NO_STD)
 | 
			
		||||
  unsigned char senderCount = 0;
 | 
			
		||||
  Participant* senders[MAX_SENDER_COUNT];
 | 
			
		||||
#else
 | 
			
		||||
  std::list<Participant*> senders;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  unsigned long nextPublishMe = 0;
 | 
			
		||||
 | 
			
		||||
  char buffer[1024];
 | 
			
		||||
 | 
			
		||||
  void SetupUDP(int localPort, const char* remoteIpAddress, int remotePort);
 | 
			
		||||
 | 
			
		||||
  Participant* GetParticipant(const char* ipAddress, int port);
 | 
			
		||||
  Participant* AddParticipant(const char* ipAddress, int port);
 | 
			
		||||
 | 
			
		||||
  void ReceiveUDP();
 | 
			
		||||
 | 
			
		||||
  virtual void Process(Participant* sender, ParticipantMsg* msg);
 | 
			
		||||
  virtual void Process(Participant* sender, SiteMsg* msg);
 | 
			
		||||
  virtual void Process(Participant* sender, InvestigateMsg* msg);
 | 
			
		||||
  virtual void Process(Participant* sender, ThingMsg* msg);
 | 
			
		||||
  virtual void Process(Participant* sender, NameMsg* msg);
 | 
			
		||||
  virtual void Process(Participant* sender, PoseMsg* msg);
 | 
			
		||||
  virtual void Process(Participant* sender, BinaryMsg* msg);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace RoboidControl
 | 
			
		||||
@ -7,6 +7,7 @@ BinaryMsg::BinaryMsg(unsigned char networkId, Thing* thing) {
 | 
			
		||||
  this->thingId = thing->id;
 | 
			
		||||
  this->thing = thing;
 | 
			
		||||
  unsigned char ix = BinaryMsg::length;
 | 
			
		||||
  this->data = new char[255];
 | 
			
		||||
  this->dataLength = this->thing->GenerateBinary(this->data, &ix);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -69,7 +69,7 @@ void ParticipantUDP::SetupUDP(int localPort,
 | 
			
		||||
#elif defined(ARDUINO)
 | 
			
		||||
  Arduino::ParticipantUDP* thisArduino =
 | 
			
		||||
      static_cast<Arduino::ParticipantUDP*>(this);
 | 
			
		||||
  thisArduino->Setup(localPort, remoteIpAddress, remotePort);
 | 
			
		||||
  thisArduino->Setup();
 | 
			
		||||
#elif defined(IDF_VER)
 | 
			
		||||
  EspIdf::ParticipantUDP* thisEspIdf =
 | 
			
		||||
      static_cast<EspIdf::ParticipantUDP*>(this);
 | 
			
		||||
@ -255,8 +255,10 @@ void ParticipantUDP::ReceiveData(unsigned char packetSize,
 | 
			
		||||
  Participant* sender = this->GetParticipant(senderIpAddress, senderPort);
 | 
			
		||||
  if (sender == nullptr) {
 | 
			
		||||
    sender = this->AddParticipant(senderIpAddress, senderPort);
 | 
			
		||||
#if !defined(NO_STD)
 | 
			
		||||
    std::cout << "New remote participant " << sender->ipAddress << ":"
 | 
			
		||||
              << sender->port << std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ReceiveData(packetSize, sender);
 | 
			
		||||
@ -317,9 +319,11 @@ void ParticipantUDP::ReceiveData(unsigned char bufferSize,
 | 
			
		||||
    } break;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Check if the buffer has been read completely
 | 
			
		||||
// Check if the buffer has been read completely
 | 
			
		||||
#if !defined(NO_STD)
 | 
			
		||||
  if (bufferSize > 0)
 | 
			
		||||
    std::cout << "Buffer not fully read, remaining " << (int)bufferSize << "\n";
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ParticipantUDP::Process(Participant* sender, ParticipantMsg* msg) {
 | 
			
		||||
@ -353,7 +357,8 @@ void ParticipantUDP::Process(Participant* sender, InvestigateMsg* msg) {
 | 
			
		||||
void ParticipantUDP::Process(Participant* sender, ThingMsg* msg) {
 | 
			
		||||
#if defined(DEBUG)
 | 
			
		||||
  std::cout << this->name << ": process ThingMsg [" << (int)msg->networkId
 | 
			
		||||
            << "/" << (int)msg->thingId << "] " << (int)msg->thingType << " " << (int)msg->parentId << "\n";
 | 
			
		||||
            << "/" << (int)msg->thingId << "] " << (int)msg->thingType << " "
 | 
			
		||||
            << (int)msg->parentId << "\n";
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -380,9 +385,13 @@ void ParticipantUDP::Process(Participant* sender, NameMsg* msg) {
 | 
			
		||||
    thingName[nameLength] = '\0';
 | 
			
		||||
    thing->name = thingName;
 | 
			
		||||
 | 
			
		||||
#if !defined(NO_STD)
 | 
			
		||||
    std::cout << thing->name;
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
#if !defined(NO_STD)
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ParticipantUDP::Process(Participant* sender, ModelUrlMsg* msg) {
 | 
			
		||||
@ -408,11 +417,13 @@ void ParticipantUDP::Process(Participant* sender, BinaryMsg* msg) {
 | 
			
		||||
  Thing* thing = sender->Get(msg->thingId);
 | 
			
		||||
  if (thing != nullptr)
 | 
			
		||||
    thing->ProcessBinary(msg->data);
 | 
			
		||||
#if !defined(NO_STD)
 | 
			
		||||
  else {
 | 
			
		||||
    std::cout << "  unknown thing [" << (int)msg->networkId << "/"
 | 
			
		||||
              << (int)msg->thingId << "]";
 | 
			
		||||
  }
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Receive
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user