need help with the mirroring function

48 vues (au cours des 30 derniers jours)
Keryous
Keryous le 26 Nov 2024 à 18:21
Réponse apportée : Abhas le 2 Déc 2024 à 3:28
I need help mirroring a scissors lift on my code. I have one side done but I can't seem to get the other. if you run it, you will see what I am talking about.
% Parameters and Initialization
clear;
clc;
close all;
% Parameters
L = 1; % Length of each bar (assume equal length for simplicity)
num_sections = 4; % Number of scissor sections (adjustable)
theta_input = linspace(0, pi/3, 100); % Input angle range (0 to 60 degrees)
base_width = 2 * L; % Distance between the fixed points D and F
% Fixed points
D = [1, 1]; % Base fixed point on the left
F = [base_width, 2]; % Base fixed point on the right
% Pre-allocate for animation data
positions = zeros(length(theta_input), 2 * num_sections + 4, 2); % [x, y] of all joints
velocities = zeros(length(theta_input) - 1, 2 * num_sections + 4, 2); % [vx, vy]
accelerations = zeros(length(theta_input) - 2, 2 * num_sections + 4, 2); % [ax, ay]
% Kinematic Simulation: Compute Joint Positions
for i = 1:length(theta_input)
% Input angle (1-DOF motion)
theta = theta_input(i);
% Initialize joint positions
joints = zeros(2 * num_sections + 4, 2); % Joint coordinates [x, y]
joints(1, :) = D; % Fixed point D (bottom-left)
joints(end, :) = F; % Fixed point F (bottom-right)
% Compute joint positions section by section
for j = 1:num_sections
% Bottom-left joint of the current section
joints(2 * j, :) = [joints(2 * j - 1, 1) + L * cos(theta), joints(2 * j - 1, 2) + L * sin(theta)];
% Top-right joint of the current section
joints(2 * j + 1, :) = [joints(2 * j, 1) + L * cos(pi - theta), joints(2 * j, 2) + L * sin(pi - theta)];
% Top-left joint of the current section
joints(2 * j + 2, :) = [joints(2 * j + 1, 1) - L * cos(theta), joints(2 * j + 1, 2) - L * sin(theta)];
end
% Store positions for animation
positions(i, :, :) = joints;
end
% Compute velocities and accelerations using finite differences
dt = theta_input(2) - theta_input(1); % Time step
for i = 2:length(theta_input)
velocities(i - 1, :, :) = (positions(i, :, :) - positions(i - 1, :, :)) / dt; % Velocity
end
for i = 2:size(velocities, 1)
accelerations(i - 1, :, :) = (velocities(i, :, :) - velocities(i - 1, :, :)) / dt; % Acceleration
end
% Animation: Visualize the Full Scissors Lift in Motion
figure;
hold on;
axis equal;
xlim([-0.5, base_width + 0.5]);
ylim([-0.5, 2 * num_sections + 0.5]);
title('Full Scissors Lift Mechanism Animation');
xlabel('X Position (m)');
ylabel('Y Position (m)');
% Plot and animate
for i = 1:length(theta_input)
joints = squeeze(positions(i, :, :));
% Clear figure
clf;
% Draw the fixed points
plot(D(1), D(2), 'ro', 'MarkerSize', 8, 'LineWidth', 2); % Fixed point D
hold on;
plot(F(1), F(2), 'ro', 'MarkerSize', 8, 'LineWidth', 2); % Fixed point F
% Draw the scissor links
for j = 1:num_sections
%Bottom linkage (left to right)
plot([joints(2 * j - 1, 1), joints(2 * j, 1)], ...
[joints(2 * j - 1, 2), joints(2 * j, 2)], 'b-', 'LineWidth', 2);
%Top linkage (right to left)
plot([joints(2 * j, 1), joints(2 * j + 1, 1)], ...
[joints(2 * j, 2), joints(2 * j + 1, 2)], 'r-', 'LineWidth', 2);
%Vertical linkage connecting sections
plot([joints(2 * j + 2, 1), joints(2 * j, 1)], ...
[joints(2 * j + 2, 2), joints(2 * j, 2)], 'k--', 'LineWidth', 1.5);
end
% Pause for animation effect
pause(0.05);
end
% 3D Plots
% Position vs Input Angle
figure;
plot3(theta_input, squeeze(positions(:, 2, 1)), squeeze(positions(:, 2, 2)), 'b-', 'LineWidth', 1.5);
grid on;
xlabel('Input Angle (rad)');
ylabel('X Position (m)');
zlabel('Y Position (m)');
title('3D Plot of Joint Positions');
% Velocity vs Input Angle
figure;
plot3(theta_input(1:end-1), squeeze(velocities(:, 2, 1)), squeeze(velocities(:, 2, 2)), 'r-', 'LineWidth', 1.5);
grid on;
xlabel('Input Angle (rad)');
ylabel('X Velocity (m/s)');
zlabel('Y Velocity (m/s)');
title('3D Plot of Joint Velocities');
% Acceleration vs Input Angle
figure;
plot3(theta_input(1:end-2), squeeze(accelerations(:, 2, 1)), squeeze(accelerations(:, 2, 2)), 'g-', 'LineWidth', 1.5);
grid on;
xlabel('Input Angle (rad)');
ylabel('X Acceleration (m/s^2)');
zlabel('Y Acceleration (m/s^2)');
title('3D Plot of Joint Accelerations');

Réponses (1)

Abhas
Abhas le 2 Déc 2024 à 3:28
Hello, @Keryous,
The problem in mirroring the scissor lift stems from the way joint positions are calculated for the sections. Your existing code expects that all computations are performed sequentially along one side, beginning at the fixed point D and progressing across sections. To accomplish symmetry (mirroring the scissors lift), calculate and place the joints on both sides consistently by following the below steps:
  • The "mirrored_joints" array calculates the x-coordinates of the mirrored side using the formula:
mirrored_x = 2×mid_xoriginal_x
  • This ensures that the right-side joints are symmetric with respect to the vertical axis passing through "mid_x".
Here's a MATLAB code reflecting the above steps:
% Parameters and Initialization
clear;
clc;
close all;
% Parameters
L = 1; % Length of each bar
num_sections = 4; % Number of scissor sections
theta_input = linspace(0, pi/3, 100); % Input angle range (0 to 60 degrees)
base_width = 2 * L; % Distance between the fixed points D and F
% Fixed points
D = [1, 1]; % Base fixed point on the left
F = [base_width, 1]; % Base fixed point on the right
mid_x = (D(1) + F(1)) / 2; % Midpoint for symmetry axis
% Pre-allocate for animation data
positions = []; % Use a dynamic array to avoid pre-allocation issues
% Kinematic Simulation: Compute Joint Positions
for i = 1:length(theta_input)
theta = theta_input(i); % Input angle (1-DOF motion)
% Initialize joint positions for the left side
left_joints = zeros(2 * num_sections + 2, 2); % Joints for the left side
left_joints(1, :) = D; % Fixed point D
% Compute joints for the left side
for j = 1:num_sections
% Bottom-left and top-right joint positions
left_joints(2 * j, :) = left_joints(2 * j - 1, :) + [L * cos(theta), L * sin(theta)];
left_joints(2 * j + 1, :) = left_joints(2 * j, :) + [L * cos(pi - theta), L * sin(pi - theta)];
end
left_joints(end, :) = F; % Fixed point F on the left side
% Compute mirrored joints
mirrored_joints = left_joints;
mirrored_joints(:, 1) = 2 * mid_x - left_joints(:, 1); % Reflect x-coordinates
% Combine left and mirrored joints
all_joints = [left_joints; mirrored_joints(end-1:-1:1, :)];
% Store joint positions for the current frame
positions{i} = all_joints; % Use cell array for dynamic sizing
end
% Determine the maximum number of joints across all frames
max_joints = max(cellfun(@(x) size(x, 1), positions));
% Convert cell array to a 3D matrix, padding with NaNs if necessary
positions_matrix = NaN(length(theta_input), max_joints, 2);
for i = 1:length(theta_input)
frame_joints = positions{i};
positions_matrix(i, 1:size(frame_joints, 1), :) = frame_joints;
end
% Animation: Visualize the Full Scissors Lift in Motion
figure;
hold on;
axis equal;
xlim([0, base_width + 1]);
ylim([0, 2 * num_sections + 1]);
title('Scissor Lift Mechanism');
xlabel('X Position');
ylabel('Y Position');
% Plot and animate
for i = 1:length(theta_input)
all_joints = squeeze(positions_matrix(i, :, :));
all_joints(isnan(all_joints(:, 1)), :) = []; % Remove NaN rows for plotting
clf;
hold on;
% Draw fixed points
plot(D(1), D(2), 'ro', 'MarkerSize', 8, 'LineWidth', 2);
plot(F(1), F(2), 'ro', 'MarkerSize', 8, 'LineWidth', 2);
% Draw scissor links
num_joints = size(all_joints, 1) / 2; % Half the joints are mirrored
for j = 1:num_sections
% Left side
plot([all_joints(2 * j - 1, 1), all_joints(2 * j, 1)], ...
[all_joints(2 * j - 1, 2), all_joints(2 * j, 2)], 'b-', 'LineWidth', 2);
plot([all_joints(2 * j, 1), all_joints(2 * j + 1, 1)], ...
[all_joints(2 * j, 2), all_joints(2 * j + 1, 2)], 'r-', 'LineWidth', 2);
% Right side (mirrored)
k = size(all_joints, 1) - 2 * j + 2; % Index for mirrored side
plot([all_joints(k, 1), all_joints(k - 1, 1)], ...
[all_joints(k, 2), all_joints(k - 1, 2)], 'b-', 'LineWidth', 2);
plot([all_joints(k - 1, 1), all_joints(k - 2, 1)], ...
[all_joints(k - 1, 2), all_joints(k - 2, 2)], 'r-', 'LineWidth', 2);
% Vertical linkages
plot([all_joints(2 * j, 1), all_joints(k, 1)], ...
[all_joints(2 * j, 2), all_joints(k, 2)], 'k--', 'LineWidth', 1.5);
end
pause(0.05);
end
Output:
You may refer to the below documentation link to have a bettern understanding on transforming co-ordnates: https://www.mathworks.com/help/robotics/coordinate-system-transformations.html
I hope this helps!

Catégories

En savoir plus sur Animation dans Help Center et File Exchange

Produits

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by