diff --git a/Models/Bouncing_Ball/Overview/html/sm_contact_ball.html b/Models/Bouncing_Ball/Overview/html/sm_contact_ball.html index 8b13e17..803afc1 100644 --- a/Models/Bouncing_Ball/Overview/html/sm_contact_ball.html +++ b/Models/Bouncing_Ball/Overview/html/sm_contact_ball.html @@ -6,7 +6,7 @@ Bouncing Ball With Zero Crossings

Multibody Rolling Disk, Custom Force Law

This example shows how to model a custom force law that integrated with the Spatial Contact Force block. The custom force law modifies the coefficients of friction based on the disk's position.

Two spinning disks are released above a floor with an initial translational speed. The friction between the disks and the floor slows the rate at which they spin and slide. When the disk with the custom force law reaches a patch of ice (shown visually in the animation), the coefficients of friction are reduced. The rotational speeds of the disks and trajectories of the disks differ, showing the effect of the custom force law.

Contents

Model

Simulation Results from Simscape Logging

The plot below compares the rotational speed of the disks and their position along the global x-axis. When the disks hit the patch of ice, only the disk with the custom force law has its friction force affected.

This example shows how to model a custom force law that integrated with the Spatial Contact Force block. The custom force law modifies the coefficients of friction based on the disk's position.

Two spinning disks are released above a floor with an initial translational speed. The friction between the disks and the floor slows the rate at which they spin and slide. When the disk with the custom force law reaches a patch of ice (shown visually in the animation), the coefficients of friction are reduced. The rotational speeds of the disks and trajectories of the disks differ, showing the effect of the custom force law.

Contents

Model

Custom Force

This shows the basic calculations required for developing a custom force law.

  1. Calculate quantities upon which normal/friction will depend
  2. Obtain relevant tangential veloctiy.
  3. Calculate normal force
  4. Calculate friction force
  5. Decompose friction force along relevant axes (tangential plane)

Simulation Results from Simscape Logging

The plot below compares the rotational speed of the disks and their position along the global x-axis. When the disks hit the patch of ice, only the disk with the custom force law has its friction force affected.

Multibody Disk Contact, Cylinder on Floor

Multibody Point Cloud Contact Steering Wheel

This example models collisions between parameterized solids, solids represented by CAD geometry, and point clouds which act as an approximation of the geometry for the purpose of contact.

Two spheres follow different trajectories as they collide with the steering wheel. The sphere whose contact is directly with the CAD geometry follows a path around the convex hull that encloses the CAD geometry. The sphere colliding with the point cloud passes through the hole in the steering wheel.

Contents

Model

Simulation Results from Simscape Logging

This script plots the paths of the balls and the final position of the steering wheel. The ball that models contact with the STL file directly encounters the convex hull and does not pass through the hole. The ball that models contact with the point cloud passes through the hole in the steering wheel.

This example models collisions between parameterized solids, solids represented by CAD geometry, and point clouds which act as an approximation of the geometry for the purpose of contact.

Two spheres follow different trajectories as they collide with the steering wheel. The sphere whose contact is directly with the CAD geometry follows a path around the convex hull that encloses the CAD geometry. The sphere colliding with the point cloud passes through the hole in the steering wheel.

Contents

Model

Convex Hull

The Spatial Contact Force block uses a convex hull to detect contact between the steering wheel geometry and other objects (ball, floor). This plot shows what that convex hull would look like.

Simulation Results from Simscape Logging

This script plots the paths of the balls and the final position of the steering wheel. The ball that models contact with the STL file directly encounters the convex hull and does not pass through the hole. The ball that models contact with the point cloud passes through the hole in the steering wheel.

Spinning Top, Contact Methods (Tippe Shape)

Spinning Top, Contact Methods (Tippe Shape)

This example models a top spinning on a flat surface. The top consists of a narrow shaft and a truncated sphere. When spun at high speeds, the stem will tilt downwards until it lifts the body of the top off of the ground. Mask parameters select whether contact with the floor is modeled using a sphere or a point cloud. A point cloud will result in higher amounts of friction forces with the floor for the same friction coefficients.

Contents

Model

Body of Top and Contact Proxies

Two types of geometry can used to model contact the floor. For both the truncated sphere and the stem, either a single sphere (single point of contact) or a point cloud can be used. The biggest difference in behavior is that for objects spinning about an axis that goes through the point of contact, no friction is generated. As a result, the point cloud will have higher levels of friction for the spinning top for the same friction coefficients.

Points For Truncated Sphere

A set of points is used to define the profile of the truncated sphere. The internal profile of the sphere adjusts the location of the center of mass which influences how quickly the top will flip over.

Convex Hull

If the top were defined as a single solid, the Spatial Contact Force block would use its convex hull to detect contact with the floor. This plot shows what that convex hull would look like.

Simulation Results from Simscape Logging

This is a plot of the rotational speed of the top. The rotational speed of the top about its axis switches direction as the top flips over and stands on its stem. Eventually the top slows down enough that both the stem and the body are touching the ground, and the top is rolling in a circle.

Simulation Results from Simscape Logging: Comparing Contact Proxies

This plot compares the effect of selected contact proxies at the head and base of the top. The Point Cloud will result in higher levels of friction than the sphere for the same friction coefficients. This is because multi-point contact will have a higher relative velocity, especially for objects that spin about an axis that passes through the contact point.

\ No newline at end of file diff --git a/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top.png b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top.png new file mode 100644 index 0000000..d121510 Binary files /dev/null and b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top.png differ diff --git a/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_01.png b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_01.png new file mode 100644 index 0000000..bb4f143 Binary files /dev/null and b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_01.png differ diff --git a/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_02.png b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_02.png new file mode 100644 index 0000000..ad38798 Binary files /dev/null and b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_02.png differ diff --git a/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_03.png b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_03.png new file mode 100644 index 0000000..9fd97bd Binary files /dev/null and b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_03.png differ diff --git a/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_04.png b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_04.png new file mode 100644 index 0000000..2643082 Binary files /dev/null and b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_04.png differ diff --git a/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_05.png b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_05.png new file mode 100644 index 0000000..40b0436 Binary files /dev/null and b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_05.png differ diff --git a/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_06.png b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_06.png new file mode 100644 index 0000000..4e95ebc Binary files /dev/null and b/Models/Spinning_Top/Tippe/Overview/html/sm_tippe_top_06.png differ diff --git a/Models/Spinning_Top/Tippe/Overview/sm_tippe_top.m b/Models/Spinning_Top/Tippe/Overview/sm_tippe_top.m new file mode 100644 index 0000000..19e6d30 --- /dev/null +++ b/Models/Spinning_Top/Tippe/Overview/sm_tippe_top.m @@ -0,0 +1,76 @@ +%% Spinning Top, Contact Methods (Tippe Shape) +% +% This example models a top spinning on a flat surface. The top consists of +% a narrow shaft and a truncated sphere. When spun at high speeds, the stem +% will tilt downwards until it lifts the body of the top off of the ground. +% Mask parameters select whether contact with the floor is modeled using a +% sphere or a point cloud. A point cloud will result in higher amounts of +% friction forces with the floor for the same friction coefficients. +% +% Copyright 2022 The MathWorks, Inc. + +%% Model + +open_system('sm_tippe_top') + +set_param(find_system('sm_tippe_top','FindAll', 'on','type','annotation','Tag','ModelFeatures'),'Interpreter','off') + +%% Body of Top and Contact Proxies +% +% Two types of geometry can used to model contact the floor. For both the +% truncated sphere and the stem, either a single sphere (single point of +% contact) or a point cloud can be used. The biggest difference in +% behavior is that for objects spinning about an axis that goes through the +% point of contact, no friction is generated. As a result, the point cloud +% will have higher levels of friction for the spinning top for the same +% friction coefficients. + +open_system('sm_tippe_top/Top','force') + + +%% Points For Truncated Sphere +% +% A set of points is used to define the profile of the truncated sphere. +% The internal profile of the sphere adjusts the location of the center of +% mass which influences how quickly the top will flip over. +% +sm_tippe_top_plot3headrevolution; + +%% Convex Hull +% +% If the top were defined as a single solid, the Spatial Contact Force +% block would use its convex hull to detect contact with the floor. This +% plot shows what that convex hull would look like. +% +sm_convex_hull_pointcloud(ptcld_cvh,'none','plot'); + +%% Simulation Results from Simscape Logging +%% +% +% This is a plot of the rotational speed of the top. The rotational speed +% of the top about its axis switches direction as the top flips over and +% stands on its stem. Eventually the top slows down enough that both the +% stem and the body are touching the ground, and the top is rolling in a +% circle. +% + +sm_tippe_top_plot1speed; + +%% Simulation Results from Simscape Logging: Comparing Contact Proxies +%% +% +% This plot compares the effect of selected contact proxies at the head and +% base of the top. The Point Cloud will result in higher levels of +% friction than the sphere for the same friction coefficients. This is +% because multi-point contact will have a higher relative velocity, +% especially for objects that spin about an axis that passes through the +% contact point. +% + +sm_tippe_top_plot2compareproxies; + +%% + +%clear all +close all +bdclose all diff --git a/Models/Spinning_Top/Tippe/ptcld_spheres.mat b/Models/Spinning_Top/Tippe/ptcld_spheres.mat new file mode 100644 index 0000000..5a3d6e7 Binary files /dev/null and b/Models/Spinning_Top/Tippe/ptcld_spheres.mat differ diff --git a/Models/Spinning_Top/Tippe/sm_tippe_top.slx b/Models/Spinning_Top/Tippe/sm_tippe_top.slx new file mode 100644 index 0000000..eff13ed Binary files /dev/null and b/Models/Spinning_Top/Tippe/sm_tippe_top.slx differ diff --git a/Models/Spinning_Top/Tippe/sm_tippe_top_image.png b/Models/Spinning_Top/Tippe/sm_tippe_top_image.png new file mode 100644 index 0000000..6e87789 Binary files /dev/null and b/Models/Spinning_Top/Tippe/sm_tippe_top_image.png differ diff --git a/Models/Spinning_Top/Tippe/sm_tippe_top_param.m b/Models/Spinning_Top/Tippe/sm_tippe_top_param.m new file mode 100644 index 0000000..f5d0ff8 --- /dev/null +++ b/Models/Spinning_Top/Tippe/sm_tippe_top_param.m @@ -0,0 +1,56 @@ +% Parameters for sm_tippe_top.slx +% Copyright 2022 The MathWorks, Inc. + +scale_factor = 0.02; % Scales radii, stem length + +% Size of top body +min_angle = -45; % Angle where sphere is truncated (deg) +head_angular_sweep = min_angle:1:90; + +% Size of hollow inside sphere +head_hollow_rad = 0.8; % m +head_hollow_depth = 0.35; % Depth from sphere center towards top + +% Derive profile for truncated sphere +head_hollow_x = min(head_hollow_rad,cosd(head_angular_sweep(1)+eps)); +rev_profile_head = [... + cosd(head_angular_sweep) 0 head_hollow_x ; + sind(head_angular_sweep) head_hollow_depth head_hollow_depth ]'*scale_factor; + +% Shaft parameters +shaft_radius = 0.2*scale_factor; +shaft_length = 1.5*scale_factor; + +top_density = 7000; % kg/m^3 + +% Height of top, used to define camera and initial height +top_height = shaft_radius+shaft_length+max(max(rev_profile_head)); + +% Contact parameters +top_contact_k = 1e6*scale_factor; % N/m +top_contact_d = 1e4*scale_factor; % N/(m/s) +top_contact_w = 1e-4; % m + +top_friction_s = 0.5; % (0-1) +top_friction_d = 0.3; % (0-1) +top_friction_v = 1e-3; % m/s + +% Small amount of viscous damping (wind resistance) +% Applied at spherical joint +top_viscous_damping = 1e-8; % N*m/(deg/s) + +% Initial conditions +init_angle_x = 150; % deg +init_speed = [0 0 50]; % rev/sec + + +% To regenerate point cloud, use this command - takes a few minutes +%ptcld_sphere_rad1_pts1000 = Point_Cloud_Data_Sphere(1,1000,'none'); +%ptcld_sphere_rad1_pts200 = Point_Cloud_Data_Sphere(1,200,'none'); +%save ptcld_spheres ptcld_sphere_rad1_pts200 ptcld_sphere_rad1_pts1000 + +% Complete point cloud for convex hull +ptcld_head = ptcld_sphere_rad1_pts1000*max(max(rev_profile_head)); +ptcld_base = ptcld_sphere_rad1_pts200*shaft_radius-[0 0 shaft_length]; +ptcld_cvh = [ptcld_base;ptcld_head]; + diff --git a/Models/Spinning_Top/Tippe/sm_tippe_top_plot1speed.m b/Models/Spinning_Top/Tippe/sm_tippe_top_plot1speed.m new file mode 100644 index 0000000..110ec10 --- /dev/null +++ b/Models/Spinning_Top/Tippe/sm_tippe_top_plot1speed.m @@ -0,0 +1,39 @@ +% Code to plot simulation results from sm_tippe_top +%% Plot Description: +% +% This is a plot of the rotational speed of the top. The rotational speed +% of the top about its axis switches direction as the top flips over and +% stands on its stem. Eventually the top slows down enough that both the +% stem and the body are touching the ground, and the top is rolling in a +% circle. +% +% Copyright 2022 The MathWorks, Inc. + +% Generate simulation results if they don't exist +if ~exist('simlog_sm_tippe_top', 'var') + sim('sm_tippe_top') +end + +% Reuse figure if it exists, else create new figure +if ~exist('h1_sm_tippe_top', 'var') || ... + ~isgraphics(h1_sm_tippe_top, 'figure') + h1_sm_tippe_top = figure('Name', 'sm_tippe_top'); +end +figure(h1_sm_tippe_top) +clf(h1_sm_tippe_top) + +temp_colororder = get(gca,'defaultAxesColorOrder'); + +% Get simulation results +simlog_wTop = logsout_sm_tippe_top.get('wTop'); + +% Plot results +plot(simlog_wTop.Values.Time, simlog_wTop.Values.Data, 'LineWidth', 2) +grid on +title('Rotational Speed of Top') +ylabel('Speed (rev/s)') +xlabel('Time (s)') + +% Remove temporary variables +clear simlog_handles +clear temp_colororder diff --git a/Models/Spinning_Top/Tippe/sm_tippe_top_plot2compareproxies.m b/Models/Spinning_Top/Tippe/sm_tippe_top_plot2compareproxies.m new file mode 100644 index 0000000..9a16de9 --- /dev/null +++ b/Models/Spinning_Top/Tippe/sm_tippe_top_plot2compareproxies.m @@ -0,0 +1,70 @@ +% Code to plot simulation results from sm_tippe_top +%% Plot Description: +% +% This plot compares the effect of selected contact proxies at the head and +% base of the top. The Point Cloud will result in higher levels of +% friction than the sphere for the same friction coefficients. This is +% because multi-point contact will have a higher relative velocity, +% especially for objects that spin about an axis that passes through the +% contact point. +% +% Copyright 2022 The MathWorks, Inc. + +% Reuse figure if it exists, else create new figure +if ~exist('h1_sm_tippe_top', 'var') || ... + ~isgraphics(h1_sm_tippe_top, 'figure') + h1_sm_tippe_top = figure('Name', 'sm_tippe_top'); +end +figure(h1_sm_tippe_top) +clf(h1_sm_tippe_top) + +temp_colororder = get(gca,'defaultAxesColorOrder'); + +% Set proxies to sphere +mdl = 'sm_tippe_top'; +set_param([mdl '/Top'],'popup_contact_head','Sphere'); +set_param([mdl '/Top'],'popup_contact_base','Sphere'); +sim(mdl) +simlog_wTop_SphSph = logsout_sm_tippe_top.get('wTop'); + +% Set head proxy to point cloud +mdl = 'sm_tippe_top'; +set_param([mdl '/Top'],'popup_contact_head','Point Cloud'); +set_param([mdl '/Top'],'popup_contact_base','Sphere'); +sim(mdl) +simlog_wTop_PCSph = logsout_sm_tippe_top.get('wTop'); + +% Set base proxy to point cloud +mdl = 'sm_tippe_top'; +set_param([mdl '/Top'],'popup_contact_head','Sphere'); +set_param([mdl '/Top'],'popup_contact_base','Point Cloud'); +sim(mdl) +simlog_wTop_SphPC = logsout_sm_tippe_top.get('wTop'); + +% Set proxies to point cloud +mdl = 'sm_tippe_top'; +set_param([mdl '/Top'],'popup_contact_head','Point Cloud'); +set_param([mdl '/Top'],'popup_contact_base','Point Cloud'); +sim(mdl) +simlog_wTop_PCPC = logsout_sm_tippe_top.get('wTop'); + + +% Plot results +plot(simlog_wTop_SphSph.Values.Time, simlog_wTop_SphSph.Values.Data,... + 'LineWidth', 2,'DisplayName','Head: Sphere, Base: Sphere') +hold on +plot(simlog_wTop_PCSph.Values.Time, simlog_wTop_PCSph.Values.Data,... + 'LineWidth', 2,'DisplayName','Head: Points, Base: Sphere') +plot(simlog_wTop_SphPC.Values.Time, simlog_wTop_SphPC.Values.Data,... + 'LineWidth', 2,'DisplayName','Head: Sphere, Base: Points') +plot(simlog_wTop_PCPC.Values.Time, simlog_wTop_PCPC.Values.Data,... + 'LineWidth', 2,'DisplayName','Head: Points, Base: Points') +hold off +grid on +title('Rotational Speed of Top') +ylabel('Speed (rev/s)') +xlabel('Time (s)') +legend('Location','Best') +% Remove temporary variables +clear simlog_handles +clear temp_colororder diff --git a/Models/Spinning_Top/Tippe/sm_tippe_top_plot3headrevolution.m b/Models/Spinning_Top/Tippe/sm_tippe_top_plot3headrevolution.m new file mode 100644 index 0000000..8fd066d --- /dev/null +++ b/Models/Spinning_Top/Tippe/sm_tippe_top_plot3headrevolution.m @@ -0,0 +1,9 @@ +% Code to plot convex hull of tippe top geometry +% +% If the top were defined as a single solid, the Spatial Contact Force +% block would use its convex hull to detect contact with the floor. This +% plot shows what that convex hull would look like. +% +% Copyright 2022 The MathWorks, Inc. + +sm_convex_hull_revolution(rev_profile_head,'none','plot') diff --git a/Models/Spinning_Top/Tippe/tippe_top_cvh.stl b/Models/Spinning_Top/Tippe/tippe_top_cvh.stl new file mode 100644 index 0000000..b9153b7 Binary files /dev/null and b/Models/Spinning_Top/Tippe/tippe_top_cvh.stl differ diff --git a/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem.html b/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem.html new file mode 100644 index 0000000..4ae009d --- /dev/null +++ b/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem.html @@ -0,0 +1,114 @@ + + + + + Spinning Top, Contact Methods (Totem Shape)

Spinning Top, Contact Methods (Totem Shape)

This example models a top spinning on a flat surface. A mask parameter selects whether the top is modeled with one contact point on the floor or two contact points on the floor.

Contents

Model

Body of Top and Contact Proxies

Simulation Results from Simscape Logging

The plot below shows the speed of the top as it spins. Due to damping and an initial angle of the top, eventually the top tips over and the wider radius strikes the floor. The rotational speed of the top slows down rapidly until it rolls around, touching the floor in two spots - the point at the bottom of the top and the wider radius.

\ No newline at end of file diff --git a/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem.png b/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem.png new file mode 100644 index 0000000..3e86115 Binary files /dev/null and b/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem.png differ diff --git a/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem_01.png b/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem_01.png new file mode 100644 index 0000000..d8928a1 Binary files /dev/null and b/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem_01.png differ diff --git a/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem_02.png b/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem_02.png new file mode 100644 index 0000000..4cfb910 Binary files /dev/null and b/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem_02.png differ diff --git a/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem_03.png b/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem_03.png new file mode 100644 index 0000000..fb64111 Binary files /dev/null and b/Models/Spinning_Top/Totem/Overview/html/sm_spinning_top_totem_03.png differ diff --git a/Models/Spinning_Top/Totem/Overview/sm_spinning_top_totem.m b/Models/Spinning_Top/Totem/Overview/sm_spinning_top_totem.m new file mode 100644 index 0000000..5dd35cd --- /dev/null +++ b/Models/Spinning_Top/Totem/Overview/sm_spinning_top_totem.m @@ -0,0 +1,40 @@ +%% Spinning Top, Contact Methods (Totem Shape) +% +% This example models a top spinning on a flat surface. A mask parameter +% selects whether the top is modeled with one contact point on the floor or +% two contact points on the floor. +% +% Copyright 2022 The MathWorks, Inc. + + + +%% Model + +open_system('sm_spinning_top_totem') + +set_param(find_system('sm_spinning_top_totem','FindAll', 'on','type','annotation','Tag','ModelFeatures'),'Interpreter','off') + +%% Body of Top and Contact Proxies +% + +open_system('sm_spinning_top_totem/Top','force') + +%% Simulation Results from Simscape Logging +%% +% +% The plot below shows the speed of the top as it spins. Due to damping +% and an initial angle of the top, eventually the top tips over and the +% wider radius strikes the floor. The rotational speed of the top slows +% down rapidly until it rolls around, touching the floor in two spots - the +% point at the bottom of the top and the wider radius. +% + +set_param([bdroot '/Top'],'popup_contact','Two Points') +sim(bdroot) +sm_spinning_top_totem_plot1speed; + +%% + +%clear all +close all +bdclose all diff --git a/Models/Spinning_Top/Totem/sm_spinning_top_totem.slx b/Models/Spinning_Top/Totem/sm_spinning_top_totem.slx new file mode 100644 index 0000000..be73eaf Binary files /dev/null and b/Models/Spinning_Top/Totem/sm_spinning_top_totem.slx differ diff --git a/Models/Spinning_Top/Totem/sm_spinning_top_totem_extr_data.mat b/Models/Spinning_Top/Totem/sm_spinning_top_totem_extr_data.mat new file mode 100644 index 0000000..1cd5195 Binary files /dev/null and b/Models/Spinning_Top/Totem/sm_spinning_top_totem_extr_data.mat differ diff --git a/Models/Spinning_Top/Totem/sm_spinning_top_totem_param.m b/Models/Spinning_Top/Totem/sm_spinning_top_totem_param.m new file mode 100644 index 0000000..e5059b3 --- /dev/null +++ b/Models/Spinning_Top/Totem/sm_spinning_top_totem_param.m @@ -0,0 +1,113 @@ +function [extr_data_top, extr_data_top_upper, extr_data_top_lower] = sm_spinning_top_totem_param(varargin) + +%% Assign default values +if (nargin==0) + showplot = 'plot'; +else + showplot = varargin(end); +end + +% Global size parameters +L = 29; W = L; H = 36; +R = 2; % radius +th = R; % thickness +topHeight = 2/3*H - th/2; +bottomHeight = 1/3*H - th/2; + +%% Half Top Circle +theta = linspace(0, pi/2, 30)'; +x1 = R*cos(theta); +y1 = R*sin(theta) + H - R; + +%% Decay +xI = [R;1.3*R; L/2]; +yI = [H-R;1.85*(bottomHeight+th);bottomHeight+th]; + +ft = fittype( 'a./log(b*x)+c', 'independent', 'x', 'dependent', 'y' ); + +opts = fitoptions( 'Method', 'NonlinearLeastSquares' ); +opts.Display = 'Off'; +opts.Lower = [0 0 0]; +opts.StartPoint = [0.678735154857773 0.757740130578333 0.743132468124916]; + +fitresult = fit( xI, yI, ft, opts ); + +x2 = flip(linspace(R, L/2, 50)'); +y2 = feval(fitresult, x2); + + +%% Line +x3 = [L/2 L/2]'; +y3 = [bottomHeight bottomHeight+th]'; + +%% Gaussian +xG = [-L/2; -L/16; 0; L/16; L/2]; +yG = [0; bottomHeight-L/16; bottomHeight; bottomHeight-L/16; 0]; + +ft = fittype( 'gauss1' ); + +opts2 = fitoptions( 'Method', 'NonlinearLeastSquares' ); +opts2.Lower = [-Inf -Inf 0]; +opts2.StartPoint = [11 0 1]; + +fitresult = fit( xG, yG, ft, opts2 ); + +x4 = linspace(0, L/2, 60)'; +y4 = -feval(fitresult, x4) + bottomHeight; + + +%% Generate Matrix +x = [x4; x3; x2(2:end-1); x1]; +y = [y4; y3; y2(2:end-1); y1]; +extr_data_top = [x y]/6; + +%% Separate lowest part into separate extrusion +top_lower_ind = find(y<5,1,'last'); +extr_data_top_lower = [extr_data_top(1:top_lower_ind,:); 0 extr_data_top(top_lower_ind,2)]; +extr_data_top_upper = [0 extr_data_top(top_lower_ind,2); extr_data_top(top_lower_ind:end,:); 0 extr_data_top(end,end)]; + +%% +if (nargin == 0 || strcmpi(showplot,'plot')) + + % Figure name + figString = ['h1_' mfilename]; + % Only create a figure if no figure exists + figExist = 0; + fig_hExist = evalin('base',['exist(''' figString ''')']); + if (fig_hExist) + figExist = evalin('base',['ishandle(' figString ') && strcmp(get(' figString ', ''type''), ''figure'')']); + end + if ~figExist + fig_h = figure('Name',figString); + assignin('base',figString,fig_h); + else + fig_h = evalin('base',figString); + end + figure(fig_h) + clf(fig_h) + subplot(1,2,1) + plot(x1, y1, "*-"); + axis equal; + %axis([0 L/2 -5 H]); + hold on + plot(x2, y2, "*-") + plot(x4, y4, "*-") + plot(x3, y3, "*-") + hold off + + subplot(1,2,2) + plot(extr_data_top_lower(:,1)*6,extr_data_top_lower(:,2)*6,'-x') + axis equal + %axis([0 L/2 -5 H]); + hold on + plot(extr_data_top_upper(:,1)*6,extr_data_top_upper(:,2)*6,'-o') + hold off +end + +%% Additional commands - used to set up example + +%% Save results +%save sm_spinning_top_totem_extr_data.mat extr_data_top extr_data_top_lower extr_data_top_upper; + +%% Create convex hull stl +% sm_revolution_to_stl(extr_data_top,'top_totem_complete_convex_hull.stl') \ No newline at end of file diff --git a/Models/Spinning_Top/Totem/sm_spinning_top_totem_plot1speed.m b/Models/Spinning_Top/Totem/sm_spinning_top_totem_plot1speed.m new file mode 100644 index 0000000..c3518d7 --- /dev/null +++ b/Models/Spinning_Top/Totem/sm_spinning_top_totem_plot1speed.m @@ -0,0 +1,36 @@ +% Code to plot simulation results from sm_spinning_top_totem +%% Plot Description: +% +% This is a plot of the rotational speed of the top. +% +% Copyright 2022 The MathWorks, Inc. + +% Generate simulation results if they don't exist +if ~exist('simlog_sm_spinning_top_totem', 'var') + sim('sm_spinning_top_totem') +end + +% Reuse figure if it exists, else create new figure +if ~exist('h1_sm_spinning_top_totem', 'var') || ... + ~isgraphics(h1_sm_spinning_top_totem, 'figure') + h1_sm_spinning_top_totem = figure('Name', 'sm_spinning_top_totem'); +end +figure(h1_sm_spinning_top_totem) +clf(h1_sm_spinning_top_totem) + +temp_colororder = get(gca,'defaultAxesColorOrder'); + +% Get simulation results +simlog_wTop = logsout_sm_spinning_top_totem.get('wTop'); + +% Plot results +plot(simlog_wTop.Values.Time, simlog_wTop.Values.Data, 'LineWidth', 1) +grid on +title('Rotational Speed of Top') +ylabel('Speed (rev/s)') +xlabel('Time (s)') + +% Remove temporary variables +clear simlog_handles +clear temp_colororder + diff --git a/Models/Spinning_Top/Totem/top_totem_complete.png b/Models/Spinning_Top/Totem/top_totem_complete.png new file mode 100644 index 0000000..6069e6c Binary files /dev/null and b/Models/Spinning_Top/Totem/top_totem_complete.png differ diff --git a/Models/Spinning_Top/Totem/top_totem_complete_convex_hull.stl b/Models/Spinning_Top/Totem/top_totem_complete_convex_hull.stl new file mode 100644 index 0000000..413562a Binary files /dev/null and b/Models/Spinning_Top/Totem/top_totem_complete_convex_hull.stl differ diff --git a/README.md b/README.md index fc93070..e2b55f9 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ The examples cover: * **[Point Cloud](https://www.mathworks.com/help/physmod/sm/ref/pointcloud.html) definition** for efficient contact modeling of complex shapes. * **[Grid Surface](https://www.mathworks.com/help/physmod/sm/ref/gridsurface.html) modeling** for efficient contact modeling with terrain. * **Custom force law definition** including collision and friction forces. +* **Point cloud definition** to evenly distribute points over areas and volume surfaces. +* **Convex hull visualization** by generating an STL of the hull for points and STL geometry. Open the project file Spatial_Contact_Force_Examples.prj to get started. @@ -28,4 +30,4 @@ To learn more about contact modeling with Simscape Multibody, please visit: * [Simscape Multibody™](https://www.mathworks.com/products/simscape-multibody.html) This submission uses the [S^2 Sampling Toolbox](https://www.mathworks.com/matlabcentral/fileexchange/37004-suite-of-functions-to-perform-uniform-sampling-of-a-sphere) -Anton Semechko (2022). Suite of functions to perform uniform sampling of a sphere (https://github.com/AntonSemechko/S2-Sampling-Toolbox), GitHub. Retrieved March 24, 2022. +Anton Semechko (2022). Suite of functions to perform uniform sampling of a sphere (https://github.com/AntonSemechko/S2-Sampling-Toolbox), GitHub. Retrieved March 24, 2022. \ No newline at end of file diff --git a/Scripts_Data/Convex_Hull/sm_convex_hull_pointcloud.m b/Scripts_Data/Convex_Hull/sm_convex_hull_pointcloud.m new file mode 100644 index 0000000..1a1891d --- /dev/null +++ b/Scripts_Data/Convex_Hull/sm_convex_hull_pointcloud.m @@ -0,0 +1,86 @@ +function sm_convex_hull_pointcloud(pointcloud,varargin) +%sm_convex_hull_pointcloud Plot and produce STL to visualize convex hull of a point cloud +% sm_convex_hull_pointcloud(pointcloud,,) +% +% You can specify: +% pointcloud Matrix of x, y, z data for points [n x 3] +% cvhfilename Filename for generated STL file to visualize convex hull +% Specify 'none' to generate no file +% showplot Specify 'plot' to plot the point cloud and convex hull +% +% Examples: +% >> sm_convex_hull_pointcloud +% With no arguments, it will plot an example +% +% >> sm_convex_hull_pointcloud(rand(25,3),'none','plot') +% This will plot 25 randomly distributed points enclosed in a convex hull +% +% >> sm_convex_hull_pointcloud(rand(25,3),'myPointcloudSTL.stl','plot') +% This will plot 25 randomly distributed points enclosed in a convex hull +% and produce an STL file of the convex hull. +% +% Copyright 2021-2022 The MathWorks, Inc. + +%% Assign default values +showplot = 'plot'; +cvhfilename = 'none'; +if (nargin==0) + stlfile = 'test_stl_steering_wheel.stl'; + stl_tri = stlread(stlfile); + pointcloud = stl_tri.Points; +end +if (nargin>=2) + cvhfilename = varargin{1}; +end +if (nargin==3) + showplot = varargin{2}; +end + +% Generate Delaunay triangulation +pointcloud_dt = delaunayTriangulation(pointcloud); + +% Obtain indexes for convex hull +cvh_inds = convexHull(pointcloud_dt); + +% Generate triangulation using indices of convex hull +warning('off','MATLAB:triangulation:PtsNotInTriWarnId') +pointcloud_dt_cvh = triangulation(cvh_inds,pointcloud_dt.Points); +warning('on','MATLAB:triangulation:PtsNotInTriWarnId') + +% Plot point cloud and convex hull if requested +if (nargin == 0 || strcmpi(showplot,'plot')) + + % Figure name + figString = ['h1_' mfilename]; + % Only create a figure if no figure exists + figExist = 0; + fig_hExist = evalin('base',['exist(''' figString ''')']); + if (fig_hExist) + figExist = evalin('base',['ishandle(' figString ') && strcmp(get(' figString ', ''type''), ''figure'')']); + end + if ~figExist + fig_h = figure('Name',figString); + assignin('base',figString,fig_h); + else + fig_h = evalin('base',figString); + end + figure(fig_h) + clf(fig_h) + + temp_colororder = get(gca,'defaultAxesColorOrder'); + plot3(pointcloud(:,1),pointcloud(:,2),pointcloud(:,3),'o','MarkerSize',2,'MarkerFaceColor',temp_colororder(2,:),'DisplayName','Point Cloud') + hold on + trisurf(pointcloud_dt_cvh,'FaceColor',[0.9 0.4 0.4],'EdgeColor',[0.9 0.4 0.4],'FaceAlpha',0.3,'DisplayName','Convex Hull'); + hold off + axis equal + box on + title('Point Cloud and Convex Hull') + legend('Location','Best') +end + +% Generate STL file for convex hull if requested +if(~strcmp(cvhfilename,'none')) + stlwrite(pointcloud_dt_cvh,cvhfilename); +end + + diff --git a/Scripts_Data/Convex_Hull/sm_convex_hull_revolution.m b/Scripts_Data/Convex_Hull/sm_convex_hull_revolution.m new file mode 100644 index 0000000..cd473be --- /dev/null +++ b/Scripts_Data/Convex_Hull/sm_convex_hull_revolution.m @@ -0,0 +1,102 @@ +function sm_convex_hull_revolution(extr_data,varargin) +%sm_convex_hull_revolution Plot and produce STL to visualize convex hull of a point cloud +% sm_convex_hull_pointcloud(pointcloud,,) +% +% You can specify: +% extr_data Matrix of x, y data for profile to be revolved [n x 2] +% cvhfilename Filename for generated STL file to visualize convex hull +% Specify 'none' to generate no file +% showplot Specify 'plot' to plot the point cloud and convex hull +% +% Examples: +% >> sm_convex_hull_revolution +% With no arguments, it will plot an example +% +% >> sm_convex_hull_revolution(sortrows(rand(25,2).*[0.3 1],2),'none','plot') +% This will plot a revolution of 25 points enclosed in a convex hull +% +% >> sm_convex_hull_revolution(sortrows(rand(25,2).*[0.3 1],2),'myRevSTL.stl','plot') +% This will plot a revolution of 25 points enclosed in a convex hull +% and produce an STL file of the convex hull. +% +% Copyright 2021-2022 The MathWorks, Inc. + +%% Assign default values +showplot = 'plot'; +cvhfilename = 'none'; +if (nargin==0) + extr_data = [ + [1 1 2 2 1 1 1 2 2 1 1]*0.4;... + linspace(-2,2,11)]'; +end +if (nargin>=2) + cvhfilename = varargin{1}; +end +if (nargin==3) + showplot = varargin(end); +end + +% Generate vector of angles +angle_vector = linspace(0,2*pi*0.99,50)'; + +% Generate points by revolving profile about z-axis +rev_pts = []; +npts = 0; +for i = 1:(size(extr_data,1)) + for j = 1:length(angle_vector) + npts = npts+1; + rev_pts(npts,:) = [[cos(angle_vector(j)) sin(angle_vector(j))].*extr_data(i,1) extr_data(i,2)]; + end +end + +% Remove any duplicate points +rev_pts = unique(rev_pts,'rows'); + +% Generate Delaunay triangulation +rev_pts_tri = delaunayTriangulation(rev_pts); + +% Obtain indexes for convex hull +cvh_inds = convexHull(rev_pts_tri); + +% Generate triangulation using indices of convex hull +warning('off','MATLAB:triangulation:PtsNotInTriWarnId') +rev_pts_cvh = triangulation(cvh_inds,rev_pts_tri.Points); +warning('on','MATLAB:triangulation:PtsNotInTriWarnId') + +% Plot points from revolved profile and convex hull if requested +if (nargin == 0 || strcmpi(showplot,'plot')) + + % Figure name + figString = ['h1_' mfilename]; + % Only create a figure if no figure exists + figExist = 0; + fig_hExist = evalin('base',['exist(''' figString ''')']); + if (fig_hExist) + figExist = evalin('base',['ishandle(' figString ') && strcmp(get(' figString ', ''type''), ''figure'')']); + end + if ~figExist + fig_h = figure('Name',figString); + assignin('base',figString,fig_h); + else + fig_h = evalin('base',figString); + end + figure(fig_h) + clf(fig_h) + + temp_colororder = get(gca,'defaultAxesColorOrder'); + plot3(extr_data(:,1),extr_data(:,1)*0,extr_data(:,2),'d-','LineWidth',2,'MarkerFaceColor',temp_colororder(2,:),'DisplayName','Revolution Profile') + hold on + plot3(rev_pts(:,1),rev_pts(:,2),rev_pts(:,3),'o','MarkerSize',2,'MarkerFaceColor',temp_colororder(4,:),'DisplayName','Revolution Points') + trisurf(rev_pts_cvh,'FaceColor',[0.6 0.6 0.9],'EdgeColor',[0.6 0.6 0.9],'FaceAlpha',0.3,'DisplayName','Convex Hull'); + hold off + axis equal + box on + title('Convex Hull') + legend('Location','Best') +end + +% Generate STL file for convex hull if requested +if(~strcmp(cvhfilename,'none')) + stlwrite(rev_pts_cvh,cvhfilename); +end + diff --git a/Scripts_Data/Convex_Hull/sm_convex_hull_stlgeometry.m b/Scripts_Data/Convex_Hull/sm_convex_hull_stlgeometry.m new file mode 100644 index 0000000..a62e0f0 --- /dev/null +++ b/Scripts_Data/Convex_Hull/sm_convex_hull_stlgeometry.m @@ -0,0 +1,87 @@ +function sm_convex_hull_stlgeometry(stlfile,varargin) +%sm_convex_hull_stlgeometry Plot and produce STL to visualize convex hull of a point cloud +% sm_convex_hull_stlgeometry(stlfile,,) +% +% You can specify: +% stlfile Matrix of x, y, z data for points [n x 3] +% cvhfilename Filename for generated STL file to visualize convex hull +% Specify 'none' to generate no file +% showplot Specify 'plot' to plot the point cloud and convex hull +% +% Examples: +% >> sm_convex_hull_stlgeometry +% With no arguments, it will plot an example +% +% >> sm_convex_hull_stlgeometry('test_stl_steering_wheel.stl','none','plot') +% This will plot the STL geometry as a surface enclosed in a convex hull +% +% >> sm_convex_hull_stlgeometry('test_stl_steering_wheel.stl','myGeometrySTL.stl','plot') +% This will plot the STL geometry as a surface enclosed in a convex hull +% and produce an STL file of the convex hull. +% +% Copyright 2021-2022 The MathWorks, Inc. + +%% Assign default values +showplot = 'plot'; +cvhfilename = 'none'; +if (nargin==0) + stlfile = 'test_stl_steering_wheel.stl'; +end +if (nargin>=2) + cvhfilename = varargin{1}; +end +if (nargin==3) + showplot = varargin{2}; +end + +% Read in STL file +stl_tri = stlread(stlfile); + +% Generate Delaunay triangulation +stl_dt = delaunayTriangulation(stl_tri.Points); + +% Obtain indexes for convex hull +cvh_inds = convexHull(stl_dt); + +% Generate triangulation using indices of convex hull +warning('off','MATLAB:triangulation:PtsNotInTriWarnId') +stl_cvh = triangulation(cvh_inds,stl_dt.Points); +warning('on','MATLAB:triangulation:PtsNotInTriWarnId') + +% Plot STL as a surface and convex hull if requested +if (nargin == 0 || strcmpi(showplot,'plot')) + + % Figure name + figString = ['h1_' mfilename]; + % Only create a figure if no figure exists + figExist = 0; + fig_hExist = evalin('base',['exist(''' figString ''')']); + if (fig_hExist) + figExist = evalin('base',['ishandle(' figString ') && strcmp(get(' figString ', ''type''), ''figure'')']); + end + if ~figExist + fig_h = figure('Name',figString); + assignin('base',figString,fig_h); + else + fig_h = evalin('base',figString); + end + figure(fig_h) + clf(fig_h) + + temp_colororder = get(gca,'defaultAxesColorOrder'); + trisurf(stl_tri,'EdgeColor','none','FaceAlpha',1,'DisplayName',strrep(stlfile,'_','\_')) + colormap bone + hold on + trisurf(stl_cvh,'FaceColor',[0.9 0.4 0.4],'EdgeColor',[0.9 0.4 0.4],'FaceAlpha',0.3,'DisplayName','Convex Hull'); + hold off + axis equal + box on + title('STL Geometry and Convex Hull') + legend('Location','Best') +end + +% Generate STL file for convex hull if requested +if(~strcmp(cvhfilename,'none')) + stlwrite(stl_cvh,cvhfilename); +end + diff --git a/Scripts_Data/Convex_Hull/test_stl_steering_wheel.stl b/Scripts_Data/Convex_Hull/test_stl_steering_wheel.stl new file mode 100644 index 0000000..c62ea6a Binary files /dev/null and b/Scripts_Data/Convex_Hull/test_stl_steering_wheel.stl differ diff --git a/Scripts_Data/Spatial_Contact_Examples_Demo_Script.html b/Scripts_Data/Spatial_Contact_Examples_Demo_Script.html index e53e1f9..2b91d2b 100644 --- a/Scripts_Data/Spatial_Contact_Examples_Demo_Script.html +++ b/Scripts_Data/Spatial_Contact_Examples_Demo_Script.html @@ -6,7 +6,7 @@ Spatial Contact Forces Examples

Spatial Contact Forces Examples

+

Spatial Contact Force Examples

Collision
@@ -76,18 +76,31 @@
Contact Proxies
1. Point Cloud Steering Wheel: Model, Documentation
-2. Point Cloud Disk on Ramp: Model, Documentation
-3. Disk, Cylinder on Floor: Model, Documentation
-4. Grid Surface, Ball on Membrane: Model, Documentation
+2. Point Cloud Cylinder on Ramp: Model, Documentation
+3. Spinning Top (Totem), Contact Solids: Model, Documentation
+4. Spinning Top (Tippe), Point Cloud: Model, Documentation
+5. Disk, Cylinder on Floor: Model, Documentation
+6. Grid Surface, Ball on Membrane: Model, Documentation

Custom Force Laws
1. Location-Dependent Friction, Disk on Floor: Model, Documentation
+
+Point Cloud Functions
+1. Brick: Example, Code
+2. Circle: Example, Code
+3. Cylinder: Example, Code
+4. Sphere: Example, Code
+
+Convex Hull Functions
+1. STL Geometry: Example, Code
+2. Point Cloud: Example, Code
+3. Revolved Solid: Example, Code

% Copyright 2012-2022 The MathWorks(TM), Inc.