1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2% 3% FILE: Env/env_sim.pl 4% 5% Author : Sebastian Sardina 6% Time-stamp: <03/12/19 10:51:50 ssardina> 7% email : ssardina@cs.toronto.edu 8% WWW : www.cs.toronto.edu/~ssardina 9% TESTED : SWI Prolog 5.0.10 http://www.swi-prolog.org 10% ECLiPSe 5.3 on RedHat Linux 6.2-7.2 11% TYPE CODE : system independent predicates 12% 13% This files provides a *simulted* environment interface with which 14% it is possible to set exogenous events in an asynchronous ways using 15% a TCL/TK application, type sensing outcome for actions 16% 17% The interface to enter exogenous events from the keyboard is 18% achieved with a simple TCL/TK program where exogenous action can 19% be typed at any time. 20% 21% 22% This environment is self-contained (automatically it loads the required 23% libraries). It should be called as follows: 24% 25% eclipse host=<HOST> port=<PORT> -b env_sim.pl -e start 26% pl host=<HOST> port=<PORT> -b env_sim.pl -e start 27% 28% where HOST/PORT is the address of the environment manager socket. 29% 30% Written for ECLiPSe Prolog (http://www.icparc.ic.ac.uk/eclipse/) 31% and SWI Prolog (http://www.swi-prolog.org) running under Linux 6.2-8.0 32%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33% 34% March 22, 2003 35% 36% This software was developed by the Cognitive Robotics Group under the 37% direction of Hector Levesque and Ray Reiter. 38% 39% Do not distribute without permission. 40% Include this notice in any copy made. 41% 42% 43% Copyright (c) 2000 by The University of Toronto, 44% Toronto, Ontario, Canada. 45% 46% All Rights Reserved 47% 48% Permission to use, copy, and modify, this software and its 49% documentation for non-commercial research purpose is hereby granted 50% without fee, provided that the above copyright notice appears in all 51% copies and that both the copyright notice and this permission notice 52% appear in supporting documentation, and that the name of The University 53% of Toronto not be used in advertising or publicity pertaining to 54% distribution of the software without specific, written prior 55% permission. The University of Toronto makes no representations about 56% the suitability of this software for any purpose. It is provided "as 57% is" without express or implied warranty. 58% 59% THE UNIVERSITY OF TORONTO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 60% SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 61% FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TORONTO BE LIABLE FOR ANY 62% SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 63% RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 64% CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 65% CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 66% 67%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 68% 69% This file assumes that the following is defined in env_gen.pl: 70% 71% -- start/0 : initialization of the environment (called when loaded) 72% -- finalize/0 : finalization of the environment (called when exiting) 73% -- main_dir/1 : obtain the root IndiGolog directory 74% -- report_exog_event(A, M): 75% report exogenous event A with message M to the 76% environment manager 77% -- All compatibility libraries depending on the architecture such us: 78% -- compat_swi/compat_ecl compatibility libraries providing: 79% 80% -- The following two dynamic predicates should be available: 81% -- listen_to(Type, Name, Channel) 82% listen to Channel of Type (stream/socket) with Name 83% -- terminate/0 84% order the termination of the application 85% 86% 87% -- The following should be implemented here: 88% 89% -- name_dev/1 : mandatory * 90% -- initializeInterfaces(L) : mandatory * 91% -- finalizeInterfaces(L) : mandatory * 92% -- execute/4 : mandatory * 93% -- handle_steam/1 : as needed 94% -- listen_to/3 : as needed 95% 96% FROM PROLOG DEPENDENT USER LIBRARY (SWI, ECLIPSE, LIBRARY): 97% 98% -- call_to_exec(+System, +Command, -Command2) 99% Command2 executes Command in plataform System 100% 101% 102% Also, this device manager requires: 103% 104% -- wish for running TCL/TK applications 105% -- exog.tcl TCL/TK script 106% 107%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 108:- include(env_gen). % INCLUDE THE CORE OF THE DEVICE MANAGER 109 110%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 111% CONSTANTS TO BE USED 112% 113% name_dev/1 : state the name of the device manager (e.g., simulator, rcx) 114%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 115 116% Name of the environment: <SIMULATOR> 117% Set name of the environment here. 118% THIS CONSTANT IS MANDATORY, DO NOT DELETE! 119name_dev(simulator). 120 121% Set verbose debug level 122:- set_debug_level(3). 123 124%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 125% A - INITIALIZATION AND FINALIZATION OF INTERFACES 126% initializeInterfaces/1 and finalizeInterfaces/1 127% 128% HERE YOU SHOULD INITIALIZE AND FINALIZE EACH OF THE INTERFACES TO BE USED 129%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 130initializeInterfaces(_) :- initializeExog(tcltk). 131finalizeInterfaces(_) :- finalizeExog(tcltk). 132 133 134 135%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 136% TCL/TK EXOGENOUS ACTIONS GENERATOR - from keyboard via Tcl/Tk interface 137% 138% This part implements a keyboard interface to enter exogenous events 139% in an asynchronous manner. 140% 141% If an exogenous event arrives via the keyboard, it is handled as soon 142% as possible by calling handle_event/1 143% 144% -- initializeExog(virtual): 145% perform any initialization of other sources of 146% exogenous actions that is required 147% -- finalizeExog(virtual): 148% things to do for other sources of exogenous actions 149% at end of program 150% -- checkOtherExog(virtual,-ExogList): 151% check whether a request has been entered via keyboard 152% 153%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 154 155% initializeExog(tcltk): initialization for sources of exogenous actions from 156% virtual interface 157% 158% An TCL/TK independent process is initiated to read exogenous events 159% the program exog.tcl writes each exogenous action entered to a special pipe. 160% At that time, a sigio signal is assigned to such pipe so that whenever data 161% arrives to the pipe an interrupt is triggered which can be cached 162% by the main cycle to handle the exog action entered. 163tcltk_exog_file(File):- main_dir(Dir), 164 concat_atom([Dir,'Env/exog.tcl'], File). 165 166initializeExog(tcltk) :- 167 printKbInstructions, 168 % Run the command as a child and send its *output* to pipe "tcltk" 169 tcltk_exog_file(File), 170 concat_atom(['wish ', File], Command), 171 call_to_exec(unix, Command, Command2), 172 exec_group(Command2, [null, tcltk, null], P), 173 sleep(2), % Give time to TCL/TK program to appear 174 assert(exog_proc(P)), % Store child pid for later 175 assert(listen_to(stream, tcltk, tcltk)). % listen to tcltk 176 177% finalizeExog: Things to do for sources of exogenous actions from the 178% virtual interface 179finalizeExog(tcltk) :- 180 listen_to(stream, tcltk, tcltk), !, % tcltk is still open 181 report_message(system(1), 'Closing Tcl/Tk interface.'), 182 retract(listen_to(stream, tcltk, tcltk)), % de-register interface 183 retract(exog_proc(P)), 184 (proc_kill(P) -> true ; true). 185finalizeExog(tcltk). % It was already down 186 187% printKbInstructions: Print instructions on how to enter keyboard input 188printKbInstructions :- 189 writeln('*********************************************************'), 190 writeln('* NOTE: This is the SIMULATOR environment'), 191 writeln('* You can enter exogenous actions using the TCL/TK window.'), 192 writeln('* Action execution will be printed here and sensing '), 193 writeln('* outcome will be asked to the user'), 194 writeln('* Actions that are not executed in any other device are'), 195 writeln('* executed here.'), 196 writeln('*********************************************************'), nl. 197 198 199%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 200% B - HANDLERS FOR EACH STREAM/SOCKET THAT IS BEING HEARD: handle_stream/1 201% 202% HERE YOU SHOULD WRITE HOW TO HANDLE DATA COMMING FROM EACH OF THE 203% INTERFACES/CHANNELS USED 204%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 205 206% Handle tcl/tk stream: called when there is data comming from the tcl/tk app 207handle_stream(tcltk) :- 208 read(tcltk, A), 209 (A=end_of_file -> 210 true % Tcl/Tk finished 211 ; 212 report_exog_event(A, ['Exogenous action *',A,'* received from TCL/TK']) 213 ). 214 215 216%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 217% C - EXECUTION MODULE: execute/4 218% 219% This part implements the execution capabilities of the environment 220% 221% execute(Action, Type, N, Sensing) : execute Action of Type and return Sensing 222%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 223% Simulate the execution of Action. 224% SensingResult is the sensing outcome of Action 225execute(Action, T, _, Sensing) :- 226 member(T, [sensing, simsensing]), !, 227 report_message(action, ['Executing sensing action: *',Action,'*']), 228 write(' ------------> Enter Sensing value, terminate with ".": '), 229 read(Sensing), nl. 230 231execute(Action, _, _, ok) :- 232 report_message(action, ['Executing non-sensing action: *',Action,'*']). 233 234 235 236%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 237%%%%%%%%%%%%%%%%%% OTHER CODE %%%%%%%%%%%%%%%%% 238%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 239:- type_prolog(ecl) -> 240 set_event_handler(170, my_system_error_handler/2) ; true. 241 242my_system_error_handler(E, Goal) :- 243 ( 244 errno_id(`Interrupted system call`), 245% errno_id(170, M), errno_id(M), % M is "Unknown error 170" ?? 246 restartable_builtin(Goal) 247 -> 248 call(Goal) 249 ; 250 errno_id(M), 251 report_message(error, M), 252 read(_), 253 error(default(E), Goal) 254 ). 255 256% Builtins that can raise EINTR and can be restarted after that 257restartable_builtin(accept(_,_,_)). 258restartable_builtin(cd(_)). 259restartable_builtin(close(_)). 260restartable_builtin(connect(_,_)). 261restartable_builtin(select_stream(_,_,_)). 262restartable_builtin(stream_select(_,_,_)). 263restartable_builtin(wait(_,_)). 264 265 266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 267% Exogenous action window in SWI itself (instead of TCL/TK) 268%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 269/* 270:- use_module(library(pce)). 271 272fileviewer(Dir) :- 273 new(F, frame('File Viewer')), 274 send(F, append(new(B, browser))), 275 send(new(D, dialog), below(B)), 276 send(D, append(button(view, 277 message(@prolog, view, 278 B?selection?key)))), 279 send(D, append(button(quit, 280 message(F, destroy)))), 281 send(B, members(directory(Dir)?files)), 282 send(F, open). 283 284view(F) :- 285 send(new(V, view(F)), open), 286 send(V, load(F)). 287 288 289 290%:- pce_autoload(file_item, library(file_item)). 291 292 293edit_file_dialog :- 294 new(D, dialog('Exogenous Events')), 295 send(D, append, new(E, text_item(exog, @default, 296 and(message(@prolog, reportTea, @arg1), 297 message(@receiver,clear)) 298 ))), 299 send(D, append, button(send, 300 and(message(@prolog, reportTea, E?selection), 301 message(E,clear)) 302 )), 303 send(D, append, button(cancel, message(D, destroy))), 304 send(D, append, button(halt, message(@prolog, terminateTea))), 305 send(D, open). 306 307 308reportTea(E) :- report_message(action, ['Executing non-sensing action: *',E,'*']). 309terminateTea :- report_message(action, terminate). 310 311 312 313 % ask_name(+Prompt, +Label, -Name) 314 % Put a prompter on the screen and wait till the user has 315 % entered a name. Pressing cancel makes this predicate fail. 316 % Prompt is a long string, giving explanation; Label is a short 317 % label displayed for the text entry field. 318 319 320 :- pce_global(@name_prompter, make_name_prompter). 321 322 make_name_prompter(P) :- 323 new(P, dialog), 324 send(P, kind, transient), 325 send(P, append, label(prompt)), 326 send(P, append, 327 new(TI, text_item(name, '', 328 message(P?ok_member, execute)))), 329 send(P, append, button(ok, message(P, return, TI?selection))), 330 send(P, append, button(cancel, message(P, return, @nil))). 331 332 333 ask_name(Prompt, Label, Name) :- 334 send(@name_prompter?prompt_member, selection, Prompt), 335 send(@name_prompter?name_member, label, Label), 336 send(@name_prompter?name_member, clear), 337 get(@name_prompter, confirm_centered, RawName), 338 send(@name_prompter, show, @off), 339 RawName \== @nil, 340 Name = RawName. 341 342 ask_name :- 343 ask_name('Street', name, Street), 344 writeln(Street). 345 346 347create_fill_pattern_dialog :- 348 new(Dialog, dialog('Fill Patterns')), 349 send(Dialog, append, 350 new(M, menu(fill_pattern, cycle, 351 message(@prolog, write_ln, @arg1)))), 352 send_list(M, append, 353 [ menu_item(white, @default, opcion1) 354 , menu_item(grey12, @default, opcion2) 355 , menu_item(grey25, @default, opcion3) 356 , menu_item(grey50, @default, opcion4) 357 ]), 358 send(Dialog, open). 359 360*/ 361 362 363 364%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 365% EOF: Env/env_sim.pl 366%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%