
I'm trying to come up with the workspace for my 3RRR pkm via discretization method. Solid edge is used to validate and code seems to be generating an overestimated workspace
7 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
clear; clc; close all;
% Workspace Discretization
x_range = -500:5:500;
y_range = -500:5:500;
% Link lengths
link1 = 300;
link2 = 375;
link3 = 47.75;
% End effector parameters
psi = pi/6;
psi_rad = psi;
% Base positions for 3 legs - straight up orientation
base_angle = 2*pi/3;
base_radius = 337.5;
base1 = [0, base_radius];
base2 = [base_radius * sin(base_angle), base_radius * cos(base_angle)];
base3 = [base_radius * sin(2*base_angle), base_radius * cos(2*base_angle)];
% Initialize workspace points
valid_points = [];
total_points = 0;
valid_count = 0;
for a_ix = x_range
for a_iy = y_range
total_points = total_points + 1;
valid_leg1 = false;
valid_leg2 = false;
valid_leg3 = false;
%end effector position
x_ee = a_ix + link3 * cos(psi_rad);
y_ee = a_iy + link3 * sin(psi_rad);
% Check Leg 1
x_rel1 = x_ee - base1(1);
y_rel1 = y_ee - base1(2);
e1_1 = x_rel1^2 + y_rel1^2 + link1^2 - link2^2;
e2_1 = -2 * x_rel1 * link1;
e3_1 = -2 * y_rel1 * link1;
discriminant1 = e3_1^2 + e2_1^2 - e1_1^2;
if discriminant1 >= 0
valid_leg1 = true;
end
% Check Leg 2
x_rel2 = x_ee - base2(1);
y_rel2 = y_ee - base2(2);
e1_2 = x_rel2^2 + y_rel2^2 + link1^2 - link2^2;
e2_2 = -2 * x_rel2 * link1;
e3_2 = -2 * y_rel2 * link1;
discriminant2 = e3_2^2 + e2_2^2 - e1_2^2;
if discriminant2 >= 0
valid_leg2 = true;
end
% Check Leg 3
x_rel3 = x_ee - base3(1);
y_rel3 = y_ee - base3(2);
e1_3 = x_rel3^2 + y_rel3^2 + link1^2 - link2^2;
e2_3 = -2 * x_rel3 * link1;
e3_3 = -2 * y_rel3 * link1;
discriminant3 = e3_3^2 + e2_3^2 - e1_3^2;
if discriminant3 >= 0
valid_leg3 = true;
end
if valid_leg1 && valid_leg2 && valid_leg3
valid_count = valid_count + 1;
valid_points(valid_count, :) = [a_ix, a_iy];
end
end
end
% Area computation
point_spacing = 5;
area = valid_count * (point_spacing * point_spacing);
fprintf('Area: %.2f mm²\n', area);
% Comparison to reference area
reference_area = 369865.10;
percentage = (area / reference_area) * 100;
fprintf('Percentage similarity to solid edge area: %.2f%%\n', percentage);
% Plot workspace
plot(valid_points(:,1), valid_points(:,2), 'b.', 'MarkerSize', 1);
axis equal;
grid on;
title('3RRR PKM Workspace');
xlabel('X (mm)');
ylabel('Y (mm)');
0 Kommentare
Antworten (1)
Mathieu NOE
vor etwa 2 Stunden
hello
I tried to reduce the error by using a more precise area computation aproach using polyarea
I had to modify a bit your original code (like creating the "non valid points" that correspond to the 3 inner disk areas) , then used dbscan (abit modified too - original version is available here : DBSCAN Clustering Algorithm - File Exchange - MATLAB Central ) then again used polyarea to compute those disk areas
the net area is the outer shape (obtained with boundary) area minus the 3 disks areas .
Seems there is still a bit of overestimation (2% instad of 3%) .
Area: 380650.00 mm²
Your Percentage similarity to solid edge area: 102.92%
Boundary Area # 1 = 428325
Boundary Area # 2 = 17000
Boundary Area # 3 = 16987.5
Boundary Area # 4 = 16912.5
My Percentage similarity to solid edge area: 102.04%
When increasing the resolution , the difference gets even less noticeable (dx = dy = 2 instead of 5)
Area: 380700.00 mm²
Your Percentage similarity to solid edge area: 102.93%
Boundary Area # 1 = 431528
Boundary Area # 2 = 17442
Boundary Area # 3 = 17444
Boundary Area # 4 = 17434
My Percentage similarity to solid edge area: 102.53%
which prompts the question : could it be that SolidEdge does overestimate the area ??
here your code a bit modified + the required dbscan related functions (customized) in attachment
hope it helps
plot with dx = dy = 5

code
clear; clc; close all;
% Workspace Discretization
dx = 5;
dy = dx;
x_range = -500:dx:500;
y_range = -500:dy:500;
% Link lengths
link1 = 300;
link2 = 375;
link3 = 47.75;
% End effector parameters
psi = pi/6;
psi_rad = psi;
% Base positions for 3 legs - straight up orientation
base_angle = 2*pi/3;
base_radius = 337.5;
base1 = [0, base_radius];
base2 = [base_radius * sin(base_angle), base_radius * cos(base_angle)];
base3 = [base_radius * sin(2*base_angle), base_radius * cos(2*base_angle)];
% Initialize workspace points
valid_points = [];
not_valid_points = [];
total_points = 0;
valid_count = 0;
for a_ix = x_range
for a_iy = y_range
total_points = total_points + 1;
valid_leg1 = false;
valid_leg2 = false;
valid_leg3 = false;
%end effector position
x_ee = a_ix + link3 * cos(psi_rad);
y_ee = a_iy + link3 * sin(psi_rad);
% Check Leg 1
x_rel1 = x_ee - base1(1);
y_rel1 = y_ee - base1(2);
e1_1 = x_rel1^2 + y_rel1^2 + link1^2 - link2^2;
e2_1 = -2 * x_rel1 * link1;
e3_1 = -2 * y_rel1 * link1;
discriminant1 = e3_1^2 + e2_1^2 - e1_1^2;
if discriminant1 >= 0
valid_leg1 = true;
end
% Check Leg 2
x_rel2 = x_ee - base2(1);
y_rel2 = y_ee - base2(2);
e1_2 = x_rel2^2 + y_rel2^2 + link1^2 - link2^2;
e2_2 = -2 * x_rel2 * link1;
e3_2 = -2 * y_rel2 * link1;
discriminant2 = e3_2^2 + e2_2^2 - e1_2^2;
if discriminant2 >= 0
valid_leg2 = true;
end
% Check Leg 3
x_rel3 = x_ee - base3(1);
y_rel3 = y_ee - base3(2);
e1_3 = x_rel3^2 + y_rel3^2 + link1^2 - link2^2;
e2_3 = -2 * x_rel3 * link1;
e3_3 = -2 * y_rel3 * link1;
discriminant3 = e3_3^2 + e2_3^2 - e1_3^2;
if discriminant3 >= 0
valid_leg3 = true;
end
if valid_leg1 && valid_leg2 && valid_leg3
valid_count = valid_count + 1;
valid_points(valid_count, :) = [a_ix, a_iy];
else
not_valid_points = [not_valid_points; a_ix, a_iy];
end
end
end
% Area computation
point_spacing = dx;
area = valid_count * (point_spacing * point_spacing);
fprintf('Area: %.2f mm²\n', area);
% Comparison to reference area
reference_area = 369865.10;
percentage = (area / reference_area) * 100;
fprintf('Your Percentage similarity to solid edge area: %.2f%%\n', percentage);
% Plot workspace
plot(valid_points(:,1), valid_points(:,2), 'w.', 'MarkerSize', 6);
axis equal;
grid on;
title('3RRR PKM Workspace');
xlabel('X (mm)');
ylabel('Y (mm)');
%% added code
hold on
shrinkFactor = 1; % Adjust shrink factor (0 < shrinkFactor <= 1)
k = boundary(valid_points(:,1), valid_points(:,2), shrinkFactor); % Get boundary indices
plot(valid_points(k,1), valid_points(k,2), 'r-','linewidth',2);
area1 = polyarea(valid_points(k,1), valid_points(k,2)); % Calculate the area of the boundary
disp(['Boundary Area # 1 = ', num2str(area1)]);
% remove not_valid_points that are outside the boundary of the valide
% points
in = inpolygon(not_valid_points(:,1), not_valid_points(:,2),valid_points(k,1),valid_points(k,2));
not_valid_points = not_valid_points(in,:);
%% Run DBSCAN Clustering Algorithm
epsilon=20;
MinPts=10;
IDX=DBSCAN(not_valid_points,epsilon,MinPts);
area2 = PlotClusterinResult(not_valid_points, IDX);
Net_area = area1 - sum(area2);
percentage = (Net_area / reference_area) * 100;
fprintf('My Percentage similarity to solid edge area: %.2f%%\n', percentage);
0 Kommentare
Siehe auch
Kategorien
Mehr zu Parallel for-Loops (parfor) finden Sie in Help Center und File Exchange
Produkte
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!