
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
    10 visualizaciones (últimos 30 días)
  
       Mostrar comentarios más antiguos
    
    Phembuvuyo
 el 23 de Oct. de 2025 a las 0:02
  
    
    
    
    
    Respondida: Mathieu NOE
      
 el 23 de Oct. de 2025 a las 9:10
            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 comentarios
Respuestas (1)
  Mathieu NOE
      
 el 23 de Oct. de 2025 a las 9:10
        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 comentarios
Ver también
Categorías
				Más información sobre Parallel for-Loops (parfor) en Help Center y File Exchange.
			
	Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

