2d map, physics, and vptree implementation for sv
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

230 lines
6.4 KiB

#include "Server.h"
void Server::start(){
std::cout << "Initialising TCP sever" << std::endl;
server.setup(port);
osc_sender.setup(OSC_HOST, OSC_PORT);
is_active = true;
previous_embedding = embedding;
last_change_time = std::chrono::steady_clock::now();
lastUpdateTime = std::chrono::steady_clock::now();
/* allocate pixels in vector */
esp_pixels.resize(4);
for(auto& p : esp_pixels){
p.allocate(128, 168, GL_RGB);
}
/* set initial chosen node */
chosen_node = &nodes[0];
}
void Server::update(ofFbo& esp_comp){
/* set all past clients to false, to check connection */
for(auto& c : clients){
c.second.connected = false;
}
ofPixels fboPixels;
esp_comp.readToPixels(fboPixels);
vector<ofImage> extractedImages;
extractedImages.resize(4);
for (int i = 0; i < 4; i++) {
ofPixels cropPixels;
fboPixels.cropTo(cropPixels, regions[i][0], regions[i][1], regions[i][2], regions[i][3]);
extractedImages[i].setFromPixels(cropPixels);
}
for ( int i = 0; i < server.getLastID(); i++){
if (server.isClientConnected(i)) {
const int buffer_size = 8;
char buffer[buffer_size];
int bytes_recieved = server.receiveRawBytes(i, buffer, buffer_size);
if (bytes_recieved == buffer_size){
float value;
int id;
memcpy(&value, buffer, sizeof(float));
memcpy(&id, buffer + sizeof(float), sizeof(int));
std::string ip_address = server.getClientIP(i);
addOrUpdateClient(id, value, ip_address, true);
//std::cout << ip_address << " : " << id << std::endl;
}
}
}
sendImagesToClients(extractedImages);
updateEmbedding();
/* check if inactive -> query vptree -> move camera */
checkActivity();
}
void Server::disconnectAllClients(){
server.disconnectAllClients();
}
void Server::addOrUpdateClient(int client_id, float value, const std::string& ip_address, bool _connected){
ClientInfo client;
client.ip_address = ip_address;
client.value = value;
client.connected = _connected;
clients[client_id] = client;
}
void Server::updateEmbedding() {
std::vector<std::string> emotionNames = {
"happy", "sad", "angry", "neutral"
};
for (const auto& c : clients) {
const ClientInfo& info = c.second;
float val = std::round(info.value * 100.0f) / 100.0f;
if (c.first >= 0 && c.first < emotionNames.size()) {
embedding.emotions[emotionNames[c.first]] = val;
}
}
}
void Server::printClients(){
for( const auto& c : clients){
int id = c.first;
const ClientInfo& info = c.second;
std::cout << "id: " << id
<< ", value: " << info.value
<< ", IP: " << info.ip_address << std::endl;
}
std::cout << is_active << std::endl;
}
void Server::print(){
const std::vector<std::string> emotionNames = {
"happy", "sad", "angry", "neutral"
};
std::ostringstream ss;
ss << "Embedding [";
for (size_t i = 0; i < emotionNames.size(); ++i) {
if (i > 0) ss << ", ";
ss << std::fixed << std::setprecision(2) << embedding.emotions[emotionNames[i]];
}
ss << "]" << endl;
ofSetColor(255, 255, 255);
ofDrawBitmapString(ss.str(), 20 , 20);
}
/* check if the controllers are in use */
void Server::checkActivity(){
if (previous_embedding.emotions != embedding.emotions) { // Check if embedding has changed
last_change_time = std::chrono::steady_clock::now(); // Reset the timer if there is a change
previous_embedding = embedding; // Update the previous embedding to the current one
is_active = true;
/* send a query to search the closest embedding in the vp-tree */
vector<vector<float>> vp_queries;
vp_queries.push_back(embedding.to_vector());
vector<int> ids = tree.query(vp_queries, 1);
chosen_node = &nodes[ids[0]];
// ofLog() << chosen_node->collider->getPosition();
} else {
// Calculate the time since the last change
auto now = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::seconds>(now - last_change_time).count();
if (duration >= 2) {
is_active = false;
//ofLogNotice() << "Inactive";
}
}
}
/* send osc msg, check if audio file exists and it is different to the past audiofile */
void Server::sendOSCMessage(){
std::vector<ofxOscMessage> messages;
ofxOscMessage me_0;
ofxOscMessage me_1;
ofxOscMessage me_2;
ofxOscMessage me_3;
ofxOscMessage me_file;
ofxOscMessage bang_new_mesh;
bang_new_mesh.setAddress("/emote/bang");
bang_new_mesh.addTriggerArg();
messages.push_back(bang_new_mesh);
for (auto& msg : messages){
osc_sender.sendMessage(msg, false);
}
}
/* sends request to http server if is_active = true */
void Server::sendHttpRequest(){
vp_resp = http.query(embedding);
}
std::vector<std::vector<double>> Server::generateRandomVectors(int count, int dimension){
return tree.generateRandomVectors(count, dimension);
}
void Server::sendImagesToClients(vector<ofImage>& imgs){
/* convert to pixels */
int c = 0;
for(const auto& f :imgs){
esp_pixels[c] = f.getPixels();
c++;
}
int num_images = imgs.size();
if (num_images != 4) {
// No images to send, return early
return;
}
ofSetLogLevel(OF_LOG_FATAL_ERROR);
for (int i = 0; i < server.getLastID(); i++) {
if (server.isClientConnected(i)) {
// Send RGB pixels as raw bytes & check if the ip addresses align -> get id
for(const auto& c_pair : clients){
//std::cout << c_pair.first << std::endl;
if(c_pair.second.ip_address == server.getClientIP(i)){
unsigned char* image_data = esp_pixels[c_pair.first].getData();
server.sendRawBytes(i, (char*)image_data, esp_pixels[c_pair.first].size());
}
}
}
}
ofSetLogLevel(OF_LOG_NOTICE);
}
Node& Server::getChosenNode(){
return *chosen_node;
}
void Server::close(){
server.close();
}