* Bug #10433 fixed - Xcos stop simulation button
[scilab.git] / scilab / modules / xcos / macros / xcos_simulate.sci
1 //
2 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 // Copyright (C) 2009-2009 - DIGITEO - Bruno JOFRET
4 //
5 // This file must be used under the terms of the CeCILL.
6 // This source file is licensed as described in the file COPYING, which
7 // you should have received as part of this distribution.  The terms
8 // are also available at
9 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10 //
11 //
12
13 function %cpr = xcos_simulate(scs_m, needcompile)
14
15 // Load the block libs if not defined
16   prot = funcprot();
17   funcprot(0);
18     if ~exists("scicos_diagram") then
19         loadXcosLibs();
20     end
21   funcprot(prot);
22   [modelica_libs, scicos_pal_libs, %scicos_with_grid, %scs_wgrid] = initial_scicos_tables();
23
24     // Hook according to SEP066
25     if isdef("pre_xcos_simulate") then
26       try
27       continueSimulation = pre_xcos_simulate(scs_m, needcompile);
28       if ~continueSimulation then
29         %cpr = []
30         return
31       end
32       catch
33       disp(_("Error occurred in pre_xcos_simulate: Cancelling simulation."))
34       %cpr = []
35       return
36       end
37     end
38
39   //**---- prepare from and to workspace stuff ( "From workspace" block )
40   scicos_workspace_init()
41
42
43 //** extract tolerances from scs_m.props.tol
44   tolerances = scs_m.props.tol ;
45   //** extract solver type from tolerances
46   solver = tolerances(6) ;
47   //** initialize a "scicos_debug_gr" variable
48   %scicos_debug_gr = %f;
49
50   ////////////////////////////////////////////////////////////////
51   // Add global environment variable so that scicos is not lost //
52   ////////////////////////////////////////////////////////////////
53   if needcompile == 4 then
54     %state0     = list();
55     needcompile = 4;
56     curwin      = 1000;
57     %cpr        = struct();
58     %tcur       = 0;
59     %cpr.state  = %state0;
60     alreadyran = %f;
61   else
62     %state0 = %cpr.state;
63     alreadyran = %f;
64   end
65
66   tf          = scs_m.props.tf;
67   %zoom       = 1.4;
68   Select      = [];
69
70   //** extract tolerances from scs_m.props.tol
71   tolerances = scs_m.props.tol ;
72   //** extract solver type from tolerances
73   solver = tolerances(6) ;
74
75   // Propagate context through all blocks
76   %scicos_context = struct();
77   context = scs_m.props.context;
78   //** context eval here
79   [%scicos_context, ierr] = script2var(context, %scicos_context);
80
81   //for backward compatibility for scifunc
82   if ierr==0 then
83     %mm = getfield(1,%scicos_context)
84     for %mi=%mm(3:$)
85       ierr = execstr(%mi+'=%scicos_context(%mi)','errcatch')
86       if ierr<>0 then
87         break; //** in case of error exit
88       end
89     end
90   end
91   //end of for backward compatibility for scifuncpagate context values
92
93   [scs_m,%cpr,needcompile,ok] = do_eval(scs_m, %cpr, %scicos_context);
94   if ~ok then
95       msg = msprintf(gettext("%s: Error during block parameters evaluation.\n"), "Xcos");
96       messagebox(msg, "Xcos", "error");
97       error(msprintf(gettext("%s: Error during block parameters evaluation.\n"), "xcos_simulate"));
98   end
99
100   //** update parameters or compilation results
101   [%cpr,%state0_n,needcompile,alreadyran,ok] = do_update(%cpr,%state0,needcompile)
102   if ~ok then
103     error(msprintf(gettext("%s: Error during block parameters update.\n"), "xcos_simulate"));
104   end
105
106   //** if alreadyran then set the var choice
107   if alreadyran then
108     choix = ['Continue';'Restart';'End']
109   else
110     choix = [] ;
111   end
112
113   issequal = %t;
114   //** initial state has been changed
115   if ~isequal(%state0_n,%state0) then
116     issequal = %f
117   else
118     //** test typeof outtb element
119     for i=1:lstsize(%state0_n.outtb)
120       if typeof(%state0_n.outtb(i))<>typeof(%state0.outtb(i))
121         issequal = %f
122         break
123       end
124     end
125     //** test typeof oz element
126     for i=1:lstsize(%state0_n.oz)
127       if typeof(%state0_n.oz(i))<>typeof(%state0.oz(i))
128         issequal = %f
129         break
130       end
131     end
132   end
133
134   //** if state have changed
135   //** finish the simulation via do_terminate()
136   if ~issequal then
137      %state0 = %state0_n
138     [alreadyran,%cpr] = do_terminate()
139     choix = []
140   end
141
142   //** switch appropriate solver
143   if %cpr.sim.xptr($)-1<size(%cpr.state.x,'*') & solver<100 then
144     warning(["Diagram has been compiled for implicit solver"
145              "switching to implicit Solver"])
146     solver = 100 ; //** Magic number
147     tolerances(6) = solver ; //** save Magic number solver type
148   elseif (%cpr.sim.xptr($)-1==size(%cpr.state.x,'*')) & (solver==100 & size(%cpr.state.x,'*')<>0) then
149     message(["Diagram has been compiled for explicit solver"
150              "switching to explicit Solver"])
151     solver = 0 ; //** Magic number
152     tolerances(6) = solver ; //** save Magic number solver type
153   end
154
155   //** ask user what to do
156   if choix<>[] then
157     //** open dialog box
158     to_do = choose(choix,"What do you want to do")
159
160     //** if cancel then exit
161     if to_do==0 then
162       ok = %f
163       return
164     end
165
166     select choix(to_do)
167
168       case "Continue" then
169         needstart = %f ;
170         state     = %cpr.state ;
171
172       case "Restart" then
173         needstart = %t ;
174         state     = %state0 ;
175
176       case "End" then
177         state     = %cpr.state ;
178         needstart = %t ;
179         tf        = scs_m.props.tf;
180
181         //Alan: ONPEUTPASAPPELLERDOTERMINATEICI?
182         //reponse : non, car do_terminate() ne rend
183         //          pas forc�ment la main � l'utilisateur
184
185         //** run scicosim via 'finish' flag
186         ierr = execstr('[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,'+..
187                        '''finish'',tolerances)','errcatch')
188
189         %cpr.state = state
190         alreadyran = %f
191
192         //** error case
193         if ierr<>0 then
194           str_err = split_lasterror(lasterror());
195           kfun    = curblock()
196           corinv  = %cpr.corinv
197
198           if kfun<>0 then //** block error
199             path = corinv(kfun)
200             //** get error cmd for the block
201             get_errorcmd(path,'End problem.',str_err);
202
203           else //** simulator error
204             message(["End problem:";str_err])
205             //scf(curwin);
206           end
207           ok = %f
208         end
209
210         return
211     end
212
213   else //** Normal first start simulation
214
215     needstart = %t
216     state     = %state0
217
218   end
219
220   //gh_win = gcf();
221
222   //** scicos initialisation
223   if needstart then
224     //** if the simulation have already ran
225     //** and is not finished then call do_terminate
226     if alreadyran then
227       [alreadyran,%cpr] = do_terminate()
228       alreadyran = %f ;
229     end
230     //** set initial values for a new simulation
231     %tcur      = 0
232     %cpr.state = %state0
233     tf         = scs_m.props.tf;
234     if tf*tolerances==[] then
235       message(["Simulation parameters not set";"use setup button"]);
236       return;
237     end
238
239     //** Run the normal first start simulation here
240
241     //** run scicosim via 'start' flag
242     ierr = execstr('[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,'+..
243                    '''start'',tolerances)','errcatch')
244
245     %cpr.state = state ; //** save the state
246     //** error case
247     if ierr<>0 then
248       str_err=split_lasterror(lasterror());
249
250       kfun=curblock()
251       corinv=%cpr.corinv
252       if kfun<>0 then  //** block error
253         path=corinv(kfun)
254         //** get error cmd for the block
255         disp(str_err);
256         get_errorcmd(path,gettext('Initialisation problem'),str_err);
257
258
259       else //** simulator error
260         message(['Initialisation problem:';str_err])
261         //scf(curwin);
262       end
263
264       ok = %f;
265       //xset('window',curwin)
266       return
267     end
268     //scf(gh_win);
269     //xset('window',win);
270   end
271
272   //** scicos simulation
273   tf = scs_m.props.tf
274
275   // inform Xcos the simulator is going to run
276   xcosSimulationStarted();
277
278   //** run scicosim via 'start' flag
279   ierr = execstr('[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,'+..
280                      '''run'',tolerances)','errcatch')
281
282   %cpr.state = state
283
284   //** no error
285   if ierr==0 then
286     alreadyran = %t;
287     //** we are at the end of the simulation
288     //** finish the simulation via do_terminate()
289     if tf-t<tolerances(3) then
290       //disp('fin');
291       //Alan : j'enl�ve do_terminate ici car do_terminate
292       //       ne rend pas la main
293       //[alreadyran,%cpr]=do_terminate()
294       needstart  = %t;
295       alreadyran = %f;
296       //** run scicosim via 'finish' flag
297       ierr = execstr('[state,t]=scicosim(%cpr.state,tf,tf,%cpr.sim,'+..
298                      '''finish'',tolerances)','errcatch')
299
300       %cpr.state = state;
301
302       //** error case
303       if ierr<>0 then
304         str_err = split_lasterror(lasterror());
305
306         kfun   = curblock()
307         corinv = %cpr.corinv
308
309         if kfun<>0 then //** block error
310           path = corinv(kfun)
311           //** get error cmd for the block
312           get_errorcmd(path,gettext('End problem'),str_err);
313         else //** simulator error
314           message(['End problem:';str_err])
315           //scf(curwin);
316         end
317       end
318     else
319       %tcur = t;
320     end
321   //** error case
322   else
323     str_err = split_lasterror(lasterror());
324
325     alreadyran = %f;
326     kfun       = curblock();
327     corinv     = %cpr.corinv;
328
329     if kfun<>0 then //** block error
330       path = corinv(kfun);
331       //** get error cmd for the block
332       get_errorcmd(path,gettext("Simulation problem"),str_err);
333     else //** simulateur error
334       message(['Simulation problem:';str_err])
335       //scf(curwin);
336     end
337     ok = %f;
338   end
339
340   //restore saved variables in Scilab environment ( "To workspace" block )
341   [txt,files]=returntoscilab()
342   n=size(files,1)
343   for i=1:n
344     load(TMPDIR+'/Workspace/'+files(i))
345     ierr = execstr(files(i)+'=struct('"values'",x,'"time'",t)', "errcatch")
346     if ierr <> 0
347        str_err = split_lasterror(lasterror());
348        message(['Simulation problem:';str_err]);
349     end
350
351   end
352
353   // Hook according to SEP066
354   if isdef("post_xcos_simulate") then
355     try
356       post_xcos_simulate(%cpr, scs_m, needcompile);
357     catch
358       disp(_("Error in post_xcos_simulate: ending simulation."))
359     end
360   end
361
362   // finally restore the exported variables on the parent context
363   if ~isempty(txt) then
364     ierr = execstr(txt, "errcatch")
365     if ierr <> 0 then
366         str_err = split_lasterror(lasterror());
367         message(['Simulation problem while executing <'+txt+'>:';str_err]);
368     end
369   end
370 endfunction
371