basic implementation of client/server for AERPAW, whole lot of mess included

This commit is contained in:
2026-01-28 22:29:17 -08:00
parent b444e44d33
commit 8c5c315380
101 changed files with 1129 additions and 36 deletions

View File

@@ -0,0 +1,30 @@
function obj = initialize(obj, initsPath)
arguments (Input)
obj (1, 1) {mustBeA(obj, 'scenario')};
initsPath (1, 1) string;
end
arguments (Output)
obj (1, 1) {mustBeA(obj, 'scenario')};
end
obj.inits = load(initsPath);
% Instantiate the correct number of UAVs
obj.uavs = cell(obj.inits.numAgents, 1);
[obj.uavs{:}] = deal(uav);
% Configure ports to broadcast to drones
obj.ports = repmat(obj.basePort, [obj.inits.numAgents, 1]) + (1:obj.inits.numAgents)';
obj.udp = cell(obj.inits.numAgents, 1);
for ii = 1:obj.inits.numAgents
obj.udp{ii} = udpport("IPV4", "LocalPort", obj.ports(ii), "Tag", sprintf("UAV %d", ii), "Timeout", obj.timeout);
end
% Initialize UAVs in scenario's knowledge
for ii = 1:obj.inits.numAgents
obj.uavs{ii} = obj.uavs{ii}.initialize(obj.ports(ii) + obj.portOffset, obj.timeout, sprintf("UAV %d", ii));
end
% Update opMode
obj.opMode = OPMODE.INITIALIZED;
end

73
aerpaw/@scenario/run.m Normal file
View File

@@ -0,0 +1,73 @@
function obj = run(obj)
arguments (Input)
obj (1, 1) {mustBeA(obj, 'scenario')};
end
arguments (Output)
obj (1, 1) {mustBeA(obj, 'scenario')};
end
count = 0;
while true
%% UAV operations (simulated only)
if coder.target("MATLAB")
% Iterate over UAVs
for ii = 1:size(obj.uavs, 1)
% Determine behavior from UAV opMode
if obj.uavs{ii}.opMode == OPMODE.INVALID
error("Invalid UAV opMode");
elseif obj.uavs{ii}.opMode == OPMODE.INITIALIZED
% Waiting for starting position to be sent by the controller
if all(~(isnan(obj.uavs{ii}.commandPos)))
% Teleport to starting position
obj.uavs{ii}.pos = obj.uavs{ii}.commandPos;
% reset to no command
obj.uavs{ii}.commandPos = NaN(1, 3);
% Acknowledge command receipt to controller by reporting a new opMode
obj.uavs{ii}.commandOpMode = OPMODE.SET;
end
else
error("Unexpected UAV opMode");
end
end
elseif coder.target("C++")
coder.cinclude('udp_comm.h');
% Iterate over UAVs
for ii = 1:size(obj.uavs, 1)
mode = uint8(0);
coder.ceval('recvOpMode', coder.wref(mode));
end
end
%% Server operations
% Compute guidance for UAVs and issue commands
if obj.opMode == OPMODE.INVALID
error("Invalid controller opMode");
elseif obj.opMode == OPMODE.INITIALIZED
% On the first iteration, command UAVs to go to their starting positions
commandPos = obj.inits.pos;
elseif obj.opMode == OPMODE.SET
% begin experiment once the controller and UAVs are ready
if unique(cellfun(@(x) x.opMode.id, obj.uavs)) == OPMODE.SET.id
keyboard
end
else
error("Unexpected controller opMode");
end
% Transmit commands
% Command drones to their starting positions
for ii = 1:size(obj.uavs, 1)
obj.uavs{ii} = obj.sendTarget(obj.uavs{ii}, commandPos(ii, 1:3));
end
keyboard
% tally iterations
count = count + 1;
end
end

View File

@@ -0,0 +1,28 @@
classdef scenario
properties (Access = public)
% Experiment
domain = rectangularPrism;
inits;
% State
opMode = OPMODE.INVALID;
% UAVs
uavs;
% Communications
timeout = 2; % seconds
basePort = 3330;
portOffset = 1110;
ports;
udp;
end
methods(Access = public)
[obj] = initialize(obj, initsPath);
[obj] = run(obj);
[obj] = setup(obj);
u = sendTarget(u, pos);
end
end

View File

@@ -0,0 +1,24 @@
function u = sendTarget(~, u, pos)
arguments (Input)
~
u (1, 1) {mustBeA(u, 'uav')};
pos (1, 3) double;
end
arguments (Output)
u (1, 1) {mustBeA(u, 'uav')};
end
% Branch here depending on environment
if coder.target("MATLAB")
% Simulation - update target position
u.commandPos = pos;
elseif coder.target("C++")
% Codegen - TX starting position to UAV
coder.cinclude("udp_comm.h");
coder.ceval("sendTarget", coder.rref(pos));
end
end

17
aerpaw/@scenario/setup.m Normal file
View File

@@ -0,0 +1,17 @@
function obj = setup(obj)
arguments (Input)
obj (1, 1) {mustBeA(obj, 'scenario')};
end
arguments (Output)
obj (1, 1) {mustBeA(obj, 'scenario')};
end
% Command drones to their starting positions
for ii = 1:size(obj.uavs, 1)
obj.uavs{ii} = obj.sendTarget(obj.uavs{ii}, obj.inits.pos(ii, 1:3));
end
% Update opMode
obj.opMode = OPMODE.SET;
end

27
aerpaw/@uav/initialize.m Normal file
View File

@@ -0,0 +1,27 @@
function obj = initialize(obj, port, timeout, label)
arguments (Input)
obj (1, 1) {mustBeA(obj, "uav")};
port (1, 1) double;
timeout (1, 1) double;
label (1, 1) string;
end
arguments (Output)
obj (1, 1) {mustBeA(obj, "uav")};
end
obj.label = label;
obj.port = port;
obj.timeout = timeout;
% Branch here depending on environment
if coder.target("MATLAB")
obj.pos = [0, 0, 20] + rand(1, 3) * 10; % just put it somewhere so we can plot it
elseif coder.target("C++")
% initialize ip/port
coder.cinclude('udp_comm.h');
coder.ceval('initComs', "ip", obj.port);
end
obj.opMode = OPMODE.INITIALIZED;
end

20
aerpaw/@uav/onYourMarks.m Normal file
View File

@@ -0,0 +1,20 @@
function obj = onYourMarks(obj)
arguments (Input)
obj (1, 1) {mustBeA(obj, "uav")};
end
arguments (Output)
obj (1, 1) {mustBeA(obj, "uav")};
end
% Receive initial position data
initialPosition = read(obj.udp, 3, "double");
% Acknowledge message receipt
% teleport to desired position
obj.pos = initialPosition;
keyboard
end

22
aerpaw/@uav/uav.m Normal file
View File

@@ -0,0 +1,22 @@
classdef uav
properties
label = "";
% Communications
port;
timeout;
% State
opMode = OPMODE.INVALID;
pos = NaN(1, 3);
% Commanding (not for codegen)
commandOpMode = OPMODE.INVALID;
commandPos = NaN(1, 3);
end
methods (Access = public)
obj = initialize(obj, port, timeout, label)
obj = onYourMarks(obj);
end
end

10
aerpaw/OPMODE.m Normal file
View File

@@ -0,0 +1,10 @@
classdef OPMODE
properties (Constant)
INVALID = uint8(0);
INITIALIZED = uint8(1);
SET = uint8(2);
RUNNING = uint8(3);
CONCLUDING = uint8(4);
FINISHED = uint8(5);
end
end

View File

@@ -0,0 +1,83 @@
#include <iostream>
#include <thread>
#include <vector>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_PORT 5000
#define SERVER_IP "127.0.0.1"
// Socket init
void initSockets() {}
void cleanupSockets() {}
int serverSocket = -1;
std::vector<int> clientSockets;
extern "C" {
// Initialize server (call once)
void initServer() {
initSockets();
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if(serverSocket < 0) { std::cerr << "Socket creation failed\n"; return; }
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(SERVER_PORT);
int opt = 1;
setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt));
if(bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
std::cerr << "Bind failed\n"; return;
}
if(listen(serverSocket, 5) < 0) {
std::cerr << "Listen failed\n"; return;
}
std::cout << "Server initialized, waiting for clients...\n";
}
// Accept client connections (call once per client)
void acceptClient(int clientId) {
sockaddr_in clientAddr;
socklen_t addrLen = sizeof(clientAddr);
int clientSock = accept(serverSocket, (sockaddr*)&clientAddr, &addrLen);
if(clientSock < 0) { std::cerr << "Accept failed for client " << clientId << "\n"; return; }
clientSockets.push_back(clientSock);
std::cout << "Client " << clientId << " connected\n";
}
// Send a message to a specific client
void sendMessage(int clientId) {
if(clientId <= 0 || clientId > clientSockets.size()) return;
const char* msg = "Hello from server";
send(clientSockets[clientId-1], msg, strlen(msg), 0);
std::cout << "Sent message to client " << clientId << "\n";
}
// Receive ACK from a specific client
int receiveAck(int clientId) {
if(clientId <= 0 || clientId > clientSockets.size()) return 0;
char buffer[1024];
int len = recv(clientSockets[clientId-1], buffer, sizeof(buffer)-1, 0);
if(len <= 0) return 0;
buffer[len] = '\0';
std::cout << "Received ACK from client " << clientId << ": " << buffer << "\n";
return 1;
}
// Cleanup server
void closeServer() {
for(auto sock : clientSockets) {
close(sock);
}
close(serverSocket);
cleanupSockets();
}
}

View File

@@ -0,0 +1,37 @@
//
// Academic License - for use in teaching, academic research, and meeting
// course requirements at degree granting institutions only. Not for
// government, commercial, or other organizational use.
//
// controller.cpp
//
// Code generation for function 'controller'
//
// Include files
#include "controller.h"
#include "controller_impl.h"
// Function Definitions
void controller(int numClients)
{
// Initialize server
initServer();
// Accept clients
for (int i{0}; i < numClients; i++) {
acceptClient(i + 1);
}
// Send messages to clients
for (int i{0}; i < numClients; i++) {
sendMessage(i + 1);
}
// Receive acknowledgements
for (int i{0}; i < numClients; i++) {
receiveAck(i + 1);
}
// Digest ACKs
// Close server
closeServer();
}
// End of code generation (controller.cpp)

View File

@@ -0,0 +1,23 @@
//
// Academic License - for use in teaching, academic research, and meeting
// course requirements at degree granting institutions only. Not for
// government, commercial, or other organizational use.
//
// controller.h
//
// Code generation for function 'controller'
//
#ifndef CONTROLLER_H
#define CONTROLLER_H
// Include files
#include "rtwtypes.h"
#include <cstddef>
#include <cstdlib>
// Function Declarations
extern void controller(int numClients);
#endif
// End of code generation (controller.h)

BIN
aerpaw/basic_demo/controller_app Executable file

Binary file not shown.

View File

@@ -0,0 +1,73 @@
#include "controller_impl.h"
#include <iostream>
#include <vector>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_PORT 5000
#define SERVER_IP "127.0.0.1"
static int serverSocket = -1;
static std::vector<int> clientSockets;
void initSockets() {}
void cleanupSockets() {}
void initServer() {
initSockets();
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if(serverSocket < 0) { std::cerr << "Socket creation failed\n"; return; }
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(SERVER_PORT);
int opt = 1;
setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt));
if(bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
std::cerr << "Bind failed\n"; return;
}
if(listen(serverSocket, 5) < 0) {
std::cerr << "Listen failed\n"; return;
}
std::cout << "Server initialized\n";
}
void acceptClient(int clientId) {
sockaddr_in clientAddr;
socklen_t addrLen = sizeof(clientAddr);
int clientSock = accept(serverSocket, (sockaddr*)&clientAddr, &addrLen);
if(clientSock < 0) { std::cerr << "Accept failed for client " << clientId << "\n"; return; }
clientSockets.push_back(clientSock);
std::cout << "Client " << clientId << " connected\n";
}
void sendMessage(int clientId) {
if(clientId <= 0 || clientId > clientSockets.size()) return;
const char* msg = "Hello from server";
send(clientSockets[clientId-1], msg, strlen(msg), 0);
std::cout << "Sent message to client " << clientId << "\n";
}
int receiveAck(int clientId) {
if(clientId <= 0 || clientId > clientSockets.size()) return 0;
char buffer[1024];
int len = recv(clientSockets[clientId-1], buffer, sizeof(buffer)-1, 0);
if(len <= 0) return 0;
buffer[len] = '\0';
std::cout << "Received ACK from client " << clientId << ": " << buffer << "\n";
return 1;
}
void closeServer() {
for(auto sock : clientSockets) {
close(sock);
}
close(serverSocket);
cleanupSockets();
}

View File

@@ -0,0 +1,18 @@
#ifndef CONTROLLER_IMPL_H
#define CONTROLLER_IMPL_H
#ifdef __cplusplus
extern "C" {
#endif
void initServer();
void acceptClient(int clientId);
void sendMessage(int clientId);
int receiveAck(int clientId);
void closeServer();
#ifdef __cplusplus
}
#endif
#endif // CONTROLLER_IMPL_H

View File

@@ -0,0 +1,16 @@
#include <iostream>
#include "controller.h" // Generated by MATLAB Coder
#include "controller_impl.h" // Your TCP implementation header
int main() {
// Number of clients to handle
int numClients = 2; // Example: change as needed
std::cout << "Initializing TCP server...\n";
// Call MATLAB-generated server function
controller(numClients);
std::cout << "Server finished.\n";
return 0;
}

View File

@@ -0,0 +1,44 @@
//
// Academic License - for use in teaching, academic research, and meeting
// course requirements at degree granting institutions only. Not for
// government, commercial, or other organizational use.
//
// rtwtypes.h
//
// Code generation for function 'controller'
//
#ifndef RTWTYPES_H
#define RTWTYPES_H
/*=======================================================================*
* Fixed width word size data types: *
* int64_T - signed 64 bit integers *
* uint64_T - unsigned 64 bit integers *
*=======================================================================*/
#if defined(__APPLE__)
#ifndef INT64_T
#define INT64_T long
#define FMT64 "l"
#if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG)
#define INT_TYPE_64_IS_LONG
#endif
#endif
#endif
#if defined(__APPLE__)
#ifndef UINT64_T
#define UINT64_T unsigned long
#define FMT64 "l"
#if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG)
#define INT_TYPE_64_IS_LONG
#endif
#endif
#endif
// Include files
#include "tmwtypes.h"
#endif
// End of code generation (rtwtypes.h)

13
aerpaw/basic_demo/uav.py Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/python3
import socket
SERVER_IP = "127.0.0.1"
SERVER_PORT = 5000
for client_id in range(2): # match numClients
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((SERVER_IP, SERVER_PORT))
data = s.recv(1024) # receive message from server
print(f"Client {client_id+1} received: {data.decode()}")
s.sendall(b"ACK") # send acknowledgment
s.close()

190
aerpaw/controller.coderprj Normal file
View File

@@ -0,0 +1,190 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<coderProject client="MatlabCoder" containerVersion="1" createdBy="R2025a" modifiedBy="R2025a">
<layers>
<layer id="core" version="R2025a">
<parts>
<part role="testRepository">
<MF0 packageUris="http://schema.mathworks.com/mf0/coderapp_core_proj_dm/R2025a http://schema.mathworks.com/mf0/coderapp_core_rt_dm/R2022b http://schema.mathworks.com/mf0/coderapp_matlabcoder_proj_dm/R2025a http://schema.mathworks.com/mf0/coderapp_matlabcoder_rt_dm/R2022b http://schema.mathworks.com/mf0/coderapp_types_project_datamodel/R2025a http://schema.mathworks.com/mf0/coderapp_types_runtime_datamodel/R2022b" version="1.1">
<coderapp.internal.core.mfz.TestRepositoryState id="1" type="coderapp.internal.core.mfz.TestRepositoryState"/>
</MF0>
</part>
</parts>
</layer>
<layer id="interface" version="R2025a">
<parts>
<part role="mainInterface">
<MF0 packageUris="http://schema.mathworks.com/mf0/coderapp_config_datamodel/R2021a.001 http://schema.mathworks.com/mf0/coderapp_core_proj_dm/R2025a http://schema.mathworks.com/mf0/coderapp_core_rt_dm/R2022b http://schema.mathworks.com/mf0/coderapp_form_datamodel/R2020a http://schema.mathworks.com/mf0/coderapp_matlabcoder_proj_dm/R2025a http://schema.mathworks.com/mf0/coderapp_matlabcoder_rt_dm/R2022b http://schema.mathworks.com/mf0/coderapp_types_project_datamodel/R2025a http://schema.mathworks.com/mf0/coderapp_types_runtime_datamodel/R2022b http://schema.mathworks.com/mf0/coderapp_utils_datamodel/R2020a" version="1.1">
<coderapp.internal.interface.project.Interface id="1" type="coderapp.internal.interface.project.Interface">
<EntryPoints id="2" type="coderapp.internal.interface.project.EntryPointFunction">
<Signatures id="3" type="coderapp.internal.interface.project.FunctionSignature">
<Inputs id="4" type="coderapp.internal.interface.project.Input">
<IsUserSpecified>false</IsUserSpecified>
<Name>numClients</Name>
<Type id="5" type="coderapp.internal.codertype.PrimitiveType"/>
</Inputs>
</Signatures>
<UseProgrammaticTypes>true</UseProgrammaticTypes>
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>controller.m</Path>
</File>
<Name>controller</Name>
</EntryPoints>
<SizeConstraints id="6" type="coderapp.internal.interface.project.SizeConstraints">
<Value type="coderapp.internal.interface.project.SizeConstraintsValue"/>
</SizeConstraints>
<Types id="7" type="coderapp.internal.codertype.TypeStore">
<Types id="5" type="coderapp.internal.codertype.PrimitiveType">
<ClassName>int32</ClassName>
<Size type="coderapp.internal.codertype.Dimension"/>
<Size type="coderapp.internal.codertype.Dimension"/>
</Types>
</Types>
</coderapp.internal.interface.project.Interface>
</MF0>
</part>
</parts>
</layer>
<layer id="matlabCoder" version="R2025a">
<parts>
<part role="matlabCoder">
<MF0 packageUris="http://schema.mathworks.com/mf0/coderapp_config_datamodel/R2021a.001 http://schema.mathworks.com/mf0/coderapp_core_proj_dm/R2025a http://schema.mathworks.com/mf0/coderapp_core_rt_dm/R2022b http://schema.mathworks.com/mf0/coderapp_form_datamodel/R2020a http://schema.mathworks.com/mf0/coderapp_matlabcoder_proj_dm/R2025a http://schema.mathworks.com/mf0/coderapp_matlabcoder_rt_dm/R2022b http://schema.mathworks.com/mf0/coderapp_types_project_datamodel/R2025a http://schema.mathworks.com/mf0/coderapp_types_runtime_datamodel/R2022b http://schema.mathworks.com/mf0/coderapp_utils_datamodel/R2020a" version="1.1">
<coderapp.internal.mlc.mfz.MatlabCoderProjectState id="1" type="coderapp.internal.mlc.mfz.MatlabCoderProjectState">
<Activity id="2" type="coderapp.internal.mlc.mfz.MainBuildActivity">
<Compile>NOT_PLANNED</Compile>
<Generate>SUCCESS</Generate>
<TargetHardware>MATLAB Host Computer</TargetHardware>
<TargetLanguage>C++</TargetLanguage>
<WorkflowTarget>LIB</WorkflowTarget>
<Result id="3" type="coderapp.internal.mlc.mfz.MatlabCoderCodegenResult"/>
</Activity>
<MainBuildResult id="3" type="coderapp.internal.mlc.mfz.MatlabCoderCodegenResult">
<WorkflowTarget>LIB</WorkflowTarget>
<LogDirectory>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller</LogDirectory>
<MainReport id="4" type="coderapp.internal.build.mfz.CodegenArtifact"/>
<Artifacts id="4" type="coderapp.internal.build.mfz.CodegenArtifact">
<SubType>CODEGEN_REPORT</SubType>
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/html/report.mldatx</Path>
</File>
<Type>CODEGEN_REPORT</Type>
</Artifacts>
<Artifacts id="5" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/controller.cpp</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="6" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/controller.h</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="7" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/controller_data.h</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="8" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/controller_impl.h</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="9" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/controller_initialize.cpp</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="10" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/controller_initialize.h</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="11" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/controller_terminate.cpp</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="12" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/controller_terminate.h</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="13" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/controller_types.h</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="14" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/rtwtypes.h</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="15" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/comms.cpp</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="16" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/matlab/R2025a/extern/include/tmwtypes.h</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="17" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/examples/main.cpp</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<Artifacts id="18" type="coderapp.internal.build.mfz.CodegenArtifact">
<File type="coderapp.internal.util.mfz.FileSpec">
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lib/controller/examples/main.h</Path>
</File>
<Type>GENERATED_SOURCE</Type>
</Artifacts>
<BuildFolder type="coderapp.internal.util.mfz.FileSpec"/>
<Success>true</Success>
<Timestamp>2026-01-28T21:28:33</Timestamp>
</MainBuildResult>
</coderapp.internal.mlc.mfz.MatlabCoderProjectState>
</MF0>
</part>
<part role="standaloneConfig">
<MF0 packageUris="http://schema.mathworks.com/mf0/coderapp_config_datamodel/R2021a.001 http://schema.mathworks.com/mf0/coderapp_core_proj_dm/R2025a http://schema.mathworks.com/mf0/coderapp_core_rt_dm/R2022b http://schema.mathworks.com/mf0/coderapp_form_datamodel/R2020a http://schema.mathworks.com/mf0/coderapp_matlabcoder_proj_dm/R2025a http://schema.mathworks.com/mf0/coderapp_matlabcoder_rt_dm/R2022b http://schema.mathworks.com/mf0/coderapp_types_project_datamodel/R2025a http://schema.mathworks.com/mf0/coderapp_types_runtime_datamodel/R2022b http://schema.mathworks.com/mf0/coderapp_utils_datamodel/R2020a" version="1.1">
<coderapp.internal.ext.ConfigStore id="1" type="coderapp.internal.ext.ConfigStore">
<Values id="2" type="coderapp.internal.ext.ConfigEntry">
<Key>customSource</Key>
<Data id="3" type="coderapp.internal.config.data.FileArrayParamData">
<Value>/home/kdee/Desktop/miSim/aerpaw/comms.cpp</Value>
<Help type="coderapp.internal.util.DocRef"/>
</Data>
</Values>
<Values id="4" type="coderapp.internal.ext.ConfigEntry">
<Key>targetLang</Key>
<Data id="5" type="coderapp.internal.config.data.EnumParamData">
<Value>C++</Value>
<Help type="coderapp.internal.util.DocRef"/>
</Data>
</Values>
</coderapp.internal.ext.ConfigStore>
</MF0>
</part>
<part role="mexConfig">
<MF0 packageUris="http://schema.mathworks.com/mf0/coderapp_config_datamodel/R2021a.001 http://schema.mathworks.com/mf0/coderapp_core_proj_dm/R2025a http://schema.mathworks.com/mf0/coderapp_core_rt_dm/R2022b http://schema.mathworks.com/mf0/coderapp_form_datamodel/R2020a http://schema.mathworks.com/mf0/coderapp_matlabcoder_proj_dm/R2025a http://schema.mathworks.com/mf0/coderapp_matlabcoder_rt_dm/R2022b http://schema.mathworks.com/mf0/coderapp_types_project_datamodel/R2025a http://schema.mathworks.com/mf0/coderapp_types_runtime_datamodel/R2022b http://schema.mathworks.com/mf0/coderapp_utils_datamodel/R2020a" version="1.1">
<coderapp.internal.ext.ConfigStore id="1" type="coderapp.internal.ext.ConfigStore"/>
</MF0>
</part>
</parts>
</layer>
</layers>
</coderProject>

59
aerpaw/controller.m Normal file
View File

@@ -0,0 +1,59 @@
function controller(numClients)
arguments (Input)
numClients (1, 1) int32;
end
coder.extrinsic('disp');
% Initialize server
if coder.target('MATLAB')
disp('Initializing server (simulation)...');
else
coder.cinclude('controller_impl.h');
coder.ceval('initServer');
end
% Accept clients
for i = 1:numClients
if coder.target('MATLAB')
disp(['Accepting client ', num2str(i)]);
else
coder.ceval('acceptClient', int32(i));
end
end
% Send messages to clients
for i = 1:numClients
if coder.target('MATLAB')
disp(['Sending message to client ', num2str(i)]);
else
coder.ceval('sendMessage', int32(i));
end
end
% Receive acknowledgements
acksReceived = zeros(1, numClients, 'int32');
for i = 1:numClients
if coder.target('MATLAB')
disp(['Receiving ACK from client ', num2str(i)]);
acksReceived(i) = 1; % Simulate successful ACK
else
acksReceived(i) = coder.ceval('receiveAck', int32(i));
end
end
% Digest ACKs
if coder.target('MATLAB')
disp(['All ACKs received: ', num2str(acksReceived)]);
end
% Close server
if ~coder.target('MATLAB')
coder.ceval('closeServer');
end
end

32
aerpaw/cpp/udp_comm.cpp Normal file
View File

@@ -0,0 +1,32 @@
#include "udp_comm.h"
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cstring>
static int sock = -1;
static sockaddr_in remote_addr;
void initComms(const char* ip, uint16_t port)
{
if (sock != -1) return;
sock = socket(AF_INET, SOCK_DGRAM, 0);
memset(&remote_addr, 0, sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(port);
inet_pton(AF_INET, ip, &remote_addr.sin_addr);
}
void sendTarget(const double* pos)
{
sendto(sock, pos, 3*sizeof(double), 0,
(sockaddr*)&remote_addr, sizeof(remote_addr));
}
void recvOpMode(uint8_t* mode)
{
recvfrom(sock, mode, sizeof(uint8_t), MSG_DONTWAIT,
nullptr, nullptr);
}

15
aerpaw/cpp/udp_comm.h Normal file
View File

@@ -0,0 +1,15 @@
#ifndef UDP_COMM_H
#define UDP_COMM_H
#ifdef __cplusplus
extern "C" {
#endif
void initComms(const char* ip, uint16_t port);
void sendTarget(const double* pos);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,3 +0,0 @@
classdef experiment
end

16
aerpaw/experiments.m Normal file
View File

@@ -0,0 +1,16 @@
classdef experiments < matlab.unittest.TestCase
methods (Test)
function Test1(tc)
s = scenario;
% TODO - define test case in simulation in here and generate the inits on the fly as needed
s = s.initialize("2026_01_28_16_11_39_miSimInits.mat");
s = s.run();
end
end
end