def test_spawn_and_delete_one_object(self, client_type): """ Ask Clerk to spawn one object. """ # Get the client for this test. client = self.clients[client_type] # Constants and parameters for this test. objID, templateID = 1, '_templateEmpty' # Spawn a new object from templateID. The new object must have objID=1. init = {'templateID': templateID, 'rbs': {'position': (0, 0, 0)}} ret = client.spawn([init]) assert ret.ok and ret.data == [objID] # Attempt to spawn a non-existing template. assert not client.spawn([{'templateID': 'blah'}]).ok # Send invalid data to 'spawn'. assert not client.spawn([{'blah': 'blah'}]).ok # Exactly one object must exist at this point. ret = client.getAllObjectIDs() assert (ret.ok, ret.data) == (True, [objID]) # Attempt to delete a non-existing object. This must silently fail. assert client.removeObject(100).ok ret = client.getAllObjectIDs() assert (ret.ok, ret.data) == (True, [objID]) # Delete an existing object. assert client.removeObject(objID).ok ret = client.getAllObjectIDs() assert (ret.ok, ret.data) == (True, [])
def run(self): # Return immediately if no resets are required. if self.period == -1: return # Establish connection to Azrael. client = azrael.client.Client() # Query all objects in the scene. These are the only objects that will # survive the reset. ret = client.getAllObjectIDs() assert ret.ok ret = client.getRigidBodies(ret.data) assert ret.ok allowed_objIDs = {k: v["rbs"] for k, v in ret.data.items() if v is not None} print("Took simulation snapshot for reset: ({} objects)".format(len(allowed_objIDs))) # Periodically reset the SV values. Set them several times because it # is well possible that not all State Variables reach Leonard in the # same frame, which means some objects will be reset while other are # not. This in turn may cause strange artefacts in the next physics # update step, especially when the objects now partially overlap. while True: # Wait until the timeout expires. time.sleep(self.period) # Remove all newly added objects. ret = client.getAllObjectIDs() for objID in ret.data: if objID not in allowed_objIDs: client.removeObject(objID) # Forcefully reset the position and velocity of every object. Do # this several times since network latency may result in some # objects being reset sooner than others. for ii in range(5): for objID, SV in allowed_objIDs.items(): tmp = { "position": SV.position, "velocityLin": SV.velocityLin, "velocityRot": SV.velocityRot, "rotation": SV.rotation, } assert client.setRigidBodies({objID: tmp}).ok time.sleep(0.1)
def test_getAllObjectIDs(self, client_type): """ Ensure the getAllObjectIDs command reaches Clerk. """ # Get the client for this test. client = self.clients[client_type] # Constants and parameters for this test. templateID, objID_1 = '_templateEmpty', 1 # So far no objects have been spawned. ret = client.getAllObjectIDs() assert (ret.ok, ret.data) == (True, []) # Spawn a new object. init = {'templateID': templateID, 'rbs': {'position': (0, 0, 0)}} ret = client.spawn([init]) assert ret.ok and ret.data == [objID_1] # The object list must now contain the ID of the just spawned object. ret = client.getAllObjectIDs() assert (ret.ok, ret.data) == (True, [objID_1])
def resetSimulation(host, port=5555): """ Delete all objects in the scene. Azrael does not have a command to do that (yet), which is why this function queries all objects and the deletes them one-by-one. The `host` and `port` parameters specify the location of the Azrael API. """ # Connect to Azrael. client = azrael.client.Client(host, port=port) # Query IDs of all objects in the simulation. ret = client.getAllObjectIDs() assert ret.ok allIDs = ret.data # Delete all objects. for objID in allIDs: assert client.removeObject(objID).ok
def run(self): """ """ # Return immediately if no resets are required. if self.period == -1: return # Instantiate Client. client = azrael.client.Client() # Query all object IDs. This happens only once which means the geometry # swap does not affect newly generated objects. time.sleep(1) ret = client.getAllObjectIDs() objIDs = ret.data print('\n-- {} objects --\n'.format(len(objIDs))) # Query and backup all models currently in the scene. geo_meta = client.getFragments(objIDs).data base_url = 'http://{}:{}'.format( azrael.config.addr_webserver, azrael.config.port_webserver) geo_orig = {} for objID in objIDs: frags = {} for frag_name in geo_meta[objID]: url = base_url + geo_meta[objID][frag_name]['url_frag'] url += '/model.json' tmp = urllib.request.urlopen(url).readall() tmp = json.loads(tmp.decode('utf8')) tmp = FragRaw(**tmp) frags[frag_name] = FragMeta(frag_name, 'raw', tmp) del url, tmp geo_orig[objID] = frags del frags, objID del geo_meta, base_url # Compile a set of sphere models for all objects. These will be # periodically swapped out for the original models. sphere_vert, sphere_uv, sphere_rgb = loadSphere() sphere = FragRaw(sphere_vert, sphere_uv, sphere_rgb) geo_spheres = {} for objID in objIDs: tmp = {_: FragMeta(_, 'raw', sphere) for _ in geo_orig[objID]} geo_spheres[objID] = tmp del tmp del sphere_vert, sphere_uv, sphere_rgb, sphere cnt = 0 while True: # Update the counter and pause for the specified time. cnt = (cnt + 1) % 20 time.sleep(self.period) # Swap out the geometry. if (cnt % 2) == 1: geo = geo_spheres else: geo = geo_orig # Apply the new geometry to each fragment. for objID, val in geo.items(): ret = client.updateFragments(objID, list(val.values())) if not ret.ok: print('--> Terminating geometry updates') sys.exit(1) # Modify the global scale and a fragment position. scale = (cnt + 1) / 10 for objID in objIDs: # Change the scale of the overall object. new_sv = RigidBodyDataOverride(scale=scale) client.setRigidBody(objID, new_sv) # Move the second fragment. x = -10 + cnt newStates = { objID: [FragState('frag_2', 1, [x, 0, 0], [0, 0, 0, 1])] } client.setFragmentStates(newStates) # Print status for user. print('Scale={:.1f}'.format(scale))