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
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							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(); | |
| } |