Walls

Description
Walls are considered an “actor” in Quanser Interactive Labs Open Worlds. Walls can be spawned anywhere in the Open Worlds and accompany several different products including the QCar Studio and the QBot Platform. The origin of the wall is at the bottom center. Walls are static by default but dynamics can be optionally enabled.
Library
Constants
- QLabsWalls.ID_WALL = 10080
Class ID
Member Variables
- QLabsWalls.actorNumber = None
The current actor number of this class to be addressed. This will be set by spawn methods and cleared by destroy methods. It will not be modified by the destroy all actors. This can be manually altered at any time to use one object to address multiple actors.
Methods
- QLabsWalls.spawn(location=[0, 0, 0], rotation=[0, 0, 0], scale=[1, 1, 1], configuration=0, waitForConfirmation=True)
Spawns a new actor with the next available actor number within this class.
- Parameters
location (float array[3]) – (Optional) An array of floats for x, y and z coordinates
rotation (float array[3]) – (Optional) An array of floats for the roll, pitch, and yaw in radians
scale (float array[3]) – (Optional) An array of floats for the scale in the x, y, and z directions. Scale values of 0.0 should not be used.
configuration (uint32) – (Optional) Spawn configuration. See class library for configuration options.
waitForConfirmation (boolean) – (Optional) Make this operation blocking until confirmation of the spawn has occurred. Note that if this is False, the returned actor number will be invalid.
- Returns
status - 0 if successful, 1 class not available, 3 unknown error, -1 communications error.
actorNumber - An actor number to use for future references.
- Return type
int32, int32
- QLabsWalls.spawn_degrees(location=[0, 0, 0], rotation=[0, 0, 0], scale=[1, 1, 1], configuration=0, waitForConfirmation=True)
Spawns a new actor with the next available actor number within this class.
- Parameters
location (float array[3]) – (Optional) An array of floats for x, y and z coordinates
rotation (float array[3]) – (Optional) An array of floats for the roll, pitch, and yaw in degrees
scale (float array[3]) – (Optional) An array of floats for the scale in the x, y, and z directions. Scale values of 0.0 should not be used.
configuration (uint32) – (Optional) Spawn configuration. See class library for configuration options.
waitForConfirmation (boolean) – (Optional) Make this operation blocking until confirmation of the spawn has occurred. Note that if this is False, the returned actor number will be invalid.
- Returns
status - 0 if successful, 1 class not available, 3 unknown error, -1 communications error.
actorNumber - An actor number to use for future references.
- Return type
int32, int32
- QLabsWalls.spawn_id(actorNumber, location=[0, 0, 0], rotation=[0, 0, 0], scale=[1, 1, 1], configuration=0, waitForConfirmation=True)
Spawns a new actor.
- Parameters
actorNumber (uint32) – User defined unique identifier for the class actor in QLabs
location (float array[3]) – (Optional) An array of floats for x, y and z coordinates
rotation (float array[3]) – (Optional) An array of floats for the roll, pitch, and yaw in radians
scale (float array[3]) – (Optional) An array of floats for the scale in the x, y, and z directions. Scale values of 0.0 should not be used.
configuration (uint32) – (Optional) Spawn configuration. See class library for configuration options.
waitForConfirmation (boolean) – (Optional) Make this operation blocking until confirmation of the spawn has occurred.
- Returns
status - 0 if successful, 1 class not available, 2 actor number not available or already in use, 3 unknown error, -1 communications error
- Return type
int32
- QLabsWalls.spawn_id_degrees(actorNumber, location=[0, 0, 0], rotation=[0, 0, 0], scale=[1, 1, 1], configuration=0, waitForConfirmation=True)
Spawns a new actor.
- Parameters
actorNumber (uint32) – User defined unique identifier for the class actor in QLabs
location (float array[3]) – (Optional) An array of floats for x, y and z coordinates
rotation (float array[3]) – (Optional) An array of floats for the roll, pitch, and yaw in radians
scale (float array[3]) – (Optional) An array of floats for the scale in the x, y, and z directions. Scale values of 0.0 should not be used.
configuration (uint32) – (Optional) Spawn configuration. See class library for configuration options.
waitForConfirmation (boolean) – (Optional) Make this operation blocking until confirmation of the spawn has occurred.
- Returns
status - 0 if successful, 1 class not available, 2 actor number not available or already in use, 3 unknown error, -1 communications error
- Return type
int32
- QLabsWalls.spawn_id_and_parent_with_relative_transform(actorNumber, location=[0, 0, 0], rotation=[0, 0, 0], scale=[1, 1, 1], configuration=0, parentClassID=0, parentActorNumber=0, parentComponent=0, waitForConfirmation=True)
Spawns a new actor relative to an existing actor and creates a kinematic relationship.
- Parameters
actorNumber (uint32) – User defined unique identifier for the class actor in QLabs
location (float array[3]) – (Optional) An array of floats for x, y and z coordinates
rotation (float array[3]) – (Optional) An array of floats for the roll, pitch, and yaw in radians
scale (float array[3]) – (Optional) An array of floats for the scale in the x, y, and z directions. Scale values of 0.0 should not be used.
configuration (uint32) – (Optional) Spawn configuration. See class library for configuration options.
parentClassID (uint32) – See the ID variables in the respective library classes for the class identifier
parentActorNumber (uint32) – User defined unique identifier for the class actor in QLabs
parentComponent (uint32) – 0 for the origin of the parent actor, see the parent class for additional reference frame options
waitForConfirmation (boolean) – (Optional) Make this operation blocking until confirmation of the spawn has occurred.
- Returns
status - 0 if successful, 1 class not available, 2 actor number not available or already in use, 3 cannot find the parent actor, 4 unknown error, -1 communications error
- Return type
int32
- QLabsWalls.spawn_id_and_parent_with_relative_transform_degrees(actorNumber, location=[0, 0, 0], rotation=[0, 0, 0], scale=[1, 1, 1], configuration=0, parentClassID=0, parentActorNumber=0, parentComponent=0, waitForConfirmation=True)
Spawns a new actor relative to an existing actor and creates a kinematic relationship.
- Parameters
actorNumber (uint32) – User defined unique identifier for the class actor in QLabs
location (float array[3]) – (Optional) An array of floats for x, y and z coordinates
rotation (float array[3]) – (Optional) An array of floats for the roll, pitch, and yaw in degrees
scale (float array[3]) – (Optional) An array of floats for the scale in the x, y, and z directions. Scale values of 0.0 should not be used.
configuration (uint32) – (Optional) Spawn configuration. See class library for configuration options.
parentClassID (uint32) – See the ID variables in the respective library classes for the class identifier
parentActorNumber (uint32) – User defined unique identifier for the class actor in QLabs
parentComponent (uint32) – 0 for the origin of the parent actor, see the parent class for additional reference frame options
waitForConfirmation (boolean) – (Optional) Make this operation blocking until confirmation of the spawn has occurred.
- Returns
status - 0 if successful, 1 class not available, 2 actor number not available or already in use, 3 cannot find the parent actor, 4 unknown error, -1 communications error
- Return type
int32
- QLabsWalls.destroy()
Find and destroy a specific actor. This is a blocking operation.
- Returns
numActorsDestroyed - The number of actors destroyed. -1 if failed.
- Return type
int32
- QLabsWalls.destroy_all_actors_of_class()
Find and destroy all actors of this class. This is a blocking operation.
- Returns
numActorsDestroyed - The number of actors destroyed. -1 if failed.
- Return type
int32
- QLabsWalls.ping()
Checks if the actor is still present in the environment. Note that if you did not spawn the actor with one of the spawn functions, you may need to manually set the actorNumber member variable.
- Returns
status - True if successful, False otherwise
- Return type
boolean
- QLabsWalls.get_world_transform()
Get the location, rotation, and scale in world coordinates of the actor.
- Returns
status - True if successful, False otherwise
location
rotation
scale
- Return type
boolean, float array[3], float array[3], float array[3]
- QLabsWalls.get_world_transform_degrees()
Get the location, rotation, and scale in world coordinates of the actor.
- Returns
status - True if successful, False otherwise
location
rotation
scale
- Return type
boolean, float array[3], float array[3], float array[3]
- QLabsWalls.parent_with_relative_transform(location=[0, 0, 0], rotation=[0, 0, 0], scale=[1, 1, 1], parentClassID=0, parentActorNumber=0, parentComponent=0, waitForConfirmation=True)
Parents one existing actor to another to create a kinematic relationship.
- Parameters
location (float array[3]) – (Optional) An array of floats for x, y and z coordinates
rotation (float array[3]) – (Optional) An array of floats for the roll, pitch, and yaw in radians
scale (float array[3]) – (Optional) An array of floats for the scale in the x, y, and z directions. Scale values of 0.0 should not be used.
parentClassID (uint32) – See the ID variables in the respective library classes for the class identifier
parentActorNumber (uint32) – User defined unique identifier for the class actor in QLabs
parentComponent (uint32) – 0 for the origin of the parent actor, see the parent class for additional reference frame options
waitForConfirmation (boolean) – (Optional) Make this operation blocking until confirmation of the spawn has occurred.
- Returns
status - 0 if successful, 1 cannot find this actor, 2 cannot find the parent actor, 3 unknown error, -1 communications error
- Return type
int32
- QLabsWalls.parent_with_relative_transform_degrees(location=[0, 0, 0], rotation=[0, 0, 0], scale=[1, 1, 1], parentClassID=0, parentActorNumber=0, parentComponent=0, waitForConfirmation=True)
Parents one existing actor to another to create a kinematic relationship.
- Parameters
location (float array[3]) – (Optional) An array of floats for x, y and z coordinates
rotation (float array[3]) – (Optional) An array of floats for the roll, pitch, and yaw in degrees
scale (float array[3]) – (Optional) An array of floats for the scale in the x, y, and z directions. Scale values of 0.0 should not be used.
parentClassID (uint32) – (Optional) See the ID variables in the respective library classes for the class identifier
parentActorNumber (uint32) – (Optional) User defined unique identifier for the class actor in QLabs
parentComponent (uint32) – (Optional) 0 for the origin of the parent actor, see the parent class for additional reference frame options
waitForConfirmation (boolean) – (Optional) Make this operation blocking until confirmation of the spawn has occurred.
- Returns
status - 0 if successful, 1 cannot find this actor, 2 cannot find the parent actor, 3 unknown error, -1 communications error
- Return type
int32
- QLabsWalls.parent_with_current_world_transform(parentClassID=0, parentActorNumber=0, parentComponent=0, waitForConfirmation=True)
Parents one existing actor to another to create a kinematic relationship while preserving the current world transform of the child actor.
- Parameters
parentClassID (uint32) – See the ID variables in the respective library classes for the class identifier
parentActorNumber (uint32) – User defined unique identifier for the class actor in QLabs
parentComponent (uint32) – 0 for the origin of the parent actor, see the parent class for additional reference frame options
waitForConfirmation (boolean) – (Optional) Make this operation blocking until confirmation of the spawn has occurred.
- Returns
status - 0 if successful, 1 cannot find this actor, 2 cannot find the parent actor, 3 unknown error, -1 communications error
- Return type
int32
- QLabsWalls.parent_break(waitForConfirmation=True)
Breaks any relationship with a parent actor (if it exists) and preserves the current world transform
- Parameters
waitForConfirmation (boolean) – (Optional) Make this operation blocking until confirmation of the spawn has occurred.
- Returns
status - 0 if successful, 1 cannot find this actor, -1 communications error
- Return type
int32
- QLabsWalls.set_enable_dynamics(enableDynamics, waitForConfirmation=True)[source]
Sets the physics properties of the wall.
- Parameters
enableDynamics (boolean) – Enable (True) or disable (False) the wall dynamics. A dynamic actor can be pushed with other static or dynamic actors. A static actor will generate collisions, but will not be affected by interactions with other actors.
waitForConfirmation (boolean) – (Optional) Wait for confirmation of the operation before proceeding. This makes the method a blocking operation.
- Returns
True if successful, False otherwise
- Return type
boolean
- QLabsWalls.set_enable_collisions(enableCollisions, waitForConfirmation=True)[source]
Enables and disables physics collisions. When disabled, other physics or velocity-based actors will be able to pass through.
- Parameters
enableCollisions (boolean) – Enable (True) or disable (False) the collision.
waitForConfirmation (boolean) – (Optional) Wait for confirmation of the operation before proceeding. This makes the method a blocking operation.
- Returns
True if successful, False otherwise
- Return type
boolean
- QLabsWalls.set_physics_properties(enableDynamics, mass=1.0, linearDamping=0.01, angularDamping=0.0, staticFriction=0.0, dynamicFriction=0.7, frictionCombineMode=COMBINE_AVERAGE, restitution=0.3, restitutionCombineMode=COMBINE_AVERAGE, waitForConfirmation=True)[source]
Sets the dynamic properties of the wall.
- Parameters
enableDynamics (boolean) – Enable (True) or disable (False) the wall dynamics. A dynamic actor can be pushed with other static or dynamic actors. A static actor will generate collisions, but will not be affected by interactions with other actors.
mass (float) – (Optional) Sets the mass of the actor in kilograms.
linearDamping (float) – (Optional) Sets the damping of the actor for linear motions.
angularDamping (float) – (Optional) Sets the damping of the actor for angular motions.
staticFriction (float) – (Optional) Sets the coefficient of friction when the actor is at rest. A value of 0.0 is frictionless.
dynamicFriction (float) – (Optional) Sets the coefficient of friction when the actor is moving relative to the surface it is on. A value of 0.0 is frictionless.
frictionCombineMode (byte) – (Optional) Defines how the friction between two surfaces with different coefficients should be calculated (see COMBINE constants).
restitution (float) – (Optional) The coefficient of restitution defines how plastic or elastic a collision is. A value of 0.0 is plastic and will absorb all energy. A value of 1.0 is elastic and will bounce forever. A value greater than 1.0 will add energy with each collision.
restitutionCombineMode (byte) – (Optional) Defines how the restitution between two surfaces with different coefficients should be calculated (see COMBINE constants).
waitForConfirmation (boolean) – (Optional) Wait for confirmation of the operation before proceeding. This makes the method a blocking operation.
- Returns
True if successful, False otherwise
- Return type
boolean
- QLabsWalls.set_transform(location, rotation, scale, waitForConfirmation=True)[source]
Sets the location, rotation in radians, and scale. If a wall is parented to another actor then the location, rotation, and scale are relative to the parent actor.
- Parameters
location (float array[3]) – An array of floats for x, y and z coordinates in full-scale units. Multiply physical QCar locations by 10 to get full scale locations.
rotation (float array[3]) – An array of floats for the roll, pitch, and yaw in radians
scale (float array[3]) – An array of floats for the scale in the x, y, and z directions.
waitForConfirmation (boolean) – (Optional) Wait for confirmation of the operation before proceeding. This makes the method a blocking operation.
- Returns
True if successful or False otherwise
- Return type
boolean
- QLabsWalls.set_transform_degrees(location, rotation, scale, waitForConfirmation=True)[source]
Sets the location, rotation in degrees, and scale. If a wall is parented to another actor then the location, rotation, and scale are relative to the parent actor.
- Parameters
location (float array[3]) – An array of floats for x, y and z coordinates in full-scale units. Multiply physical QCar locations by 10 to get full scale locations.
rotation (float array[3]) – An array of floats for the roll, pitch, and yaw in degrees
scale (float array[3]) – An array of floats for the scale in the x, y, and z directions.
waitForConfirmation (boolean) – (Optional) Wait for confirmation of the operation before proceeding. This makes the method a blocking operation.
- Returns
True if successful or False otherwise
- Return type
boolean
Configurations
There is only one configuration for the walls class.
Connection Points
There are no connection points for this actor class.
Walls Tutorial
Python Tutorial
Raw to download this tutorial: Walls Tutorial (.py)
.
1"""
2Walls Example
3---------------
4
5.. note::
6
7 Make sure you have Quanser Interactive Labs open before running this
8 example. This example is designed to be run in the Plane, Warehouse
9 or Studio environment.
10
11"""
12
13from qvl.qlabs import QuanserInteractiveLabs
14from qvl.free_camera import QLabsFreeCamera
15from qvl.basic_shape import QLabsBasicShape
16
17import time
18
19from qvl.walls import QLabsWalls
20
21
22def main():
23 # Creates a server connection with Quanser Interactive Labs and manages
24 # the communications
25 qlabs = QuanserInteractiveLabs()
26
27 # Ensure that QLabs is running on your local machine
28 print("Connecting to QLabs...")
29 if (not qlabs.open("localhost")):
30 print("Unable to connect to QLabs")
31 return
32
33 print("Connected")
34
35 num_destroyed = qlabs.destroy_all_spawned_actors()
36
37 # Initialize an instance of a custom camera
38 camera = QLabsFreeCamera(qlabs)
39 camera.spawn([2.295, -3.826, 1.504], [-0, 0.213, 1.957])
40 camera.possess()
41
42 # Initialize instances of walls
43 wall = QLabsWalls(qlabs)
44
45 # Use 'for' loops to spawn a line of walls
46 for y in range (5):
47 wall.spawn_degrees([-0.5, y*1.05, 0.001])
48
49 # Spawn a second line of walls but enable the dynamics
50 for y in range (5):
51 wall.spawn_degrees([0.5, y*1.05, 0.001])
52
53 # Enable dynamics for this set of walls
54 wall.set_enable_dynamics(True)
55
56
57 # Spawn a large sphere to demonstrate which walls are dynamic
58 sphere = QLabsBasicShape(qlabs)
59 sphere.spawn(location=[0,2,3], scale=[1.5,1.5,1.5], configuration=sphere.SHAPE_SPHERE)
60 sphere.set_enable_dynamics(True)
61
62
63
64 # Closing qlabs
65 qlabs.close()
66 print('Done!')
67
68if __name__ == "__main__":
69 main()
Maze
Raw to download this tutorial: Wall Maze Tutorial (.py)
.
1"""
2Maze Example
3---------------
4
5.. note::
6
7 Make sure you have Quanser Interactive Labs open before running this
8 example. This example is designed to be run in the Plane or Warehouse
9 environment.
10
11"""
12
13from qvl.qlabs import QuanserInteractiveLabs
14from qvl.free_camera import QLabsFreeCamera
15from qvl.system import QLabsSystem
16
17import numpy as np
18import random
19import time
20
21from qvl.walls import QLabsWalls
22
23# Use the ramdom seed if you want the same maze every time (uncomment the following line)
24#random.seed(12)
25
26# Do you want the walls to be able to fall over if hit? (Maze generation will take slightly longer.)
27dynamic_walls = False
28
29# Maze size
30maze_x = 10
31maze_y = 10
32
33# Initialize constants and variables. We'll use a bit mask to efficiently store multiple
34# pieces of information inside a single value.
35North = 0b00001
36East = 0b00010
37South = 0b00100
38West = 0b01000
39Unexplored = 0b10000
40maze_data = np.ones(shape=(maze_x,maze_y), dtype=int) * (North | East | South | West | Unexplored)
41
42# Length of a wall segment plus a bit of padding
43wall_length = 1.05
44
45
46
47def generate_maze():
48 location = [0, 0]
49
50 # Mark the first cell as explored and remove the North wall as the entrance to the maze
51 maze_data[0,0] = maze_data[0,0] & (~Unexplored) & (~North)
52
53 # Start digging through the maze recursively
54 remove_maze_wall(location)
55
56 # Remove one wall on the South side of the maze
57 maze_data[0,maze_y-1] = maze_data[0,maze_y-1] & (~South)
58
59
60def remove_maze_wall(location):
61
62 # first pick a random direction (N, S, W, E) (The order helps reduce "easy" solutions to the maze)
63 first_direction = random.randint(0,3)
64
65 # Check all four compass directions for a valid travel path
66 for direction in range(4):
67
68 # Offset the direction count by the random direction
69 current_direction = (direction + first_direction) % 4
70
71 if (current_direction == 0):
72 if ((location[1] > 0) and (maze_data[location[0], location[1]-1] & Unexplored)):
73 # Remove North wall from the current cell and the South wall of the new cell and mark the new cell as explored
74 maze_data[location[0], location[1]-1] = maze_data[location[0], location[1]-1] & (~Unexplored)
75 maze_data[location[0], location[1]-1] = maze_data[location[0], location[1]-1] & (~South)
76 maze_data[location[0], location[1]] = maze_data[location[0], location[1]] & (~North)
77
78 remove_maze_wall([location[0], location[1]-1])
79
80 elif (current_direction == 1):
81 if ((location[1] < (maze_y-1)) and (maze_data[location[0], location[1]+1] & Unexplored)):
82 # Remove South wall from the current cell and the North wall of the new cell and mark the new cell as explored
83 maze_data[location[0], location[1]+1] = maze_data[location[0], location[1]+1] & (~Unexplored)
84 maze_data[location[0], location[1]+1] = maze_data[location[0], location[1]+1] & (~North)
85 maze_data[location[0], location[1]] = maze_data[location[0], location[1]] & (~South)
86
87 remove_maze_wall([location[0], location[1]+1])
88
89 elif (current_direction == 2):
90 if ((location[0] > 0) and (maze_data[location[0]-1, location[1]] & Unexplored)):
91 # Remove West wall from the current cell and the East wall of the new cell and mark the new cell as explored
92 maze_data[location[0]-1, location[1]] = maze_data[location[0]-1, location[1]] & (~Unexplored)
93 maze_data[location[0]-1, location[1]] = maze_data[location[0]-1, location[1]] & (~East)
94 maze_data[location[0], location[1]] = maze_data[location[0], location[1]] & (~West)
95
96 remove_maze_wall([location[0]-1, location[1]])
97
98 else:
99 if ((location[0] < (maze_x-1)) and (maze_data[location[0]+1, location[1]] & Unexplored)):
100 # Remove East wall from the current cell and the West wall of the new cell and mark the new cell as explored
101 maze_data[location[0]+1, location[1]] = maze_data[location[0]+1, location[1]] & (~Unexplored)
102 maze_data[location[0]+1, location[1]] = maze_data[location[0]+1, location[1]] & (~West)
103 maze_data[location[0], location[1]] = maze_data[location[0], location[1]] & (~East)
104
105 remove_maze_wall([location[0]+1, location[1]])
106
107
108
109
110def draw_maze(qlabs):
111 # Initialize a wall object
112 wall = QLabsWalls(qlabs)
113
114 # add just the first top row
115 for count_x in range(maze_x):
116 if (maze_data[count_x, 0] & North):
117 place_wall(wall, count_x, 0, North)
118
119 for count_y in range(maze_y):
120 # left most wall of the maze
121 if (maze_data[0, count_y] & West):
122 place_wall(wall, 0, count_y, West)
123
124 # all the rest of the walls
125 for count_x in range(maze_x):
126 if (maze_data[count_x, count_y] & South):
127 place_wall(wall, count_x, count_y, South)
128
129 if (maze_data[count_x, count_y] & East):
130 place_wall(wall, count_x, count_y, East)
131
132 if (not dynamic_walls):
133 # If we're not waiting for any responses from QLabs, add
134 # a slight delay after each row to ensure we don't overflow
135 # the buffers for really large mazes.
136 time.sleep(0.01)
137
138
139
140def place_wall(wall, x, y, direction):
141 # You can tweak the global x/y offset of the maze generation here by entering a position in meters.
142 offset = [0, 0]
143
144 # Walls are static by default so we only need to wait for confirmation if the dynamic_walls flag is set.
145 if direction == North:
146 wall.spawn_degrees(location=[x*wall_length + offset[0], -(y*wall_length) + offset[1], 0.001], rotation=[0, 0, 90], waitForConfirmation=dynamic_walls)
147
148 elif direction == East:
149 wall.spawn_degrees(location=[x*wall_length + wall_length/2 + offset[0], -(y*wall_length + wall_length/2) + offset[1], 0.001], rotation=[0, 0, 0], waitForConfirmation=dynamic_walls)
150
151 elif direction == South:
152 wall.spawn_degrees(location=[x*wall_length + offset[0], -(y*wall_length + wall_length) + offset[1], 0.001], rotation=[0, 0, 90], waitForConfirmation=dynamic_walls)
153 else:
154 wall.spawn_degrees(location=[x*wall_length-wall_length/2 + offset[0], -(y*wall_length + wall_length/2) + offset[1], 0.001], rotation=[0, 0, 0], waitForConfirmation=dynamic_walls)
155
156 if (dynamic_walls):
157 wall.set_enable_dynamics(dynamic_walls)
158
159
160
161
162def main():
163
164 # Creates a server connection with Quanser Interactive Labs and manages
165 # the communications
166 qlabs = QuanserInteractiveLabs()
167
168 # Ensure that QLabs is running on your local machine
169 print("Connecting to QLabs...")
170 if (not qlabs.open("localhost")):
171 print("Unable to connect to QLabs")
172 return
173
174 print("Connected")
175
176 # Set the window title
177 hSystem = QLabsSystem(qlabs)
178 hSystem.set_title_string('Walls Tutorial')
179
180 num_destroyed = qlabs.destroy_all_spawned_actors()
181
182 # Initialize an instance of a camera
183 camera = QLabsFreeCamera(qlabs)
184
185 # Set the spawn of the camera in a specific location
186 camera.spawn([-0.337, 3.205, 4.895], [-0, 0.59, -1.091], [1, 1, 1], 0, 1)
187 camera.possess()
188
189 generate_maze()
190 draw_maze(qlabs)
191
192 # Closing qlabs
193 qlabs.close()
194 print('Done!')
195
196if __name__ == "__main__":
197 main()
Matlab Tutorial
Raw to download this tutorial: Walls Tutorial (.m)
.
1% Walls Example
2% -------------------------
3%
4% .. note::
5%
6% Make sure you have Quanser Interactive Labs open before running this
7% example. This example is designed to be run in the Plane, Studio,
8% or Warehouse environments.
9
10% --------------------------------------------------------------
11% Setting MATLAB Path for the libraries
12% Always keep at the start, it will make sure it finds the correct references
13newPathEntry = fullfile(getenv('QAL_DIR'), 'libraries', 'matlab', 'qvl');
14pathCell = regexp(path, pathsep, 'split');
15if ispc % Windows is not case-sensitive
16 onPath = any(strcmpi(newPathEntry, pathCell));
17else
18 onPath = any(strcmp(newPathEntry, pathCell));
19end
20
21if onPath == 0
22 path(path, newPathEntry)
23 savepath
24end
25% --------------------------------------------------------------
26
27
28% Open communications
29qlabs = QuanserInteractiveLabs();
30connection_established = qlabs.open('localhost');
31
32if connection_established == false
33 disp("Failed to open connection.")
34 return
35end
36
37disp('Connected')
38
39% Remove any existing actors
40num_destroyed = qlabs.destroy_all_spawned_actors();
41
42% Initialize an instance of a custom camera
43camera = QLabsFreeCamera(qlabs);
44camera.spawn([2.295, -3.826, 1.504], [-0, 0.213, 1.957]);
45camera.possess();
46
47
48% Initialize instances of walls
49wall = QLabsWalls(qlabs);
50
51% Use 'for' loops to spawn a line of walls
52for y = 0:5
53 wall.spawn_degrees([-0.5, y*1.05, 0.001]);
54end
55
56% Spawn a second line of walls but enable the dynamics
57for y = 0:5
58 wall.spawn_degrees([0.5, y*1.05, 0.001]);
59
60 % Enable dynamics for this set of walls
61 wall.set_enable_dynamics(true);
62end
63
64
65% Spawn a large sphere to demonstrate which walls are dynamic
66sphere = QLabsBasicShape(qlabs);
67sphere.spawn([0,2,3], [0,0,0], [1.5,1.5,1.5], sphere.SHAPE_SPHERE);
68sphere.set_enable_dynamics(true);
69
70% Closing qlabs
71qlabs.close();
72disp('Done!');
Maze
Raw to download this tutorial: Wall Maze Tutorial (.m)
.
1% Wall Maze Example
2% -------------------------
3%
4% .. note::
5%
6% Make sure you have Quanser Interactive Labs open before running this
7% example. This example is designed to be run in the Plane, Studio,
8% or Warehouse environments.
9
10% Define globals
11global North;
12global East;
13global South;
14global West;
15global Unexplored;
16global maze_data;
17global maze_x;
18global maze_y;
19
20load_qvl_path()
21
22% Do you want the walls to be able to fall over if hit? (Maze generation will take slightly longer.)
23dynamic_walls = false;
24
25% Maze size
26maze_x = 10;
27maze_y = 10;
28
29% Initialize constants and variables. We'll use a bit mask to efficiently store multiple
30% pieces of information inside a single value.
31North = 0b00001;
32East = 0b00010;
33South = 0b00100;
34West = 0b01000;
35Unexplored = 0b10000;
36maze_data = uint8(ones(maze_x,maze_y)) * 0b11111; % (bit-or of N, E, S, W, and unexplored)
37
38
39% Open communications
40qlabs = QuanserInteractiveLabs();
41connection_established = qlabs.open('localhost');
42
43if connection_established == false
44 disp("Failed to open connection.")
45 return
46end
47
48disp('Connected')
49
50% Remove any existing actors
51num_destroyed = qlabs.destroy_all_spawned_actors();
52
53% Initialize an instance of a custom camera
54camera = QLabsFreeCamera(qlabs);
55camera.spawn([-0.337, 3.205, 4.895], [-0, 0.59, -1.091]);
56camera.possess();
57
58
59% Initialize instances of walls
60wall = QLabsWalls(qlabs);
61
62generate_maze();
63draw_maze(qlabs, dynamic_walls);
64
65% Closing qlabs
66qlabs.close();
67disp('Done!');
68
69
70
71
72function load_qvl_path()
73
74 % --------------------------------------------------------------
75 % Setting MATLAB Path for the libraries
76 % Always keep at the start, it will make sure it finds the correct references
77 newPathEntry = fullfile(getenv('QAL_DIR'), 'libraries', 'matlab', 'qvl');
78 pathCell = regexp(path, pathsep, 'split');
79 if ispc % Windows is not case-sensitive
80 onPath = any(strcmpi(newPathEntry, pathCell));
81 else
82 onPath = any(strcmp(newPathEntry, pathCell));
83 end
84
85 if onPath == 0
86 path(path, newPathEntry)
87 savepath
88 end
89 % --------------------------------------------------------------
90end
91
92function generate_maze()
93 global North;
94 global East;
95 global South;
96 global West;
97 global Unexplored;
98 global maze_data;
99 global maze_x;
100 global maze_y;
101
102 location = [1, 1];
103
104 % Mark the first cell as explored and remove the North wall as the entrance to the maze
105 maze_data(1,1) = bitand(bitand(maze_data(1,1), bitcmp(Unexplored)), bitcmp(North));
106
107 % Start digging through the maze recursively
108 remove_maze_wall(location);
109
110 % Remove one wall on the South side of the maze
111 maze_data(1,maze_y) = bitand(maze_data(1,maze_y), bitcmp(South));
112end
113
114function remove_maze_wall(location)
115 global North;
116 global East;
117 global South;
118 global West;
119 global Unexplored;
120 global maze_data;
121 global maze_x;
122 global maze_y;
123
124 % first pick a random direction (N, S, W, E) (The order helps reduce "easy" solutions to the maze)
125 first_direction = randi([1 4]);
126
127 % Check all four compass directions for a valid travel path
128 for direction = 1:4
129
130 % Offset the direction count by the random direction
131 current_direction = (direction + first_direction);
132 if current_direction > 4
133 current_direction = current_direction - 4;
134 end
135
136 if (current_direction == 1)
137 if ((location(2) > 1) && (bitand(maze_data(location(1), location(2)-1), Unexplored)))
138 % Remove North wall from the current cell and the South wall of the new cell and mark the new cell as explored
139 maze_data(location(1), location(2)-1) = bitand(maze_data(location(1), location(2)-1), bitcmp(Unexplored));
140 maze_data(location(1), location(2)-1) = bitand(maze_data(location(1), location(2)-1), bitcmp(South));
141 maze_data(location(1), location(2)) = bitand(maze_data(location(1), location(2)), bitcmp(North));
142
143 remove_maze_wall([location(1), location(2)-1]);
144 end
145
146 elseif (current_direction == 2)
147 if ((location(2) < (maze_y)) && (bitand(maze_data(location(1), location(2)+1), Unexplored)))
148 % Remove South wall from the current cell and the North wall of the new cell and mark the new cell as explored
149 maze_data(location(1), location(2)+1) = bitand(maze_data(location(1), location(2)+1), bitcmp(Unexplored));
150 maze_data(location(1), location(2)+1) = bitand(maze_data(location(1), location(2)+1), bitcmp(North));
151 maze_data(location(1), location(2)) = bitand(maze_data(location(1), location(2)), bitcmp(South));
152
153 remove_maze_wall([location(1), location(2)+1]);
154 end
155
156 elseif (current_direction == 3)
157 if ((location(1) > 1) && (bitand(maze_data(location(1)-1, location(2)), Unexplored)))
158 % Remove West wall from the current cell and the East wall of the new cell and mark the new cell as explored
159 maze_data(location(1)-1, location(2)) = bitand(maze_data(location(1)-1, location(2)), bitcmp(Unexplored));
160 maze_data(location(1)-1, location(2)) = bitand(maze_data(location(1)-1, location(2)), bitcmp(East));
161 maze_data(location(1), location(2)) = bitand(maze_data(location(1), location(2)), bitcmp(West));
162
163 remove_maze_wall([location(1)-1, location(2)]);
164 end
165
166 else
167 if ((location(1) < (maze_x)) && (bitand(maze_data(location(1)+1, location(2)), Unexplored)))
168 % Remove East wall from the current cell and the West wall of the new cell and mark the new cell as explored
169 maze_data(location(1)+1, location(2)) = bitand(maze_data(location(1)+1, location(2)), bitcmp(Unexplored));
170 maze_data(location(1)+1, location(2)) = bitand(maze_data(location(1)+1, location(2)), bitcmp(West));
171 maze_data(location(1), location(2)) = bitand(maze_data(location(1), location(2)), bitcmp(East));
172
173 remove_maze_wall([location(1)+1, location(2)]);
174 end
175 end
176 end
177end
178
179
180function draw_maze(qlabs, dynamic_walls)
181 global North;
182 global East;
183 global South;
184 global West;
185 global maze_data;
186 global maze_x;
187 global maze_y;
188
189 % Initialize a wall object
190 wall = QLabsWalls(qlabs);
191
192 % add just the first top row
193 for count_x = 1:maze_x
194 if (bitand(maze_data(count_x, 1), North))
195 place_wall(wall, count_x, 1, North, dynamic_walls);
196 end
197 end
198
199 for count_y = 1:maze_y
200 % left most wall of the maze
201 if (bitand(maze_data(1, count_y), West))
202 place_wall(wall, 1, count_y, West, dynamic_walls);
203 end
204
205 % all the rest of the walls
206 for count_x = 1:maze_x
207 if (bitand(maze_data(count_x, count_y), South))
208 place_wall(wall, count_x, count_y, South, dynamic_walls);
209 end
210
211 if (bitand(maze_data(count_x, count_y), East))
212 place_wall(wall, count_x, count_y, East, dynamic_walls);
213 end
214 end
215
216 if (~dynamic_walls)
217 % If we're not waiting for any responses from QLabs, add
218 % a slight delay after each row to ensure we don't overflow
219 % the buffers for really large mazes.
220 pause(0.01);
221 end
222 end
223end
224
225
226function place_wall(wall, x, y, direction, dynamic_walls)
227 global North;
228 global East;
229 global South;
230 global West; %#ok<NUSED>
231
232 % You can tweak the global x/y offset of the maze generation here by entering a position in meters.
233 offset = [0, 0];
234
235 % Length of a wall segment plus a bit of padding
236 wall_length = 1.05;
237
238 % Walls are static by default so we only need to wait for confirmation if the dynamic_walls flag is set.
239
240 if direction == North
241 wall.spawn_degrees([x*wall_length + offset(1), -(y*wall_length) + offset(2), 0.001], [0, 0, 90], [1,1,1], 0, dynamic_walls);
242
243 elseif direction == East
244 wall.spawn_degrees([x*wall_length + wall_length/2 + offset(1), -(y*wall_length + wall_length/2) + offset(2), 0.001], [0, 0, 0], [1,1,1], 0, dynamic_walls);
245
246 elseif direction == South
247 wall.spawn_degrees([x*wall_length + offset(1), -(y*wall_length + wall_length) + offset(2), 0.001], [0, 0, 90], [1,1,1], 0, dynamic_walls);
248 else
249 wall.spawn_degrees([x*wall_length-wall_length/2 + offset(1), -(y*wall_length + wall_length/2) + offset(2), 0.001], [0, 0, 0], [1,1,1], 0, dynamic_walls);
250 end
251
252 if (dynamic_walls)
253 wall.set_enable_dynamics(dynamic_walls);
254 end
255end