Hidden participant support

This commit is contained in:
Pascal Serrarens 2025-02-28 16:03:01 +01:00
parent f2f942d084
commit 876ae441b4
7 changed files with 177 additions and 140 deletions

@ -29,9 +29,9 @@ LocalParticipant::LocalParticipant(int port) {
}
LocalParticipant::LocalParticipant(const char* ipAddress, int port) {
this->ipAddress = ipAddress; // maybe this is not needed anymore, keeping it to "0.0.0.0"
this->ipAddress = "0.0.0.0"; //ipAddress; // maybe this is not needed anymore, keeping it to "0.0.0.0"
this->port = port;
this->site = new Participant(ipAddress, port);
this->remoteSite = new Participant(ipAddress, port);
}
void LocalParticipant::begin() {
@ -68,10 +68,10 @@ void LocalParticipant::Update(unsigned long currentTimeMs) {
if (this->publishInterval > 0 && currentTimeMs > this->nextPublishMe) {
ParticipantMsg* msg = new ParticipantMsg(this->networkId);
if (this->site == nullptr)
if (this->remoteSite == nullptr)
this->Publish(msg);
else
this->Send(this->site, msg);
this->Send(this->remoteSite, msg);
delete msg;
this->nextPublishMe = currentTimeMs + this->publishInterval;

@ -34,7 +34,7 @@ class LocalParticipant : public Participant {
const char* name = "LocalParticipant";
// int localPort = 0;
Participant* site = nullptr;
Participant* remoteSite = nullptr;
#if defined(ARDUINO)
const char* remoteIpAddress = nullptr;

@ -4,13 +4,25 @@
#include <algorithm>
#include <iostream>
#include <list>
#include <chrono>
#include "LocalParticipant.h"
namespace RoboidControl {
static LocalParticipant* hiddenParticipant = nullptr;
LocalParticipant* Thing::CheckHiddenParticipant() {
if (hiddenParticipant == nullptr)
hiddenParticipant = new LocalParticipant(0);
return hiddenParticipant;
}
Thing::Thing(int thingType) : Thing(CheckHiddenParticipant(), thingType) {
}
Thing::Thing(Participant* owner, Type thingType) : Thing(owner, (unsigned char)thingType) {}
Thing::Thing(Participant* owner, unsigned char thingType) {
Thing::Thing(Participant* owner, int thingType) {
this->participant = owner;
this->id = 0;
this->type = thingType;
@ -153,6 +165,13 @@ void Thing::SetModel(const char* url) {
this->modelUrl = url;
}
unsigned long Thing::GetTimeMs() {
auto now = std::chrono::steady_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch());
return static_cast<unsigned long>(ms.count());
}
#if defined(ARDUINO)
void Thing::Update() {
Update(millis());
@ -168,6 +187,13 @@ void Thing::Update(unsigned long currentTimeMs) {
}
void Thing::UpdateThings(unsigned long currentTimeMs) {
if (hiddenParticipant == nullptr)
return;
hiddenParticipant->Update(currentTimeMs);
}
void Thing::GenerateBinary(char* buffer, unsigned char* ix) {
(void)buffer;
(void)ix;

37
Thing.h

@ -7,6 +7,7 @@
namespace RoboidControl {
class Participant;
class LocalParticipant;
#define THING_STORE_SIZE 256
// IMPORTANT: values higher than 256 will need to change the Thing::id type
@ -15,13 +16,8 @@ class Participant;
/// @brief A thing is the primitive building block
class Thing {
public:
Participant* participant; // -> owner
unsigned char networkId = 0;
/// @brief The ID of the thing
unsigned char id = 0;
/// @brief Predefined thing types
enum class Type {
enum Type {
Undetermined,
// Sensor,
Switch,
@ -38,24 +34,34 @@ class Thing {
Humanoid,
ExternalSensor,
};
/// @brief The type of Thing
unsigned char type = 0;
/// @brief Create a new thing using an implicit local participant
/// @param thingType The type of thing
Thing(int thingType = Type::Undetermined);
/// @brief Create a new thing of the given type
/// @param thingType The predefined type of thing
Thing(Participant* participant, Type thingType = Type::Undetermined);
/// @brief Create a new thing of the give type
/// @param thingType The custom type of the thing
Thing(Participant* participant, unsigned char thingType);
Thing(Participant* participant, int 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(Participant* participant,
unsigned char networkId,
unsigned char thingId,
Type thingType = Type::Undetermined);
Thing(Participant* participant, unsigned char networkId, unsigned char thingId, Type thingType = Type::Undetermined);
private:
LocalParticipant* CheckHiddenParticipant();
public:
Participant* participant; // -> owner
unsigned char networkId = 0;
/// @brief The ID of the thing
unsigned char id = 0;
/// @brief The type of Thing
unsigned char type = 0;
/// @brief Find a thing by name
/// @param name Rhe name of the thing
@ -165,13 +171,16 @@ class Thing {
/// the only official supported model format is .obj
void SetModel(const char* url);
static unsigned long GetTimeMs();
#if defined(ARDUINO)
void Update();
#endif
/// @brief Updates the state of the thing
/// @param currentTimeMs The current clock time in milliseconds
virtual void Update(unsigned long currentTimeMs); // { (void)currentTimeMs; };
virtual void Update(unsigned long currentTimeMs); // { (void)currentTimeMs; };
static void UpdateThings(unsigned long currentTimeMs);
/// @brief Function used to generate binary data for this thing
/// @param buffer The byte array for thw binary data

114
test/participant_test.cc Normal file

@ -0,0 +1,114 @@
#if GTEST
// #include <gmock/gmock.h>
// not supported using Visual Studio 2022 compiler...
#include <gtest/gtest.h>
#include <chrono>
#include <thread>
// #include <ws2tcpip.h>
#include "Participant.h"
#include "SiteServer.h"
#include "Thing.h"
using namespace RoboidControl;
// Function to get the current time in milliseconds as unsigned long
unsigned long get_time_ms() {
auto now = std::chrono::steady_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch());
return static_cast<unsigned long>(ms.count());
}
// class RoboidControlSuite : public ::testing::test {
// TEST_F(RoboidControlSuite, HiddenParticipant) {
// Thing thing = Thing();
// unsigned long milliseconds = get_time_ms();
// unsigned long startTime = milliseconds;
// while (milliseconds < startTime + 1000) {
// Thing.Update(milliseconds);
// milliseconds = get_time_ms();
// }
// ASSERT_EQ(1, 1);
// }
// }
class ParticipantSuite : public ::testing::Test {
protected:
// SetUp and TearDown can be used to set up and clean up before/after each
// test
void SetUp() override {
// Initialize test data here
}
void TearDown() override {
// Clean up test data here
}
};
TEST_F(ParticipantSuite, LocalParticipant) {
LocalParticipant* participant = new LocalParticipant("127.0.0.1", 7681);
unsigned long milliseconds = get_time_ms();
unsigned long startTime = milliseconds;
while (milliseconds < startTime + 1000) {
participant->Update(milliseconds);
milliseconds = get_time_ms();
}
ASSERT_EQ(1, 1);
}
TEST_F(ParticipantSuite, SiteServer) {
SiteServer site = SiteServer(7681);
unsigned long milliseconds = get_time_ms();
unsigned long startTime = milliseconds;
while (milliseconds < startTime + 1000) {
site.Update(milliseconds);
milliseconds = get_time_ms();
}
ASSERT_EQ(1, 1);
}
TEST_F(ParticipantSuite, SiteParticipant) {
SiteServer site = SiteServer(7681);
LocalParticipant participant = LocalParticipant("127.0.0.1", 7681);
unsigned long milliseconds = get_time_ms();
unsigned long startTime = milliseconds;
while (milliseconds < startTime + 1000) {
site.Update(milliseconds);
participant.Update(milliseconds);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
milliseconds = get_time_ms();
}
ASSERT_EQ(1, 1);
}
TEST_F(ParticipantSuite, Thing) {
SiteServer site = SiteServer(7681);
LocalParticipant participant = LocalParticipant("127.0.0.1", 7681);
Thing thing = Thing(&participant);
unsigned long milliseconds = get_time_ms();
unsigned long startTime = milliseconds;
while (milliseconds < startTime + 1000) {
site.Update(milliseconds);
participant.Update(milliseconds);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
milliseconds = get_time_ms();
}
ASSERT_EQ(1, 1);
}
#endif

@ -1,43 +0,0 @@
#if GTEST
// #include <gmock/gmock.h>
// not supported using Visual Studio 2022 compiler...
#include <gtest/gtest.h>
#include <chrono>
#include "Participant.h"
#include "Thing.h"
using namespace RoboidControl;
class ControlCoreSuite2 : public ::testing::Test {
protected:
// SetUp and TearDown can be used to set up and clean up before/after each
// test
void SetUp() override {
// Initialize test data here
}
void TearDown() override {
// Clean up test data here
}
};
TEST_F(ControlCoreSuite2, Dummytest2) {
LocalParticipant participant = LocalParticipant("127.0.0.1", 7681);
ASSERT_EQ(1, 1);
}
TEST_F(ControlCoreSuite2, Basic2) {
// Thing t = Thing();
// unsigned long milliseconds = (unsigned long)std::chrono::steady_clock::now()
// .time_since_epoch()
// .count();
// // Thing::UpdateAll(milliseconds);
// t.Update(milliseconds);
}
#endif

@ -4,94 +4,25 @@
// not supported using Visual Studio 2022 compiler...
#include <gtest/gtest.h>
#include <chrono>
#include <thread>
// #include <ws2tcpip.h>
// #include <chrono>
// #include <thread>
#include "Participant.h"
#include "SiteServer.h"
#include "Thing.h"
using namespace RoboidControl;
// Function to get the current time in milliseconds as unsigned long
unsigned long get_time_ms() {
auto now = std::chrono::steady_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch());
return static_cast<unsigned long>(ms.count());
}
TEST(RoboidControlSuite, LocalParticipant) {
Thing* thing = new Thing();
class ControlCoreSuite : public ::testing::Test {
protected:
// SetUp and TearDown can be used to set up and clean up before/after each
// test
void SetUp() override {
// Initialize test data here
}
void TearDown() override {
// Clean up test data here
}
};
TEST_F(ControlCoreSuite, LocalParticipant) {
LocalParticipant participant = LocalParticipant("127.0.0.1", 7681);
unsigned long milliseconds = get_time_ms();
unsigned long milliseconds = Thing::GetTimeMs();
unsigned long startTime = milliseconds;
while (milliseconds < startTime + 1000) {
participant.Update(milliseconds);
Thing::UpdateThings(milliseconds);
milliseconds = get_time_ms();
milliseconds = Thing::GetTimeMs();
}
ASSERT_EQ(1, 1);
SUCCEED();
}
TEST_F(ControlCoreSuite, SiteServer) {
SiteServer site = SiteServer(7681);
unsigned long milliseconds = get_time_ms();
unsigned long startTime = milliseconds;
while (milliseconds < startTime + 1000) {
site.Update(milliseconds);
milliseconds = get_time_ms();
}
ASSERT_EQ(1, 1);
}
TEST_F(ControlCoreSuite, SiteParticipant) {
SiteServer site = SiteServer(7681);
LocalParticipant participant = LocalParticipant("127.0.0.1", 7681);
unsigned long milliseconds = get_time_ms();
unsigned long startTime = milliseconds;
while (milliseconds < startTime + 1000) {
site.Update(milliseconds);
participant.Update(milliseconds);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
milliseconds = get_time_ms();
}
ASSERT_EQ(1, 1);
}
TEST_F(ControlCoreSuite, Thing) {
SiteServer site = SiteServer(7681);
LocalParticipant participant = LocalParticipant("127.0.0.1", 7681);
Thing thing = Thing(&participant);
unsigned long milliseconds = get_time_ms();
unsigned long startTime = milliseconds;
while (milliseconds < startTime + 1000) {
site.Update(milliseconds);
participant.Update(milliseconds);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
milliseconds = get_time_ms();
}
ASSERT_EQ(1, 1);
}
#endif