You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: graphics/README.md
+229-4Lines changed: 229 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
This folder contains the graphics functionality of the toolbox.
2
-
3
-
Instructions on how to use the graphical section of the toolbox to come.
2
+
Instructions on how to use the graphical section of the toolbox below.
3
+
(Pictures to come)
4
4
5
5
# TODO
6
6
* Robot Joints
@@ -20,7 +20,6 @@ Instructions on how to use the graphical section of the toolbox to come.
20
20
* Option to save a mesh to STL?
21
21
* 2D Graphics
22
22
* Will likely not be done in vpython (overkill)
23
-
#
24
23
25
24
# Future Additions
26
25
* Updated Canvas Controls
@@ -31,4 +30,230 @@ Instructions on how to use the graphical section of the toolbox to come.
31
30
* Labels, reference frames, robot, etc
32
31
* Robot Interaction
33
32
* Use the mouse/keyboard to manually rotate/move joints
34
-
#
33
+
34
+
# How To
35
+
## Common Functionality
36
+
VPython has its own data types that have been used. Firstly, the `radians()`, and `degrees()` functions convert between radians and degrees.
37
+
The `vector` class is also very crucial to the graphics. It can either represent a vector or a 3D point.
38
+
39
+
For convenience, some functions and variables are provided for easy use. `wrap_to_pi()` takes in an angle, and specification on degrees or radians. It returns the respective angle between -pi and pi.
40
+
Three vectors are also supplied for readability to ensure correct axes are used when referencing. `x_axis_vector`, `y_axis_vector`, `z_axis_vector` can be used when supplying the rotation axis, for example.
41
+
```python
42
+
# Rotate the joint around its local x-axis by 30 degrees
Firstly, import the model_puma560 file to import all files/packages used within the graphics (imports are used within other files).
48
+
```python
49
+
from graphics.model_puma560 import*
50
+
```
51
+
Any use of VPython objects requires a scene.
52
+
53
+
To create a scene to draw object to, a canvas must be created. Upon creation, a localhost http server will be opened. The function will return a GraphicsGrid object.
54
+
55
+
Different attributes can be supplied to the function for some customisation. The display width, height, title, and caption can be manually input. Lastly, a boolean representing the grid visibility can be set.
56
+
```python
57
+
# Create a default canvas (1000*500, with grid displayed, no title or caption)
58
+
canvas_grid = init_canvas()
59
+
60
+
# Alternatively create a grid with specified parameters
61
+
canvas_grid = init_canvas(height=768, width=1024, title="Scene 1", caption="This scene shows...", grid=False)
62
+
```
63
+
The GraphicsGrid object has functions to update the visual, or to toggle visibility.
64
+
```python
65
+
# Update the grids to relocate/reorient to the camera focus point
66
+
canvas_grid.update_grid()
67
+
68
+
# Turn off the visual display of the grid
69
+
canvas_grid.set_visibility(False)
70
+
```
71
+
Now that the scene is created, a robot must be created to be displayed.
72
+
73
+
## Displaying Robot Joints
74
+
If you want to use the example puma560 robot, simply call the creation function that will return a GraphicalRobot object. It will automatically be displayed in the canvas
75
+
```python
76
+
# Import the puma560 models and return a GraphicalRobot object
77
+
puma560 = import_puma_560()
78
+
```
79
+
80
+
Creating your own robot is just as easy with the ability to use STL objects for your own custom robot, or using simple line segments.
81
+
Importing the STL objects is described below. Once you have the created 3D objects from the import, they can be used in the constructors.
82
+
83
+
Firstly, decide which type of joint you require: `RotationalJoint`, `PrismaticJoint`, `StaticJoint`, `Gripper`.
84
+
85
+
All joint types can be supplied with an `x_axis` parameter. Defaulting to `x_axis_vector`, this variable simply states which direction in space the object's current x-axis is pointing in. This allows alignment of reference frames, for example that objects aren't used sideways.
86
+
87
+
Rotational joints have an independent attribute `rotation_axis` to assign which axis the joint rotates about, defaulting to `y_axis_vector`.
88
+
89
+
If using an STL object, the connection parameters are the 3D points in space (real coordinates of where the object is currently) that correspond to the positions where the neighbour joints connect to it.
90
+
For example, if the object is currently loaded in with the point where it would connect to a previous segment at (0, 0, 0), and the 'tooltip' or point it would connect to the next joint at (1, 0, 0), the creation would look like
91
+
```python
92
+
# Current connection points
93
+
connect_from = vector(0, 0, 0)
94
+
connect_to = vector(1, 0, 0)
95
+
96
+
# Create a Rotational joint that is currently facing in the +x direction, that rotates about it's y-axis
97
+
new_link = RotationalJoint(connect_from,
98
+
connect_to,
99
+
x_axis=x_axis_vector,
100
+
rotation_axis=y_axis_vector,
101
+
graphic_obj=your_stl_obj)
102
+
```
103
+
Otherwise if no prior 3D object is given, a line segment will be created to render as the joint. The `x_axis` attribute is not used in this situation.
104
+
```python
105
+
# The current joint will go from (1, 1, 0) to (1, 1, 3)
Importing an STL can either be straight-forward or a bit tedious. Firstly, import the STL file into VPython using `import_object_from_stl()`.
142
+
This will create a compound object from the triangles, and display it in the canvas.
143
+
```python
144
+
# Create a compound object from an STL file 'my_object'
145
+
# The search path is relative to ./graphics/models/
146
+
# Only the filename is required (no extension)
147
+
my_mesh = import_object_from_stl('my_object')
148
+
```
149
+
Then depending on where the object triangles are configured from the file, it may need to be translated or rotated.
150
+
151
+
The Joint classes assume that the origin of the joint is the rotation point. However, creating a compound object puts the origin at the centre of the 3D bounding box.
152
+
Since these positions may not align, translation and/or rotation may be required.
153
+
154
+
If the loaded object was not oriented correctly upon loading, it can be manually rotated (preferably before setting the origin described below).
155
+
Manual inspection of the objects orientation will guide to how to rotate the object in space. They can be easily rotated through VPython's object rotate function
A function `set_stl_origin()` is also supplied to change the origin.
164
+
This function takes in a graphical object, and two 3D points representing the world coordinates of where the desired origin currently is, and where the desired origin should be.
165
+
166
+
For example, if an STL object loads in and the origin is below (-z) where it should be, and the origin is at the bottom of the object, the following code will translate it up and set the origin.
167
+
```python
168
+
# Load the mesh
169
+
my_stl_obj = import_object_from_stl('my_object')
170
+
171
+
# Find the coordinates of where the desired origin is
172
+
# It's at the bottom of the object, that is entirely below the z=0 plane
173
+
174
+
# Z coordinate is located from the middle of the object, with an extra distance of half the object away.
The STL objects can now be used in the Joint classes without hassle.
185
+
186
+
## Creating a GraphicalRobot
187
+
Now that you have created all of the robot links, a `GraphicalRobot` can be created. Simply inputting a list of the joints to the constructor is all that is required.
188
+
189
+
The order of joints is important! It is assumed that index 0 is the base, and incrementally goes through the robot from base to tooltip.
190
+
```python
191
+
# Create a default 3-link rotational robot along the +X axis.
Moving the robot around in the 3D space is possible through `move_base()`. Given a 3D coordinate, the origin of the base will be relocated to this position.
225
+
```python
226
+
# Move the base of the robot to (2, 3, 0)
227
+
my_graphic_robot.move_base(vector(2, 3, 0))
228
+
```
229
+
Setting joint angles can be done in two ways. Firstly, one joint can be rotated individually.
230
+
The function takes the joint index (from the list of creation) and an angle (radians) to set the joint angle to. The angle given is it's local rotation angle.
231
+
232
+
If a joint that is not a rotational joint is given, an error will be displayed.
233
+
```python
234
+
joint_index =1
235
+
new_angle = radians(30)
236
+
237
+
# Rotate the 1st joint of the robot (base = 0) to an angle of 30 degrees
Otherwise, all joint angles can be modified together.
241
+
If the given list of angles doesn't match the number of joints, an error will be displayed.
242
+
Further, while iterating through the joints, a message will appear saying a non-revolute was found. It will skip this joint and it's associated given angle.
243
+
```python
244
+
# Assuming a 3-joint all-rotational robot
245
+
my_graphical_robot.set_all_joint_angles([
246
+
radians(-45),
247
+
radians(45),
248
+
radians(15)
249
+
])
250
+
```
251
+
252
+
Lastly, a print function `print_joint_angles()` will print out the current local joint angles, if a revolute.
253
+
If the output angles are to be displayed in degrees, True should be input as a parameter.
0 commit comments