Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions IGGLU-VSSS/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
find_package(Qt6 REQUIRED COMPONENTS WebSockets)
find_package(msgpack REQUIRED)


set(PROJECT_SOURCES
main.cpp
Expand Down Expand Up @@ -47,6 +49,12 @@ else()
endif()
endif()

target_link_libraries(IGGLU-VSSS
PRIVATE Qt6::WebSockets
PRIVATE Qt6::Core
PRIVATE msgpackc
)

target_link_libraries(IGGLU-VSSS PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
target_link_libraries(IGGLU-VSSS PUBLIC Qt${QT_VERSION_MAJOR}::WebSockets)

Expand Down
76 changes: 72 additions & 4 deletions IGGLU-VSSS/serverIgglu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
#include <QtWebSockets/QtWebSockets>
#include <QtCore>
#include <cstdio>
#include <QDataStream>
#include <QByteArray>
#include <msgpack.hpp>
#include <map>
#include <string>

using namespace std;

QT_USE_NAMESPACE
Expand Down Expand Up @@ -36,8 +42,7 @@ void ServerIgglu::closeWebSocket() {
}

void ServerIgglu::onConnected() {

connect(&m_webSocket, &QWebSocket::textMessageReceived,
connect(&m_webSocket, &QWebSocket::binaryMessageReceived,
this, &ServerIgglu::processMessage);
}

Expand All @@ -46,10 +51,73 @@ void ServerIgglu::closed() {
qDebug() << "closed";
}

void ServerIgglu::processMessage(const QString &message)
void ServerIgglu::processMessage(const QByteArray &message)
{
QTextStream(stdout) << message;
// Recebendo a mensagem binária empacotada do MessagePack
std::string msg_data(message.constData(), message.size());

try {
// Desempacotando a mensagem
msgpack::object_handle oh = msgpack::unpack(msg_data.data(), msg_data.size());
msgpack::object obj = oh.get();

// Converta o objeto para um dicionário (std::map em C++)
std::map<std::string, msgpack::object> received_dict;
obj.convert(received_dict);

// Iterando sobre os elementos do dicionário e imprimindo com qDebug()
for (const auto& pair : received_dict) {
QTextStream(stdout) << "Key: " << QString::fromStdString(pair.first) << "- Value: ";

// Verifica o tipo do valor
if (pair.second.type == msgpack::type::ARRAY) {
// Se o valor é um array, iteramos sobre os elementos
std::vector<msgpack::object> array_values;
pair.second.convert(array_values);
for (const auto& element : array_values) {
if (element.type == msgpack::type::FLOAT) {
float float_value;
element.convert(float_value);
QTextStream(stdout) << float_value << ' '; // Imprime valor float
} else {
QTextStream(stdout) << "Unsupported array element type"; // Caso de tipo não suportado no array
}
}
QTextStream(stdout) << "\n";
} else if (pair.second.type == msgpack::type::MAP) {
// Se o valor é um dicionário, convertemos para um map
std::map<std::string, msgpack::object> inner_dict;
pair.second.convert(inner_dict);
for (const auto& inner_pair : inner_dict) {
QTextStream(stdout) << "Inner Key: " << QString::fromStdString(inner_pair.first) << "- Inner Value: ";

// Verifica o tipo do valor no dicionário interno
if (inner_pair.second.type == msgpack::type::ARRAY) {
std::vector<msgpack::object> inner_array_values;
inner_pair.second.convert(inner_array_values);
for (const auto& element : inner_array_values) {
if (element.type == msgpack::type::FLOAT) {
float float_value;
element.convert(float_value);
QTextStream(stdout) << float_value; // Imprime valor float
} else {
QTextStream(stdout) << "Unsupported inner array element type"; // Caso de tipo não suportado
}
}
} else {
QTextStream(stdout) << "Unsupported type in inner dictionary"; // Caso de tipo não suportado no dicionário
}
}
QTextStream(stdout) << "\n";
} else {
QTextStream(stdout) << "Unsupported type"; // Caso de tipo não suportado
}
}
} catch (const std::exception& e) {
qDebug() << "Error unpacking message:" << e.what();
}
}

void ServerIgglu::sendMessage() {
m_webSocket.sendTextMessage("message");
}
3 changes: 2 additions & 1 deletion IGGLU-VSSS/serverIgglu.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <QObject>
#include <QtCore/QList>
#include <QtWebSockets/QWebSocket>
#include <QByteArray>

class ServerIgglu : public QObject
{
Expand All @@ -19,7 +20,7 @@ class ServerIgglu : public QObject
private slots:
void onConnected();
void closed();
void processMessage(const QString &message);
void processMessage(const QByteArray &message);
void onDisconnected(){
qDebug() << "Disconnected";
}
Expand Down
113 changes: 78 additions & 35 deletions src/client/websocket.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,90 @@
import asyncio
from websockets.asyncio.server import serve
import threading
import websockets.sync.server as sync_ws
import time
import websockets
import pickle
import numpy as np
import matplotlib.pyplot as plt
import msgpack

# sleep foi para simular o tempo que o Loop demora para ser executado
async def producer():
await asyncio.sleep(3)
return "Hello from UnBrain!\n"
def producer():
while True:
time.sleep(3)
message = "Hello !"

async def consumer(message):
print(f'Message from client: {message}\n')
await queue.put(message)
def consumer(message):
print(f'Hello {message}')

class WebSocket:
def __init__(self, port=5001):
global queue
self.host="localhost"
def __init__(self, loop, port=5001):
self.loop = loop
self.host = "localhost"
self.port = port
self.message = ""
self.queue = queue

def run(self):
asyncio.run(main())
self.server = None

async def consumer_handler(websocket):
async for message in websocket:
await consumer(message)
await websocket.send(f"UnBrain received: {message}\n")
def producer(self):
# Simula uma tarefa demorada de 3 segundos
# time.sleep(3)

async def producer_handler(websocket):
while True:
message = await producer()
await websocket.send(message)
# mensagem com infos dos robos e bola
message_robot = {f"ROBOT {i}": list(self.loop.world.team[i].pos)+list(self.loop.world.team[i].v) for i in self.loop.world.n_robots if i is not None}
message_ball = list(self.loop.world.ball.pos)+list(self.loop.world.ball.v) # lembrar de multiplicar a velocidade por 400 (n sei pq)

# calculo pra enviar o UVF via mensagem
def message_uvf(robot_i=2, field_dims=(170*4, 130*4), arrow_spaces=16):
x = np.arange(-field_dims[0]/2, field_dims[0]/2, arrow_spaces)
y = np.arange(-field_dims[1]/2, field_dims[1]/2, arrow_spaces)
X, Y = np.meshgrid(x, y)
arrow_positions = np.array([X.flatten(), Y.flatten()]).T

robot = self.loop.world.raw_team[robot_i]

async def hello(websocket):
print(f"New websocket connected\n")
await asyncio.gather(
consumer_handler(websocket),
producer_handler(websocket),
)
positions = []
for i in range(arrow_positions.shape[0]):
positions.append(arrow_positions[i]/400)

angles = list(map(robot.field.F, positions))

return angles if robot.field is not None else 0

# self.message = f"{message_robot[0]}{message_robot[1]}{message_robot[2]}{message_ball};\n UVF:{message_uvf()}" # main.loop.world.team
self.message = {"TEAM": message_robot,
"BALL": message_ball}

if self.loop.draw_uvf:
self.message["UVF"] = message_uvf()

packed_message = msgpack.packb(self.message)
print(msgpack.unpackb(packed_message)["BALL"])

info = packed_message
print("produzindo")
return info

def run(self):
server_thread = threading.Thread(target=self.start_server)
server_thread.start()

async def main():
async with serve(hello, "localhost", 5001):
await asyncio.get_running_loop().create_future()
def start_server(self):
if self.server is None:
with sync_ws.serve(self.handle_connection, host=self.host, port=self.port) as server:
print(f"WebSocket server running at ws://{self.host}:{self.port}")
server.serve_forever()

def handle_connection(self, websocket):
print(f"New websocket connected\n")
while True:
try:
message = websocket.recv()
print(f"Message from client: {message}\n")
websocket.send(f"UnBrain received: {message}\n")
response = self.producer()
websocket.send(response)
except websockets.ConnectionClosed:
print("Client disconnected\n")
break


if __name__ == '__main__':
asyncio.run(main())
ws = WebSocket()
ws.run()
Loading