Ejemplo n.º 1
0
class SocketNode(SimulationNodeClass):
    """ 
    Implements multinode simulation using sockets.
    """

    out_data = {}

    def initialize(self):
        """
        Create the socket that will be used to commmunicate to the server.
        """
        self.node_stream = None
        logger.debug("Connecting to %s:%d" % (self.host, self.port) )
        try:
            self.node_stream = StreamJSON(self.host, self.port)
            self.async_thread = threading.Thread( target = asyncore.loop, kwargs = {'timeout': .1} )
            self.async_thread.start()
            if self.node_stream.connected:
                logger.info("Connected to %s:%s" % (self.host, self.port) )
        except Exception as e:
            logger.info("Multi-node simulation not available!")
            logger.warning("Unable to connect to %s:%s"%(self.host, self.port) )
            logger.info(str(e))

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

    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, local_robot_data in blenderapi.persistantstorage().robotDict.items():
            #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]]
        # 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))

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

    def finalize(self):
        """ Close the communication socket. """
        self.node_stream.close()
        # asyncore.close_all() # make sure all connection are closed
        self.async_thread.join(timeout=1)
Ejemplo n.º 2
0
class TestPyMorseStreamSlow(unittest.TestCase):

    def setUp(self):
        print("Starting test...")
        self.freq = 10
        self._server = SocketWriter(freq = self.freq) # First tests: producer at 10 Hz

        self.host = "localhost"
        self.stream = StreamJSON(self.host, 61000)
        self._asyncore_thread = threading.Thread( target = asyncore.loop, kwargs = {'timeout': 0.01} )
        self._asyncore_thread.start()
        
    def test_get(self):

        self.assertEqual(self.stream.get(), [0])
        self.assertEqual(self.stream.get(), [1])
        
    def test_last_timed(self):

        d = 1/float(self.freq)
        self.assertIsNone(self.stream.last())
        time.sleep(d + d * 0.5)
        self.assertEqual(self.stream.last(), [0])
        time.sleep(d)
        self.assertEqual(self.stream.last(), [1])
        time.sleep(d)
        time.sleep(d)
        self.assertEqual(self.stream.last(), [3])

    def test_subscribe(self):

        d = 1/float(self.freq)
        self.ok = False
        self.i = 0

        self.stream.subscribe(self.on_data)

        time.sleep(d + d * 0.5)
        self.assertTrue(self.ok)

        self.ok = False
        time.sleep(d)
        self.assertTrue(self.ok)

    def test_unsubscribe(self):

        d = 1/float(self.freq)
        self.ok = False
        self.i = 0

        self.stream.subscribe(self.on_data)
        time.sleep(d + d * 0.5)
        self.assertTrue(self.ok)

        self.ok = False

        self.stream.unsubscribe(self.on_data)
        time.sleep(d)
        self.assertFalse(self.ok)

    def on_data(self, record):
        
        self.ok = True
        self.assertEqual(record, [self.i])
        self.i += 1
        
    def tearDown(self):
        self._server.close()
        asyncore.close_all()
        self._asyncore_thread.join(TIMEOUT)
        self._asyncore_thread = None # in case we want to re-create
Ejemplo n.º 3
0
class TestPyMorseStreamSlow(unittest.TestCase):
    def setUp(self):
        print("Starting test...")
        self.freq = 10
        self._server = SocketWriter(
            freq=self.freq)  # First tests: producer at 10 Hz

        self.host = "localhost"
        self.stream = StreamJSON(self.host, 61000)
        self._asyncore_thread = threading.Thread(target=asyncore.loop,
                                                 kwargs={'timeout': 0.01})
        self._asyncore_thread.start()

    def test_get(self):

        self.assertEqual(self.stream.get(), [0])
        self.assertEqual(self.stream.get(), [1])

    def test_last_timed(self):

        d = 1 / float(self.freq)
        self.assertIsNone(self.stream.last())
        time.sleep(d + d * 0.5)
        self.assertEqual(self.stream.last(), [0])
        time.sleep(d)
        self.assertEqual(self.stream.last(), [1])
        time.sleep(d)
        time.sleep(d)
        self.assertEqual(self.stream.last(), [3])

    def test_subscribe(self):

        d = 1 / float(self.freq)
        self.ok = False
        self.i = 0

        self.stream.subscribe(self.on_data)

        time.sleep(d + d * 0.5)
        self.assertTrue(self.ok)

        self.ok = False
        time.sleep(d)
        self.assertTrue(self.ok)

    def test_unsubscribe(self):

        d = 1 / float(self.freq)
        self.ok = False
        self.i = 0

        self.stream.subscribe(self.on_data)
        time.sleep(d + d * 0.5)
        self.assertTrue(self.ok)

        self.ok = False

        self.stream.unsubscribe(self.on_data)
        time.sleep(d)
        self.assertFalse(self.ok)

    def on_data(self, record):

        self.ok = True
        self.assertEqual(record, [self.i])
        self.i += 1

    def tearDown(self):
        self._server.close()
        asyncore.close_all()
        self._asyncore_thread.join(TIMEOUT)
        self._asyncore_thread = None  # in case we want to re-create
Ejemplo n.º 4
0
class SocketNode(SimulationNodeClass):
    """ 
    Implements multinode simulation using sockets.
    """

    out_data = {}

    def initialize(self):
        """
        Create the socket that will be used to commmunicate to the server.
        """
        self.node_stream = None
        logger.debug("Connecting to %s:%d" % (self.host, self.port))
        try:
            self.node_stream = StreamJSON(self.host, self.port)
            self.async_thread = threading.Thread(target=asyncore.loop,
                                                 kwargs={'timeout': .1})
            self.async_thread.start()
            if self.node_stream.connected:
                logger.info("Connected to %s:%s" % (self.host, self.port))
        except Exception as e:
            logger.info("Multi-node simulation not available!")
            logger.warning("Unable to connect to %s:%s" %
                           (self.host, self.port))
            logger.info(str(e))

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

    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, local_robot_data in blenderapi.persistantstorage(
        ).robotDict.items():
            #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]
            ]
        # 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))

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

    def finalize(self):
        """ Close the communication socket. """
        self.node_stream.close()
        # asyncore.close_all() # make sure all connection are closed
        self.async_thread.join(timeout=1)