Goals: Simulate the internal mechanisms of predation in the scorpion
The objective of this step is to program the class NeuronalScorpion capable of simulating the predation mechanisms of the scorpion.
We will consider that NeuronalScorpion is equipped with 8 sensors located at the end of its legs. To simplify, these sensors will be equidistant from the center of the scorpion, on a radius getAppConfig().scorpion_sensor_radius from the Vec2d serving as the scorpion's position:
![]() | ← simplified modeling of sensors (green circles) The CircularCollider has been drawn in black for better visibility. |
Start by creating an empty Sensor class.
Then code a primer of the class NeuronalScorpion derived from Scorpion . A NeuronalScorpion is characterized by:
We will see a little later that the NeuronalScorpion will be in different states (similar to the standard Scorpion ). When one of its sensors is activated, the scorpion goes into a state indicating that it perceives the signals of a wave and will remain in this state for a limited time. When this time is up, it will deactivate all of its sensors.
[Question Q4.5] How do you propose to represent all the sensors and their angles in NeuronalScorpion ? Answer this question in your file ANSWERS , justifying your choices.
The calculation made by NeuronalScorpion to estimate the direction of its target will depend on the position of its sensors. It is therefore wise to provide this class with a getPositionOfSensor method returning the position of a given sensor in the global reference frame.
[Question Q4.6] What prototype do you propose for the getPositionOfSensor method? Answer this question in your file ANSWERS , justifying your choices.
It is now a matter of modeling the sensors more precisely.
Each sensor is essentially characterized by:
A sensor is activated when the waves that touch it (or more precisely that touch its position) accumulate an intensity exceeding a certain threshold (getAppConfig().sensor_intensity_threshold).
The intensity of the waves in the environment at a given point is calculated as the sum of the intensities of each wave at that point.
The intensity of a wave at a point location is calculated as follows: if location is on the radius of the wave (to the nearest getAppConfig().wave_on_wave_marging ), and if location belongs to one of the arcs of the latter, then the intensity will be calculated as described here , otherwise it will be zero.
[Question Q4.7] What method(s) do you add and to which class(es) so that a sensor can know the cumulative intensity of the waves that touch it; without coding overly intrusive getters giving access to all the waves in the environment? Answer this question in your file file REPONSES and adapt your code accordingly.
As soon as it is activated, a sensor will increase its score with each simulation step. It will also begin to inhibit a number of sensors located in front of it.
![]() | ← the sensor 5 inhibits sensors 0, 1, and 2
|
Let s i be a sensor connected to the sensor this . Over a time step dt , this will act on s i by increasing its degree of inhibition proportionally to its own score (the higher the score of this , the more it inhibits s i ). Concretely, the degree of inhibition of s i will be increased by the score of this multiplied by getAppConfig().sensor_inhibition_factor .
To summarize, at each simulation step and as long as it is active, a sensor increases the degree of inhibition of the sensors connected to it and updates its own score by increasing it by 2.0 * (1.0 - inhibitor).
When inactive, the sensor will listen for potential waves. The algorithm is simply as follows: if the intensity of a wave perceived at the sensor's position is strong enough (greater than getAppConfig().sensor_intensity_threshold), the sensor becomes active.
[Question Q4.8] The sensor, to know its position, therefore needs to know the scorpion to which it belongs. What does this imply in terms of dependencies between the classes NeuronalScorpion and Sensor ? How do you manage it? Answer these questions in your file ANSWERS .
[Question Q4.9] Does this have an impact on how to build a sensor? Answer these questions in your file file REPONSES by justifying your answer.
Given the above, provide the complete coding for the Sensor class. This class should derive from Updatable and update its score and inhibition level according to the previous description. You won't worry about drawing the sensors for now .
As mentioned previously, the NeuronalScorpion is only sensitive to sensor activation for a limited time. Once this time has elapsed, it will deactivate all of its sensors.
Now that the sensors are coded, we can complete the behavioral aspects of the NeuronalScorpion . The operation of this type of scorpion (method update and updateState ) only takes into account predation .
Below you will find information on:
The direction towards the target estimated by the scorpion is simply the resultant:

where s i is the score of sensor i and v⃗ i its position vector.

An estimate d⃗ of the target direction will be associated with a score given simply by the norm of d⃗ .
The behavior of a NeuronalScorpion is conditioned by states different from those of the Scorpion (to take into account only predation in particular):
[Question Q4.10] How and where do you propose to model the possible states? Answer this question in your file file REPONSES by justifying your choices.
[Question Q4.11] How do you propose to model the clocks associated with states? Answer this question in your file file REPONSES justifying your choices.
The implemented algorithm is as follows:
[Question Q4.12] What actions related to the management of the different clocks involved must you undertake and in which states of the scorpion? Answer this question in your file file REPONSES by justifying your answer.
To be compatible with the provided test files, the NeuronalScorpion will have constructors with signatures similar to those coded for Scorpion . It will have WANDERING as its default state. The estimated direction of the target is of course zero initially.
The provided test NeuronalTest.cpp , which you can run using the command scons NeuronalTest-run for example, allows you to test the scorpion's perception of waves.
It is programmed so that a left click with the mouse creates a wave. You should see the scorpion orient itself based on the perception of this wave as shown by the following video:
| [Video: Neural model of the scorpion] |
Also test the fact that obstacles block the scorpion's perception of waves.
If the scorpion does not behave as desired, some graphical supplements can help you "debug" your code.
To verify your developments, complete the display in "debugging" mode so as to:
You should be able to observe a functioning similar to that shown in the short video below.
| [Video: Display of the neural model in "debugging" mode] |
The "debugging" mode display will allow you to verify that the obstacles indeed block the activation of the neurons.
| [Video: Obstacles preventing neuron activation] |
The provided test FinalApplication.cpp allows you to test the coexistence of a NeuronalScorpion and a WaveLizard in an environment.
The test launch modalities will be as follows:
The scorpion should then be able to locate the lizard using the waves it emits, as shown in the video below:
| [Video: Scorpion detecting a lizard outside its field of vision thanks to the perception of waves it emits while walking.] |
The neural model simulation is now complete. Congratulations on achieving the desired result! In the final stage of the project, you will refine the simulation tool a bit and have the opportunity to code some freely chosen extensions.