Source code for morse.multinode.socket

import logging; logger = logging.getLogger("morse." + __name__)
import mathutils
import time

from morse.core import blenderapi
from morse.core.multinode import SimulationNodeClass

from pymorse.stream import StreamJSON, PollThread

[docs]class SocketNode(SimulationNodeClass): """ Implements multinode simulation using sockets. """ out_data = {}
[docs] def initialize(self): """ Create the socket that will be used to commmunicate to the server. """ self.node_stream = None self.poll_thread = None self.simulation_time = blenderapi.persistantstorage().time logger.debug("Connecting to %s:%d" % (self.host, self.port) ) try: self.node_stream = StreamJSON(self.host, self.port) self.poll_thread = PollThread() self.poll_thread.start() if self.node_stream.connected: logger.info("Connected to %s:%s" % (self.host, self.port) ) except Exception as err: logger.info("Multi-node simulation not available!") logger.warning("Unable to connect to %s:%s"%(self.host, self.port) ) logger.warning(str(err))
def _exchange_data(self, out_data): """ Send and receive pickled data through a socket """ # Use the existing socket connection self.node_stream.publish([self.node_name, out_data]) return self.node_stream.get(timeout=.1) or self.node_stream.last()
[docs] def synchronize(self): if not self.node_stream: logger.debug("not self.node_stream") return if not self.node_stream.connected: logger.debug("not self.node_stream.connected") return # Get the coordinates of local robots for obj in blenderapi.persistantstorage().robotDict.keys(): #self.out_data[obj.name] = [obj.worldPosition.to_tuple()] euler_rotation = obj.worldOrientation.to_euler() self.out_data[obj.name] = [obj.worldPosition.to_tuple(), \ [euler_rotation.x, euler_rotation.y, euler_rotation.z]] self.out_data['__time'] = [self.simulation_time.time, 1.0/ blenderapi.getfrequency(), self.simulation_time.real_time] # Send the encoded dictionary through a socket # and receive a reply with any changes in the other nodes in_data = self._exchange_data(self.out_data) logger.debug("Received: %s" % in_data) if not in_data: return try: self.update_scene(in_data, blenderapi.scene()) except Exception as e: logger.warning("error while processing incoming data: " + str(e))
[docs] def update_scene(self, in_data, scene): # Update the positions of the external robots for obj_name, robot_data in in_data.items(): try: obj = scene.objects[obj_name] except Exception as e: logger.debug("%s not found in this simulation scenario, but present in another node. Ignoring it!" % obj_name) continue if obj not in blenderapi.persistantstorage().robotDict: obj.worldPosition = robot_data[0] obj.worldOrientation = mathutils.Euler(robot_data[1]).to_matrix()
[docs] def finalize(self): """ Close the communication socket. """ if self.node_stream: self.node_stream.close() self.node_stream = None if self.poll_thread: self.poll_thread.syncstop(1) self.poll_thread = None