2 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 // Copyright (C) 2008 - INRIA - Serge Steer <Serge.Steer@scilab.org>
5 // This file is distributed under the same license as the Scilab package.
8 //The graphics objects builder and subsidiaries
9 //--------------------------------------------
10 function [H]=build_levitron(h)
11 //construct the graphical object representing the levitron in 3D
13 n=21;// assumed to be odd
14 [X, Y, Z]=levitron_facets(levitron_profile, n)
17 f = get("levitron_main_figure")
20 f.color_map = graycolormap(N);
21 f.immediate_drawing = "off"
23 s=[((N/2)):(N-1), N:-1:((N/2)+1)];
24 plot3d(X, Y, list(Z, ones(1, np-1).*.s))// the top
32 H.user_data=[0 0 0 0 0 0];
35 param3d(zeros(x), zeros(x), x) //z axis
36 e=gce();e.thickness=2;
38 plot3d([-1 1]*1.5, [-1 1]*1.5, zeros(2, 2))
39 e=gce();e.color_mode=color("red");
41 levitron_axes = gca();
42 //Axes definition for the plot
43 //plot will be on the left-hand side of the screen
44 levitron_axes.axes_bounds = [0 0 3.5/5 1];
45 levitron_axes.tight_limits="on";
46 levitron_axes.clip_state="off";
47 levitron_axes.data_bounds=[-1 -1 0;1 1 2];
48 levitron_axes.axes_visible="off";
49 levitron_axes.box="off";
50 levitron_axes.cube_scaling="on";
51 levitron_axes.isoview="on";
52 levitron_axes.rotation_angles=[76 45];
53 levitron_axes.foreground=N
54 levitron_axes.x_label.text=""
55 levitron_axes.y_label.text=""
56 levitron_axes.z_label.text=""
58 immediate_drawing ="on"
62 function [zp, ro]=levitron_profile()
63 //zp : elevation of the profile's points
66 zp = [0.6;0.22;0.15;0.06;0.04;0.02;-0.04;-0.06;
67 -0.07;-0.15;-0.19;-0.27;-0.34;-0.38]*0.8;
68 ro = [0;0.03;0.07;0.42;0.43;0.44;0.44;
69 0.43;0.42;0.07;0.05;0.03;0.02;0];
73 function [X, Y, Z]=levitron_facets(prof, n)
74 //computes the facets of the surface of a revolution surface
75 // prof is a function that returns the elevation and the radiud of ech
77 // n: is the number of points for the rotation angle discretization
79 [zp, ro]=prof();//one profile
81 //generate points on the top surface
82 t=linspace(0, 2*%pi, n);
88 Iz=([0;0;1;1]*ones(1, np-1)+ones(4, 1)*(1:(np-1))).*.ones(1, n-1);
89 It=ones(1, np-1).*.([0;1;1;0]*ones(1, n-1)+ones(4, 1)*(0:(n-2)));
90 I=matrix(Iz+np*It, -1, 1);
91 X=matrix(x(I), 4, -1);
92 Y=matrix(y(I), 4, -1);
93 Z=matrix(z(I), 4, -1);
98 //-------------------------------------------------------------
100 function update_height(h)
101 Slider_Height=get("slider_height");
102 Value_Height =get("value_height")
104 Slider_Height.Value=(h-1.6)*100/0.2;
106 h=Slider_Height.Value
107 h=max(0.001, 1.6+h*0.2/100)
109 Value_Height.String=msprintf("%.3f", h)
113 function update_theta(t)
114 Slider_Theta=get("slider_theta")
115 Value_Theta=get("value_theta")
117 Slider_Theta.Value=(t-0.01)*100;
122 Value_Theta.String=msprintf("%.3f", t)
126 function update_phi(p)
127 Slider_Phi=get("slider_phi")
128 Value_Phi=get("value_phi")
130 Slider_Phi.Value=p*100/360;
135 Value_Phi.String=msprintf("%.3f", p)
139 function update_psi(p)
140 Slider_Psi=get("slider_psi")
141 Value_Psi=get("value_psi")
143 Slider_Psi.Value=p*100/360;
148 Value_Psi.String=msprintf("%.3f", p)
153 function levitron_start()
158 function levitron_stop()
162 function levitron_reinit()
173 // Callbacks subsidiary functions
174 //-------------------------------
175 function update_state(k, value)
176 global y1 state_changed init Stop changed
178 if or(k==(4:6)) then value=value*%pi/180;end
188 function set_levitron(H, q)
191 f=20 //Dilatation factor of X and Y coordinates
192 XYZ=[matrix(Data.x-f*O(1), 1, -1)
193 matrix(Data.y-f*O(2), 1, -1)
194 matrix(Data.z-O(3), 1, -1)];
195 psi =q(6); //precession:rotation Oxyz ->Ouvz
196 theta=q(4);//nutation Ouvz -> Ouwz'
197 phi =q(5);// rotation propre Ouwz'->0x'y'z' (referentiel attache a la toupie)
199 XYZ=euler(psi, theta, phi)*eulerm1(O(6), O(4), O(5))*XYZ
202 Data.x=f*q(1)+matrix(XYZ(1, :), 4, -1);
203 Data.y=f*q(2)+matrix(XYZ(2, :), 4, -1);
204 Data.z=q(3)+matrix(XYZ(3, :), 4, -1);
205 H.user_data(1:6)=q(1:6)';
211 global y1 state_changed init Stop changed
212 //y1 is a copy of that can be updated by the gui (state_changed is true
213 //if the GUI has modified its value).
217 if state_changed then y=y1;end
218 [y, w, iw]=ode(y, 0, dt, list(levitron_dyn, a, c, Mc)); y1=y;
223 if state_changed then
224 [y, w, iw]=ode(y1, t0, t0+dt, list(levitron_dyn, a, c, Mc));y1=y;
226 [y, w, iw]=ode(y, t0, t0+dt, list(levitron_dyn, a, c, Mc), w, iw);y1=y;
228 if y(3)<=0 then Stop=%t, end
229 if Stop then init=%t, break, end
230 if ~is_handle_valid(H) then break; end
231 set_levitron(H, y(1:6));
236 update_theta(y(4)*180/%pi)
237 update_phi(modulo(y(5)*180/%pi, 360))
238 update_psi(modulo(y(6)*180/%pi, 360))
247 function levitron_create_gui()
248 //Simulation parameters
249 height_param = tlist(["sim_param", "name", "unit", "default"]);
250 height_param.name = "height";
251 height_param.unit = "m";
252 height_param.default = (1.72-1.6)*50;
254 theta_param = tlist(["sim_param", "name", "unit", "default"]);
255 theta_param.name = "theta"
256 theta_param.unit = "deg"
257 theta_param.default = 28;
259 phi_param = tlist(["sim_param", "name", "unit", "default"]);
260 phi_param.name = "phi"
261 phi_param.unit = "deg"
262 phi_param.default = 0;
264 psi_param = tlist(["sim_param", "name", "unit", "default"]);
265 psi_param.name = "psi"
266 psi_param.unit = "deg"
267 psi_param.default = 0
269 param_list = list(height_param, theta_param, phi_param, psi_param);
271 //Create the figure and the frame to put the sliders
272 levitron_main_fig = figure( ...
273 "dockable", "off", ...
274 "infobar_visible", "off", ...
275 "toolbar_visible", "off", ...
276 "toolbar", "none", ...
277 "menubar_visible", "off", ...
278 "menubar", "none", ...
279 "default_axes", "on", ...
280 "layout", "none", ...
281 "visible", "off", ...
282 "immediate_drawing", "off", ...
283 "background", -2, ...
284 "figure_position", [0 0], ...
285 "axes_size", [800, 600], ...
286 "figure_name", "Levitron Simulation", ...
287 "tag", "levitron_main_figure");
290 levitron_main_fig.layout = "gridbag"
292 //An empty frame to push parameters on the right when resizing
293 c = createConstraints("gridbag", [1, 1, 1, 1], [0.75, 1], "horizontal", "upper_left", [0, 0], [500, 0])
294 empty_frame = uicontrol(levitron_main_fig, "style", "frame", "constraints", c, "backgroundcolor", [1, 0, 0]);
296 c = createConstraints("gridbag", [2, 1, 1, 1], [0.25, 1], "both", "right", [0, 0], [300, 0]);
297 right_frame = uicontrol(levitron_main_fig, "style", "frame", "backgroundcolor", [1, 1, 1], ...
300 right_frame.layout = "border";
301 right_frame.layout_options = createLayoutOptions("border");
303 l_border = createBorder("line", "black", 2)
304 param_border = createBorder("titled", l_border, "Simulation Parameters", "center", "top")
305 c = createConstraints("border", "center");
306 param_frame = uicontrol(right_frame, "style", "frame", "backgroundcolor", [1, 1, 1], ...
307 "constraints", c, "tag", "param_frame", "border", param_border, "layout", "gridbag");
309 c = createConstraints("border", "bottom", [0, 50]);
310 button_frame = uicontrol(right_frame, "style", "frame", "backgroundcolor", [1, 1, 1], ...
311 "constraints", c, "tag", "button_frame", "layout", "gridbag");
313 c = createConstraints("border", "right", [10, 0]);
314 empty_frame = uicontrol(right_frame, "style", "frame", "backgroundcolor", [1, 1, 1], ...
317 c = createConstraints("border", "left", [10, 0]);
318 empty_frame = uicontrol(right_frame, "style", "frame", "backgroundcolor", [1, 1, 1], ...
321 gui_createParamFrame(param_list);
322 gui_createButtonFrame();
325 function gui_createParamFrame(param_list);
326 param_frame = get("param_frame");
328 for i = 1:size(param_list)
329 c = createConstraints("gridbag", [1, i, 1, 1], [1, 1], "both", "left", [5, 0], [25, 0]);
330 name_p = uicontrol(param_frame, ...
332 "String", param_list(i).name + " ", ...
333 "BackgroundColor", [1 1 1], ...
334 "horizontalalignment", "right", ...
335 "constraints", c, ...
336 "tag", "text_" + param_list(i).name);
338 c = createConstraints("gridbag", [2, i, 1, 1], [1, 1], "both", "center", [0, 0], [60, 0]);
339 slider_p = uicontrol(param_frame, ...
340 "Style", "slider", ...
341 "Value", param_list(i).default, ...
344 "callback", "update_" + param_list(i).name + "()", ...
345 "constraints", c, ...
346 "horizontalalignment", "center", ...
347 "backgroundcolor", [1, 1, 1], ...
348 "tag", "slider_" + param_list(i).name);
350 c = createConstraints("gridbag", [3, i, 1, 1], [1, 1], "both", "left", [15, 0], [25, 0]);
351 value_p = uicontrol(param_frame, ...
353 "String", msprintf("%.3f", param_list(i).default), ...
354 "BackgroundColor", [1 1 1], ...
355 "constraints", c, ...
356 "foregroundcolor", [0 0 1], ...
357 "horizontalalignment", "right", ...
358 "tag", "value_" + param_list(i).name);
360 c = createConstraints("gridbag", [4, i, 1, 1], [1, 1], "both", "right", [5, 0], [25, 0]);
361 unite_p = uicontrol(param_frame, ...
363 "String", " " + param_list(i).unit, ...
364 "BackgroundColor", [1 1 1], ...
365 "constraints", c, ...
366 "horizontalalignment", "left", ...
367 "tag", "unite_" + param_list(i).name);
372 function gui_createButtonFrame();
373 button_frame = get("button_frame");
375 c = createConstraints("gridbag", [1, 1, 1, 1], [1, 1], "horizontal", "left");
376 empty = uicontrol(button_frame, "style", "frame", "backgroundcolor", [1, 1, 1], "constraints", c);
378 c = createConstraints("gridbag", [2, 1, 1, 1], [0, 0], "none", "center");
379 Start = uicontrol("parent", button_frame, ...
380 "Style" , "pushbutton", ...
381 "String" , "Start", ...
382 "callback" , "levitron_start()", ...
383 "constraints", c, ...
386 c = createConstraints("gridbag", [3, 1, 1, 1], [1, 1], "horizontal", "center");
387 empty = uicontrol(button_frame, "style", "frame", "backgroundcolor", [1, 1, 1], "constraints", c);
389 c = createConstraints("gridbag", [4, 1, 1, 1], [0, 0], "none", "center");
390 Stop = uicontrol("parent", button_frame, ...
391 "Style" , "pushbutton", ...
392 "String" , "Stop", ...
393 "callback" , "levitron_stop()", ...
394 "callback_type", 12, ...
395 "constraints", c, ...
398 c = createConstraints("gridbag", [5, 1, 1, 1], [1, 1], "horizontal", "center");
399 empty = uicontrol(button_frame, "style", "frame", "backgroundcolor", [1, 1, 1], "constraints", c);
401 c = createConstraints("gridbag", [6, 1, 1, 1], [0, 0], "none", "center");
402 Reinit = uicontrol("parent", button_frame, ...
403 "Style" , "pushbutton", ...
404 "String" , "Reset", ...
405 "callback" , "levitron_reinit()", ...
406 "callback_type", 12, ...
407 "constraints", c, ...
410 c = createConstraints("gridbag", [7, 1, 1, 1], [1, 1], "horizontal", "right");
411 empty = uicontrol(button_frame, "style", "frame", "backgroundcolor", [1, 1, 1], "constraints", c);