I'm trying to simulate a robot reach bubble. The goal would be to export it into a CAD file and visualize the possible workspace. My approach was to plot all potential endpoints using forward kinematics for the robot, considering linkage lengths and joint limits. This may be a brute-force way to generate the endpoints (Rx, Ry, Rz), but it comes out to be very accurate (at least for 2D examples). [This image shows the provided workspace for an IRB robot and my results when plotting the points in 2D][1]
[1]: https://i.stack.imgur.com/g3cP7.jpg
I can display a three-dimensional figure of the bubble as a scatterplot; however, to export it into a CAD file, I need to mesh it first, which requires converting it into a surface, as I understand. This is the part I'm having trouble with.
Using matplotlib's ax.surface_plot(Rx, Ry, Rz) I receive an error stating that Rz must be a 2-dimensional value. I fiddled with np.meshgrid() and np.mgrid() functions but have been unable to create a simple surface of the bubble. What can I do to convert this scatterplot into a surface? Is there another approach that I'm missing?
Another thing that dawned on me is that I'd likely want to remove some of the intermediate points inside the reach bubble. Ideally, the surface would be composed of the outer ends and the hollow points from the center radius.
Below is a code that results in 1D arrays:
# Reach bubble 3D
import NumPy as np
import matplotlib.pyplot as plt
# Initialize figure and label axes
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
dr = np.pi/180 # Degree to radian multiple
pi = np.pi
# Define important robot dimensions and axis limits for IRB 1100
z0 = 0.327 # Fixed height from base to A1
link1 = 0.28
link2 = 0.3
a1 = np.linspace(0, 2*pi, 8) # Angle limits for axes
a2 = np.linspace(-115*dr, 113*dr, 12)
a3 = np.linspace(-205*dr, 55*dr, 12)
Rx = []
Ry = []
Rz = []
for i1 in a1:
for i2 in a2:
for i3 in a3:
r = link1*np.sin(i2) + link2*np.sin(pi/2+i2+i3)
Rx.append(r*np.cos(i1))
Ry.append(r*np.sin(i1))
Rz.append(z0 + link1*np.cos(i2) + link2*np.cos(pi/2+i2+i3))
# Plot reach points
ax.scatter(Rx, Ry, Rz, c='r', marker='o', alpha = 0.2)
plt.show()
Below is a code that results in 3D arrays but doesn't use for loops:
# 3D Reach bubble for robot
import numpy as np
import matplotlib.pyplot as plt
# Initialize figure and label axes
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
pi = np.pi
dr = pi/180 # Degree to radian multiple
# Define important robot dimensions and axis limits for GP8
z0 = 0.327 # Fixed height from base to A1
link1 = 0.28
link2 = 0.3
link3 = 0.064
a1, a2, a3 = np.mgrid[0:2*pi:15j, -115*dr:113*dr:13j, -205*dr:55*dr:17j]
r = link1*np.sin(a2) + link2*np.sin(pi/2+a2+a3)
Rx = r*np.cos(a1)
Ry = r*np.sin(a1)
Rz = z0 + link1*np.cos(a2) + link2*np.cos(pi/2+a2+a3)
# Plot reach points
ax.plot_surface(Rx, Ry, Rz, color = 'Red', alpha = 0.2)
ax.scatter(Rx, Ry, Rz, c='r', marker='o', alpha = 0.2)