Table of contents
Working in 3D is not too difficult once we get familiar with proper tools. Here we shall give a thorough walk-through of the process on a non-trivial example. The hardest part is the kinematics, i.e., describing the positions of the points relative to each other. Once this is done, formulating forces and moments to do equilibrium is a trivial matter with computer support.
We shall here learn to work with a rotated coordinate system.
, , , around the local -axis at and
Let denote the rotation of the shaft . In the picture above, the vector is parallel to the axis, and this is when .
The center of gravity can be defined using local coordinates as:
Similarly, we can define using local coordinates. See below for the definition of the local coordinates.
Given the spring constant of N/mm and the unloaded spring length of mm:
Determine and plot the length of the spring as well as the spring force .
Determine and plot the moment which the motor needs to generate to rotate the shaft AB, for
We are going to work with vectors to define the path from to and as a function of the rotation angle . To do this with our sanity in tact, we will introduce local coordinates and rotate these using rotation matrices.
We shall introduce the local vectors and and always let point in the direction of the path.
We start by getting to point using the vector . From here we need to establish the direction of the shaft axis, which we can do by rotating the vector around the -axis by degrees (using the right hand rule).
This gives our direction.
clear
ez = [0;0;1];
R_x = @(a) [1 0 0
0 cosd(a) -sind(a)
0 sind(a) cosd(a)];
R_y = @(a) [cosd(a) 0 sind(a)
0 1 0
-sind(a) 0 cosd(a)];
R_z = @(a) [cosd(a) -sind(a) 0
sind(a) cosd(a) 0
0 0 1];
theta1 = 35; theta2 = 30;
eAB = R_x(-theta1)*ez
eAB = 3x1
0
0.5736
0.8192
The shaft needs to rotate around its axis, or the . The rotation can be achieved by rotating around the global axis, and . From the initial configuration, see below, where the shaft axis is aligned with the -axis and oriented towards the -axis. To get the correct rotation of the shaft, we need to first rotate around the -axis and then around the -axis.
Mathematically, this is the same as rotating our coordinate system by
where is the identity matrix containing the Cartesian bases, i.e.,
Let us verify this by setting and , we expect
theta1 = 0; theta2 = 0;
X = R_x(theta1)*R_z(theta2)*eye(3)
X = 3x3
1 0 0
0 1 0
0 0 1
Now we can set and we should have that
theta1 = 0; theta2 = 90;
X = R_x(theta1)*R_z(theta2)*eye(3)
X = 3x3
0 -1 0
1 0 0
0 0 1
We can confirm this and also see that as it should.
Now we can rotate around the by , we should get
theta1 = -90; theta2 = 90;
X = R_x(theta1)*R_z(theta2)*eye(3)
X = 3x3
0 -1 0
0 0 1
-1 0 0
We can confirm that the new coordinates point in the expected directions.
Thus have confirmed that the rotation makes sense, we have built confidence in our model and can set the rotation to solve our problem:
theta1 = -35; theta2 = 0;
X = R_x(theta1)*R_z(theta2)*eye(3)
X = 3x3
1.0000 0 0
0 0.8192 0.5736
0 -0.5736 0.8192
eex = X(:,1); eey = X(:,2); eez = X(:,3);
Now we can easily model the rest of the points.
We do a final verification of the kinematics by visualizing the geometry in Matlab:
OA = [30, 60, 75]'; % mm
OE = [175, 105, 15]'; % mm
L_AB = 65; % mm
L_BC = 50; % mm
k = 0.2; % N/mm
L0 = 120; % mm
theta1 = 35; % deg
theta2 = 26; % deg
X = R_x(-theta1)*R_z(theta2)*eye(3);
eex = X(:,1); eey = X(:,2); eez = X(:,3);
AB = eez*L_AB;
BC = eex*L_BC;
CD = eex*70 + eez*40;
OD = OA + AB + BC + CD;
OB = OA+AB;
OC = OB+BC;
AD = OD - OA;
DE = OE - OD;
AG = 34*eex + 51*eez;
OG = OA + AG;
% Visualization
close all
figure
axis equal; hold on;
xlabel('x'); ylabel('y'); zlabel('z');
set(gcf,'Visible','on')
hp1 = plot3([OA(1), OB(1)], ...
[OA(2), OB(2)], ...
[OA(3), OB(3)], '-k', 'LineWidth',2);
htA = text(OA(1), OA(2), OA(3), 'A');
htB = text(OB(1), OB(2), OB(3), 'B');
hp2 = plot3([OB(1), OC(1)], ...
[OB(2), OC(2)], ...
[OB(3), OC(3)], '-k', 'LineWidth',2);
htC = text(OC(1), OC(2), OC(3), 'C');
hp3 = plot3([OC(1), OD(1)], ...
[OC(2), OD(2)], ...
[OC(3), OD(3)], '-k', 'LineWidth',2);
htD = text(OD(1), OD(2), OD(3), 'D');
hp4 = plot3([OD(1), OE(1)], ...
[OD(2), OE(2)], ...
[OD(3), OE(3)], '-m', 'LineWidth',2);
htE = text(OE(1), OE(2), OE(3), 'E');
hp5 = plot3(OG(1), OG(2), OG(3), 'ok', 'MarkerFaceColor','k');
view(3)
grid on
axis([0,200, -100, 250, 0, 250])
view(-69, 35)
view(2)
view(40, 32)
htitel = title(sprintf('$\\theta=%d^\\circ$',theta2),'interpreter','latex');
% Animation below
% exportgraphics(gca,"shaft3D.gif","Append",false)
%
% Az = [52, 80];
% El = [44, 74];
%
% view(52,44)
% Theta = [-90:1:90, 89:-1:-90];
% c = 1;
%
% for theta2 = Theta
% t = c/length(Theta);
% az = Az(1) + t*(Az(2)-Az(1));
% el = El(1) + t*(El(2)-El(1));
% view(az,el)
%
% X = R_x(-theta1)*R_z(theta2)*eye(3);
% eex = X(:,1); eey = X(:,2); eez = X(:,3);
%
% AB = eez*L_AB;
% BC = eex*L_BC;
% CD = eex*70 + eez*40;
%
% OD = OA + AB + BC + CD;
% OB = OA+AB;
% OC = OB+BC;
% AD = OD - OA;
% DE = OE - OD;
%
% AG = 34*eex + 51*eez;
% OG = OA + AG;
%
% set(hp1, 'XData', [OA(1), OB(1)], ...
% 'YData', [OA(2), OB(2)], ...
% 'ZData', [OA(3), OB(3)]);
% set(hp2, 'XData', [OB(1), OC(1)], ...
% 'YData', [OB(2), OC(2)], ...
% 'ZData', [OB(3), OC(3)])
% set(hp3, 'XData', [OC(1), OD(1)], ...
% 'YData', [OC(2), OD(2)], ...
% 'ZData', [OC(3), OD(3)])
% set(hp4, 'XData', [OD(1), OE(1)], ...
% 'YData', [OD(2), OE(2)], ...
% 'ZData', [OD(3), OE(3)])
% set(hp5, 'XData', OG(1), 'YData', OG(2), 'ZData', OG(3))
% set(htA, 'Position', [OA(1),OA(2), OA(3)])
% set(htB, 'Position', [OB(1),OB(2), OB(3)])
% set(htC, 'Position', [OC(1),OC(2), OC(3)])
% set(htD, 'Position', [OD(1),OD(2), OD(3)])
% set(htE, 'Position', [OE(1),OE(2), OE(3)])
% set(htitel,'String', sprintf('$\\theta=%d^\\circ$',theta2))
% drawnow
% c = c+1;
% exportgraphics(gca,"shaft3D.gif","Append",true)
% end
The spring force is modeled using
The moment at is the given by
where where g, and
Finally the moment around the axis is given by
Now we can plot the graphs using a symbolic
syms theta2 real
X = R_x(-theta1)*R_z(theta2)*eye(3);
eex = X(:,1); eey = X(:,2); eez = X(:,3);
AB = eez*L_AB;
BC = eex*L_BC;
CD = eex*70 + eez*40;
OD = OA + AB + BC + CD;
OB = OA+AB;
OC = OB+BC;
AD = OD - OA;
DE = OE - OD;
AG = 34*eex + 51*eez;
OG = OA + AG;
L = norm(DE);
eDE = DE/L;
L0 = 120;
F = k*(L-L0);
FF = F*eDE;
W = [0; 0; -0.15*9.82];
figure
fplot(L,[-90,90])
xlabel('\theta [deg]')
ylabel('L [mm]')
figure
fplot(F,[-90,90])
xlabel('\theta [deg]')
ylabel('F [N]')
M_A = cross(AD, FF) + cross(AG, W);
eAB = eez;
M_AB = dot(M_A, eAB)/1000;
figure
fplot(M_AB,[-90,90])
xlabel('\theta [deg]')
ylabel('M [Nm]')
Zooming in at the force graph, we learn that the minimum force and length of the spring occurs at .
The maximum moment occurs at around . The moment is zero around .
Another approach to rotating the coordinate system is to rotate around a local coordinate system. This makes the modeling and thinking easier. One does not need to be confined to thinking about rotations around global coordinates.
This can be done by rotating the -rotation matrix, around the -axis by:
This rotation matrix rotates vectors around the axis. This approach still relies on defining the rotation matrix by rotating it around global axis. The order of rotations is important, thus chaining rotations can become tedious.
It would be nicer to have a function that lets us rotate around a arbitrary vector . To achieve this we visit our favorite source of goodyness, Wikipedia, and find that the very elegant way of rotating a vector around an axis by an angle according to the right-hand rule is stated as
which we can write in matlab as
Ruv = @(a,u,v) u*dot(u,v) + cross(cosd(a)*cross(u,v), u) + sind(a)*cross(u,v);
We can test this by rotating the -axis 90 degrees around and -axis, we expect the resulting vector to be
Ruv(90,[0;0;1],[1;0;0])
ans = 3x1
0
1
0
Now we can repeat the definitions of the points from the example above using the new rotation tool.
OA = [30, 60, 75]'; % mm
OE = [175, 105, 15]'; % mm
L_AB = 65; % mm
L_BC = 50; % mm
k = 0.2; % N/mm
L0 = 120; % mm
theta1 = 35; % deg
theta2 = 26; % deg
We formulate the direction by rotating the -axis around the -axis.
eAB = Ruv(-theta1, [1,0,0]', [0,0,1]')
eez = eAB;
eAB = 3x1
0
0.5736
0.8192
Ok, nothing new, hardly easier than using standard rotation matrices. But now we can rotate around
eex = Ruv(theta2, eAB, [1,0,0]')
eex = 3x1
0.8988
0.3591
-0.2514
AB = eez*L_AB;
BC = eex*L_BC;
CD = eex*70 + eez*40;
OD = OA + AB + BC + CD;
OB = OA+AB;
OC = OB+BC;
AD = OD - OA;
DE = OE - OD;
AG = 34*eex + 51*eez;
OG = OA + AG;
% Visualization
close all
figure
axis equal; hold on;
xlabel('x'); ylabel('y'); zlabel('z');
set(gcf,'Visible','on')
hp1 = plot3([OA(1), OB(1)], ...
[OA(2), OB(2)], ...
[OA(3), OB(3)], '-k', 'LineWidth',2);
htA = text(OA(1), OA(2), OA(3), 'A');
htB = text(OB(1), OB(2), OB(3), 'B');
hp2 = plot3([OB(1), OC(1)], ...
[OB(2), OC(2)], ...
[OB(3), OC(3)], '-k', 'LineWidth',2);
htC = text(OC(1), OC(2), OC(3), 'C');
hp3 = plot3([OC(1), OD(1)], ...
[OC(2), OD(2)], ...
[OC(3), OD(3)], '-k', 'LineWidth',2);
htD = text(OD(1), OD(2), OD(3), 'D');
hp4 = plot3([OD(1), OE(1)], ...
[OD(2), OE(2)], ...
[OD(3), OE(3)], '-m', 'LineWidth',2);
htE = text(OE(1), OE(2), OE(3), 'E');
hp5 = plot3(OG(1), OG(2), OG(3), 'ok', 'MarkerFaceColor','k');
view(3)
grid on
axis([0,200, -100, 250, 0, 250])
view(-69, 35)
view(2)
view(40, 32)
htitel = title(sprintf('$\\theta=%d^\\circ$',theta2),'interpreter','latex');