Skip to content

Commit

Permalink
Automatically dispatch the command to the required Actuators
Browse files Browse the repository at this point in the history
  • Loading branch information
WL-Richards committed Jul 5, 2022
1 parent 284a94d commit 5cc9dd7
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 8 deletions.
46 changes: 46 additions & 0 deletions src/Actuators.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once

#include <ArduinoJson.h>

enum ACTUATOR_TYPE{
SERVO,
STEPPER
};

/**
* All actuators eg. Servos, Steppers, etc. use this to allow for max control
*/
class Actuator{
public:
Actuator(ACTUATOR_TYPE actType, int instance) {
instance_num = instance;
type = actType;
};

/**
* Called when a packet is received that needs to move the actuator
* @param json The parameters that can change
*/
virtual void control(JsonArray json) = 0;

/**
* Convert the type of actuator to a String
*/
String typeToString(){
switch(type){
case SERVO:
return "Servo";
case STEPPER:
return "Stepper";
}
};

/**
* Get the instance number of the actuator
*/
int get_instance_num() { return instance_num; };

private:
int instance_num; // Instance number of the Actuator
ACTUATOR_TYPE type; // Type of actuator
};
46 changes: 39 additions & 7 deletions src/Internet/PublishingPlatforms/Loom_Max.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ Loom_Max::~Loom_Max() {
}
//////////////////////////////////////////////////////////////////////////////////////////////////////

void Loom_Max::package(){
JsonArray tmp = manInst->getDocument()["id"].createNestedArray("ip");
IPAddress ip = wifiInst->getIPAddress();
tmp.add(ip[0]);
tmp.add(ip[1]);
tmp.add(ip[2]);
tmp.add(ip[3]);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
void Loom_Max::initialize(){

Expand All @@ -40,7 +49,6 @@ bool Loom_Max::publish(){
}

size_t size = serializeJson(manInst->getDocument(), (*udpSend));
Serial.println(size);

if(size <= 0){
printModuleName(); Serial.println("An error occurred when attempting to write the JSON packet to the UDP stream");
Expand Down Expand Up @@ -72,16 +80,40 @@ bool Loom_Max::subscribe(){
return false;
}

printModuleName(); Serial.println("Packet received from: " + Loom_WIFI::IPtoString(udpRecv->remoteIP()));
printModuleName(); Serial.println("Message Json: ");
serializeJsonPretty(messageJson, Serial);
Serial.println("\n");

// DISPATCH HERE
// If there are actuators supplied control those if not just print the packet
if(actuators.size() > 0){
if(messageJson["type"].as<String>() == "command"){
// Loop over each command being sent to the device
for(int j = 0; j < messageJson["commands"].as<JsonArray>().size(); j++){
// Loop over each actuator to find the right one
String type = messageJson["commands"][j]["module"].as<String>();
int instanceNum = messageJson["commands"][j]["params"][0].as<int>();

// Loop over each actuator
for(int i = 0; i < actuators.size(); i++){

// If the current actuator is the one we want to control
if(actuators[i]->typeToString() == type && actuators[i]->get_instance_num() == instanceNum){

// Pass the parameters field to the actuator
actuators[i]->control(messageJson["commands"][j]["params"].as<JsonArray>());
}
}
}
}
}
else{
printModuleName(); Serial.println("Packet received from: " + Loom_WIFI::IPtoString(udpRecv->remoteIP()));
printModuleName(); Serial.println("Message Json: ");
serializeJsonPretty(messageJson, Serial);
Serial.println("\n");
}

return true;
}

printModuleName(); Serial.println("No message received!");

return false;

}
Expand Down
57 changes: 56 additions & 1 deletion src/Loom_Max.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

#include "Module.h"
#include "Loom_Wifi.h"
#include "Actuators.h"

#include <Udp.h>
#include <vector>
#include <memory>

// Base ports to send and receive on
Expand All @@ -19,7 +22,7 @@ class Loom_Max : public Module{
void print_measurements() override {};
void power_up() override {};
void power_down() override {};
void package() override {};
void package() override;

public:
/// Close the socket and delete the UDP object when the unique ptr dissapears
Expand Down Expand Up @@ -54,6 +57,38 @@ class Loom_Max : public Module{
*/
Loom_Max(Manager& man, Loom_WIFI& wifi);

/**
* Construct a new instance of the the Max MSP Pub/Sub protocol
* @param man Reference to the manager
* @param wifi Reference to the Wifi manager for getting UDP communication streams
* @param firstAct The first actuator to add to the list
*/
template<typename T>
Loom_Max(Manager& man, Loom_WIFI& wifi, T firstAct) : Module("Max Pub/Sub"), manInst(&man), wifiInst(&wifi){

actuators.push_back(&firstAct);

udpSend = UDPPtr(wifiInst->getUDP());
udpRecv = UDPPtr(wifiInst->getUDP());
manInst->registerModule(this);
};

/**
* Construct a new instance of the the Max MSP Pub/Sub protocol
* @param man Reference to the manager
* @param wifi Reference to the Wifi manager for getting UDP communication streams
* @param firstAct The first actuator to add to the list
* @param additionalActuators This takes any number of actuators
*/
template<typename T, typename... Args>
Loom_Max(Manager& man, Loom_WIFI& wifi, T firstAct, Args... additionalActuators) : Module("Max Pub/Sub"), manInst(&man), wifiInst(&wifi){
get_variadic_parameters(firstAct, additionalActuators...);

udpSend = UDPPtr(wifiInst->getUDP());
udpRecv = UDPPtr(wifiInst->getUDP());
manInst->registerModule(this);
};

~Loom_Max();

private:
Expand All @@ -72,6 +107,26 @@ class Loom_Max : public Module{
void setIP(); // Set the remote IP to send the packets too

StaticJsonDocument<1000> messageJson; // Response packet

std::vector<Actuator*> actuators; // List of actuators we want to control with max


/*
* The following two functions are some sorcery to get the variadic parameters without the need for passing in a size variable
* I don't fully understand it so don't touch it just works
* Based off: https://eli.thegreenplace.net/2014/variadic-templates-in-c/
*/
template<typename T>
T get_variadic_parameters(T v) {
actuators.push_back(&v);
return v;
};

template<typename T, typename... Args>
T get_variadic_parameters(T first, Args... args) {
actuators.push_back(&first);
return get_variadic_parameters(args...);
};


};

0 comments on commit 5cc9dd7

Please sign in to comment.