Child scripts
A child script is a simulation script. CoppeliaSim supports an unlimited number of child scripts per scene. Each child script represents a small collection of routines allowing handling a particular function in a simulation. Child scripts are attached to (or associated with) scene objects, and they can be easily recognized from their script icon in the scene hierarchy:
[A child script associated with object Robot]
Double-clicking the script icon allows opening the script editor. You can change properties of a given script via the script dialog. You can attach a new child script to an object by selecting the object, then navigating to [menu bar --> Add --> Associated child script].
A child script's association with a scene object has important and positive consequences:
Very good portability: child scripts will be saved/loaded together with their associated object. Using child scripts, you are able to create extremely portable code and simulation models that do not need to rely on any system specific plugin. A fully functional model can be contained in a single file (usable without modification across various platforms), which is not the case when relying on plugins for model control. Additionally, and for the same reason, models relying on child scripts require no maintenance over time (e.g. a new OS version will not require you to adjust portions of code or recompilation, as you might have to do when using plugins).
Inherent scalability: if an object that has an attached child script is duplicated, its child script will also be duplicated. The duplicated child script's content will be identical to the original child script's content, however, the duplicated child script will know that is was duplicated and redirect object access correctly, if relative paths were used for object access. Refer to the section on accessing scene objects programmatically for more details.
No conflict between different model versions: if you modify the child script of a given model (e.g. to customize it to your needs), this will have no consequence on other similar models. This is a much more critical aspect when relying on plugins instead of child scripts for model control: indeed, with plugins you always run the risk of having conflicts with previous plugin versions.
Very easy synchronization with the simulation loop: child scripts can run threaded or non-threaded, and can be easily synchronized with the simulation loop, which represents a powerful feature.
Child scripts can run threaded or non-threaded code. Since they only run when simulation is running, they should exclusively be used to handle simulation-time tasks.
As do other script types, child scripts should mainly contain a collection of functions. The entrance functions are callback functions. Functions that are not running threaded (i.e. that are not running in a coroutine) should not be blocking. This means that every time they are called, they should perform some task and then return control. If control is not returned, then the whole simulation halts. Child script functions are called by the main script at least twice per simulation step from the main script's actuation and sensing functions. The system will also call other system callback functions where appropriate (e.g. during child script initialization, clean-up, etc).
Child scripts also follow a precise calling or execution order: by default, child scripts are called starting with leaf objects (or childless objects), and ending with root objects (or parentless objects). A child script is typically segmented into a collection of system callback functions, the most important ones are:
the initialization function: sysCall_init. This system callback function is the only one that is not optional. It will be executed just one time (the first time the child script is called). This can be at the beginning of a simulation, but also in the middle of a simulation: remember that objects associated with child scripts can be copy/pasted into a scene at any time, also when a simulation is running. Usually you would put some initialization code as well as handle retrieval in this part. Or, if your code is meant to run threaded, then you would prepare one or several coroutines in that part.
the actuation function: sysCall_actuation. This part will be executed in each simulation step, during the actuation phase of a simulation step. Refer to the main script default code for more details about the actuation phase, but typically, you would do some actuation in this part (no sensing). Or, if an actuation function is meant to run threaded, then you would resume the coroutine of that function in that part.
the sensing function: sysCall_sensing. This part will be executed in each simulation step, during the sensing phase of a simulation step. Refer to the main script default code for more details about the sensing phase, but typically, you would only do sensing in this part (no actuation). Or, if a sensing function is meant to run threaded, then you would resume the coroutine of that function in that part.
the restoration function: sysCall_cleanup. This part will be executed one time just before a simulation ends, or before the script is destroyed.
|