Chapter 27 | The Smart Optimizer
Introduction
With the Winter 2025 Software Update, Virtual CRASH 6 introduces the new Smart Optimizer, an advanced search and optimization tool designed to streamline the accident reconstruction process. This powerful system automatically iterates over your selected input variables, such as speeds, positions, impact parameters, and more, in order to rapidly generate a range of simulation scenarios that align with the physical evidence. By intelligently evaluating each iteration against your defined constraints and objectives, the Smart Optimizer identifies the combinations that most accurately satisfy your reconstruction goals. Whether you are refining initial conditions, testing alternative hypotheses, or exploring the sensitivity of specific parameters, the Smart Optimizer significantly reduces the time required to arrive at defensible and evidence-based solutions. Read on to learn more about how this amazing feature, available only in Virtual CRASH 6, can enhance both the speed and precision of your simulation workflow!
A Gentle Introduction | Slide-to-Stop Analysis
To begin using the Smart Optimizer, simply create your simulation model as you normally would. You can model an initial hypothesis, or you can leave all simulated objects at rest. In this example, we are evaluating the pre-braking speed of a red vehicle (see below) based on a known braking distance. The driver applied the brakes after striking a pedestrian. Of course, this trivial “slide-to-stop” analysis can be performed manually by using the real-time feedback in Virtual CRASH and quickly scanning across v(t=0) in the Dynamics menu, or by using the V0 fast-control icon. For this first example illustrating the Smart Optimizer, we will allow it to automatically iterate over a user-specified range of possible pre-braking speeds to see whether it can correctly converge on the known 50 mph initial speed.
Once your simulation scenario is set up with all necessary objects in place, you will need to insert “Position / Orientation Constraint” objects into your scene if your intention is to satisfy any position, orientation, or speed constraints. Left-click on Optimizer > Position / Orientation Constraint to activate constraint object mode.
Next, select your time-step of interest either by using the time slider or by left-clicking directly on an interposition for the unfrozen object to which you want to add constraint objects. In this example, we will hover over the red subject vehicle. The object will highlight in light blue to confirm it is ready for selection. Hold+left-click and drag away from the object to create a constraint object associated with that parent. You can add as many constraint objects as needed, scrubbing forward and backward in time while in constraint object creation mode. Constraint objects can also be cloned in “use copy” mode. Note that it is not necessary to use the time slider when placing constraint objects, but you may find it convenient, because if your parent object is in motion, the constraint object will be placed near the region and orientation of interest corresponding to your selected time-step.
Right-click to exit constraint object adding mode. In this simple example, we are only using one constraint object, placed at the documented rest position of our vehicle.
In [F2] or [F3] mouse cursor control mode, you can adjust the constraint object’s position and orientation as needed. This can also be done in the position-local and rotation-local menus.
Next, open the “misc” menu to set the various tolerances for the constraint object. In this case, we will set “radius” to 0.5 ft, “delta yaw” to 2 degrees, “min v” to 0 mph, and “max v” to 0.5 mph. The Smart Optimizer will attempt to find the user-enabled simulation inputs that produce outputs falling within these tolerance ranges. How these input values are used, and how valid outputs are identified, is described in more detail below.
Next, to access the optimizer tool, left-click Optimizer > Show Optimizer from the menu bar. You can also open the Smart Optimizer by clicking the Smart Optimizer button on the upper toolbar, or by pressing the graph button on the lower toolbar.
Once the graph window opens, adjust its size as needed so you can clearly read the left-side panel. Make sure “optimizer” is highlighted in the upper-left corner of the graph window rather than “controllers” or “diagrams”.
Next, locate the rigid body objects of interest in the list on the left-side of the graph window. In our example, we want the Smart Optimizer to solve for the initial speed that allows the vehicle to traverse the known braking distance. Therefore, we will activate Vehicle 1 > dynamics > v (t=0s) by left-clicking on the empty box to the right of its name. Once clicked, a check mark appears, confirming that this parameter is now active. Notice that the hierarchy mirrors the standard menu structure found in the left-side control panel for all rigid body objects. Note, the known braking distance is implied by the initial position of the vehicle and the rest position indicated by the inserted constraint object (with target speed range < 0.5 mph).
After a parameter is enabled, you can set its lower limit (“min value”) and upper limit (“max value”) in the “parameter settings” menu under Properties. These values define the range the Smart Optimizer is permitted to use when selecting input values for the enabled parameter. If possible, try to set a reasonable but narrow min/max range to speed up the optimization process. Reasonable ranges can often be estimated from hand calculations, data from literature, experience, preliminary simulation analyses, etc.
To re-access the parameter menu later, simply left-click directly on the parameter’s name in the hierarchy.
In this simple use case, we will have the Smart Optimizer test initial speeds from 0 to 100 mph and an initial yaw angle within ±5 degrees, in case the initial yaw angle is suboptimal given the known rest position. For any enabled optimization parameter, the “relative” toggle can be enabled. When enabled, the “value” input field will be automatically populated with the corresponding value from the parent object’s input field, which can be considered a best or reasonable estimate. A search window can then be defined above and below this estimate using the “delta value” input field.
In our example, the red vehicle was set up in the 3D workspace with rotation-local yaw = −32.864 degrees based on the lane configuration in the 3D environment, and therefore this is the reasonable first estimate. When rotation-local is enabled in the optimizer window, this initial yaw value is automatically populated in the “value” input field. Note that at the time of the initial release, the “value” field will not update automatically if the user changes the initial state of the parent object after “relative” is enabled.
Finally, open the “optimizer” menu under “properties”. In this menu, you will see both the inputs and outputs associated with the Smart Optimizer. By default, the genetic algorithm is selected. This algorithm evaluates many possible combinations of user-enabled input parameters and retains the candidates whose simulated outcomes most closely satisfy the constraints, typically those implied by forensic evidence. It then creates new candidate solutions by mixing and slightly modifying those high-performing results, allowing the search to steadily converge toward input values that best reproduce the observed physical evidence. The default parameter set described below works well in many cases, but these settings can be modified depending on the specific use case.
Genetic Algorithm
The genetic algorithm inputs are as follows:
Size of Population: The number of candidate simulations (iterations) maintained in each generation. Larger populations provide greater initial diversity across the input data space but increase computational cost per generation.
Max. Number of Generations: The absolute stopping criterion: the maximum number of generations the Smart Optimizer will run before terminating if “exit after max. generations” is enabled; otherwise, optimizer will reset with new random seed and continue running.
Transfer Ratio: The fraction of simulations that is preserved unchanged between generations. These are the best performing simulations (best “fitness”) that survive directly into the next generation without modification to input data.
Mutate Probability: The probability that an child-simulation will have random variations added to all its input data after it's created. When triggered, mutation perturbs every parameter simultaneously.
Crossover Probability: The probability that an child-simulation is created by blending two parents parent-simulations versus being a direct copy of one parent-simulation. If crossover triggers: child-simulation input parameters are sampled uniformly between the two parent values. If crossover doesn't trigger: child-simulation inputs are an exact copy of one parent (before mutation).
Once you have set the parameters in the optimizer menu, verify that physics is not paused (the gears icon should not be highlighted). Then left-click the play button in the graph window to activate the Smart Optimizer.
As the Smart Optimizer runs, you will see a real-time visualization of the current trial in the 3D environment. By default, only a subset of trials will be displayed within the 3D environment. Pressing the play button at the bottom of the screen (next to the teapot icon) will display all iterations as the optimizer runs.
You will also see real-time results on the left side of the graph window in the “optimizer” section. For each iteration performed by the solver, the total deviation is computed as the quadratic mean of the individual deviation terms enabled by the user.
$$\text{minimize: } f_i(\alpha_{1,i}, \alpha_{2,i}, ..., \alpha_{M,i}) = \frac{1}{\sqrt{N}} \sqrt{\sum_{j=1}^{N} w_j \cdot \left(\frac{\tilde{p}_{j,i} - p_{j,\text{target}}}{p_{j,\text{norm}}}\right)^2} $$
where:
\(M\) = number of enabled input parameters specified within min/max range
\(N\) = number of constraints
\(\alpha\) = automatically varied input parameter
\(i\) = optimization "trial simulation" index
\(j\) = optimization parameter constraint index
\(w_j\) = weight for constraint parameter \(j\)
\(\tilde{p}_{j,i}\) = parameter \(j\) OUTPUT value for trial simulation \(i\)
\(p_{j,\text{target}}\) = parameter \(j\) TARGET constraint value (for example, \(\Delta\text{yaw} = 0°\))
\(p_{j,\text{norm}}\) = normalization factor to unitless terms which can be summed
The individual deviation terms are described below.
For each position / orientation constraint object created for a given parent, Virtual CRASH evaluates all time-steps for each optimization iteration. It identifies the time-step that yields the minimum distance to the constraint object. This process is repeated for all constraint objects in the scene. Virtual CRASH then computes the individual deviation terms for each enabled parameter for each constraint object. These are listed below:
Position Deviation: For a given constraint object, the position deviation is computed using the x-y projected displacement vector between the constraint object and the parent object's position at the nearest time-step within the current optimization iteration. This deviation displacement vector is then normalized by the magnitude of the x-y projected displacement from the parent object’s initial position to the constraint object. The magnitude of the normalized deviation vector is then squared and multiplied by the “position weight” input value (default 100%). If the user-defined “radius” tolerance is greater than zero, the deviation displacement magnitude is first reduced by the radius. If this difference is less than or equal to zero (i.e., the deviation lies within the tolerance circle), the position deviation for that constraint object is set to 0 for the optimization iteration.
Orientation Deviation: For a given constraint object, the yaw orientation deviation is computed using the absolute difference in yaw (|delta yaw|) between the constraint object and the parent object at the nearest time-step. This value is normalized by 180 degrees. The normalized deviation is squared and multiplied by the “orientation weight” input value (default 100%). Note, at the time of the initial release, yaw angles are bounded between -180 to +180 degrees. If the user-defined “delta yaw” tolerance is greater than zero, the computed |delta yaw| is reduced by this tolerance. If this difference is less than zero (i.e., within tolerance), the orientation deviation for that constraint object is set to 0 for the optimization iteration. Note: The orientation deviation term can be disabled by unchecking the “use orientation” toggle.
Speed Deviation: For a given constraint object, the speed deviation is computed using the nearest time-step speed of the parent object. If this speed is less than or equal to the user-defined “min v”, the deviation is taken relative to min v. If the speed is greater than or equal to the user-defined “max v”, the deviation is taken relative to max v. This speed difference is then normalized by 100 kph, squared, and multiplied by the “velocity weight” input value (default 100%). If the nearest time-step speed lies between min v and max v (inclusive), the speed deviation for that constraint object is set to 0 for the optimization iteration. Note: The velocity deviation term can be disabled by unchecking the “use velocity” toggle.
There are also constraints available through Auto-EES and EES objects. These will be discussed further below.
All individual deviation terms are then averaged, and the square root of this average is returned and displayed in the “iteration deviation” output field in the “optimizer” menu. The minimum deviation over all iterations in the current population is shown in the “deviation” output field.
As the optimizer runs, you will see a graph on the right that displays the iteration deviation as a function of iteration within the population. These values are represented by blue vertical bars (dark blue if from the prior generation and light blue if from the current generation). If an iteration deviation is less than 5%, its bar will appear light orange. Population members whose iteration deviation falls below the user-defined “max. deviation” exit condition will be shown in green. The lowest deviation for all iterations within the current generation will be shown in the upper right corner.
Once at least one iteration returns a deviation below the user-specified maximum deviation, the optimizer will complete the remaining iterations for the current generation and then terminate. If no such iteration is found, the optimizer will continue running until it reaches the maximum number of generations or until the pause or stop buttons are pressed.
Once the optimizer has finished, you can left-click on any enabled parameter in the left-side hierarchy to view its output distribution for the final generation. The parameter values will be graphed as a function of iteration, sorted from least to greatest deviation.
In the results shown below, we improved our solution by requiring the maximum deviation to be no greater than 0.01% before terminating the optimization process. Doing so, of course, increases the total run-time of the Smart Optimizer. Again, any iterations remaining in the final generation with deviation less than or equal to 0.01% will be shown in green. In our case, only 1 iteration out of 40 in the final generation had its deviation less than 0.01%, and therefore the optimizer stopped.
You can hover over the vertical bar graphics in the graph to refresh the ghosted visualizations that show the nearest simulated positions to each constraint object for the iteration corresponding to the bar under the mouse cursor. This provides a quick understanding of the variation in position and orientation among the iterations in the final generation. You can also left-click any vertical bar in the graph to load the corresponding simulation input values and update the 3D workspace to display that specific scenario.
By left-clicking on any disabled parameter name in the hierarchy, the right-side graph will switch to display the iteration error for the final generation. As before, you can hover over the graph bars to view the ghosted vehicle representations relative to the constraint objects, or you can left-click on a bar to load its corresponding input data directly into the simulation.
The workflow in the slide-to-stop example above is reviewed in the video below.
Assessing Simulation Sensitivity
We will now expand the range of adhesion values for our vehicle in order to explore the effect of drag factor uncertainty. To illustrate the concept, we will suppose our adhesion value is in the range from 0.7 to 0.8 and examine how this broader range widens the initial speed range for our solution. We are using a deliberately wide uncertainty window here to make the idea clear. For this study, we have disabled optimization of the initial yaw and instead hold it fixed at the best value obtained from the prior run.
For this task, we will use differential evolution.
Differential evolution is another evolutionary algorithm that often outperforms a genetic algorithm on continuous, numerical problems because its mutation step uses the difference between existing solutions to guide the search more efficiently. While a genetic algorithm typically relies on random perturbations that resemble taking random steps in the search space, differential evolution uses vector-based operations to produce a more informed and directed step. Both approaches then use crossover to blend information from the newly generated candidate with the current best solution, followed by a selection process that retains the superior option for the next generation. Use the algorithm drop down to select “differential evolution”.
You’ll find new input parameters, defined below:
Differential Weight: The scaling factor that controls how strongly the difference between two randomly selected candidate simulations influences the creation of a new candidate. Higher differential weight values produce larger steps across the input space, which increases exploration and helps the optimizer search widely. Lower values produce smaller, more conservative steps that focus on refining promising regions of the search space.
Crossover Probability: The probability that each input value in the new candidate simulation will be taken from the mutated vector rather than from the existing parent simulation. High crossover probabilities promote stronger mixing of candidate solutions and encourage the optimizer to move decisively toward new variations created through mutation. Lower probabilities preserve more of the original parent values, which can stabilize the search but may limit the rate of improvement.
Differential evolution can provide better performance than a genetic algorithm for our constrained, continuous search across the two-dimensional parameter space in this example. It can potentially explore a complex, continuous solution space more efficiently and more consistently.
Our strategy in this example is to lower the “max. deviation limit” input value so that the Smart Optimizer is required to run through many generations before it can meet the constraint. We will then simply observe the optimizer’s progress and stop the process manually once all candidates in a given generation fall below 1% deviation.
For our optimizer constraint object, we set both the min v and max v to 0, and we set the radius to 0. Tight constraints, in addition to the minimum possible “max. deviation limit” practically ensure no stopping condition will be satisfied, and so we can run the optimizer until all iterations within a generation are filled with deviation less than 1%. Below we see the final distribution of deviation values after a few minutes of running.
Next, we examine the distribution of adhesion values across the population to verify that the full range of possible values is represented. As expected, the distribution spans the complete range.
Finally, we determine the minimum and maximum initial speeds that satisfy the slide-to-stop distance requirement implied by our constraint object and the vehicle’s initial position (107.1 ft stopping distance). The resulting range of 47–51 mph matches the interval predicted by hand calculations for a vehicle braking from 50 mph on a flat, level surface.
This illustrates how the Smart Optimizer can be used to evaluate a simulation’s sensitivity to its input parameters and to identify feasible parameter ranges under multi-dimensional constraints. Although we focused on adhesion-driven variation in initial speed in this simple scenario, the same methodology extends naturally to a broad set of input parameters for far more complex simulations.
Collision Analysis
The Smart Optimizer can be a big time saver for collision analysis since the input parameter space tends to span numerous dimensions, which are prohibitive to scan via manual multi-dimensional grid searching. Below we show a collision analysis setup based on RICSAC Test 3. The vehicles' initial positions are at the moment of contact. Constraint objects are set for each vehicle at their documented rest positions. An intermediate constraint object is used for Vehicle 2 since its post-impact trajectory follows an arcing path. Note, intermediate constraint objects should have "use velocity" disabled without specific data to suggest a likely range at the given location. In this study, our objective is to find the pre-impact speed for Vehicle 1 that results in simulated outcomes consistent with our vehicle position and orientation constraints.
Here, the optimizer is enabled. The minimum parameter set for this analysis is selected, with reasonable initial minimum and maximum values set for each parameter. In order to scan across potential effect points of contact, a user contact EES object was created with contact > "auto-position" disabled. Once auto-position is disabled, the user contact EES object position can be added to the optimization parameter list. Since the position-local y value of the EES object is of particular importance in this case to generate post-impact yaw rate needed to redirect Vehicle 1, only position-local y was added to the parameter list. Restitution can be particularly important, and therefore the user contact's restitution value was also included. Induced steer is added to Vehicle 2. Thus we are searching for a deviation function global minimum within a 4-dimensional volume. In this case, we'll use the default settings for the genetic algorithm, but use a strict exit condition of "max. deviation" = 0.2%.
When optimizing over many parameters, you may find it useful to adjust min/max values as it becomes clear what the narrower range should be. Be careful not to bias your results in doing so since there may be unique and non-intuitive combinations of input parameters that satisfy your constraints. Here, it quickly becomes clear that the possible range for Vehicle 2's induced steering angle must be quite low for it to follow the arcing trajectory indicated by the evidence. By shrinking the volume of the search space, you can more quickly arrive at an optimal solution.
After a few minutes, we exit out of the optimizer with the best pre-impact speed estimate of 20.5 mph (within 1 mph of the true value).
A video of this optimization is shown below (playback sped up).
Impulse-based constraints
It is also possible to add optimization parameters based on impulse exchanges. Below, we see the user contact impulse has under "Object 1" and "Object 2" options to include deviation terms based on EES, delta-v (impulse / mass), v pre-impact, v post-impact, deformation, and impulse PDOF (local, SAE). Any parameter shown highlighted in red can be added as an optimization constraint. In our example, we'll remove the rest position constraint of Vehicle 1 and see if instead the optimizer can obtain a best estimate of pre-impact speed if we include a delta-v constraint. Here we'll use 8.9 mph. After re-running the optimization, the optimal speed value is again found to be 20.5 mph.
Pedestrian Impact Analysis
Constraint objects can also be added for multibodies. Simply left-click on Optimizer > Position/Orientation Constraint, then left-click on your unfrozen multibody in your scene and position the constraint object as needed. In the example shown below, we use two constraint objects. One for an intermediate position near ground contact and the second for the rest position. Of course, for the intermediate position, the "use velocity" toggle should be disabled. Using two such constraint objects can help ensure the multibody travels from impact to rest along a straight vector, reducing trajectories that scatter laterally and then tumble back to the rest constraint object. Note, since the initial implementation of the Smart Optimizer tool only uses projected x-y displacement vectors, the height of the multibody constraint object is not included in the deviation function. Additionally, the pose of the optimizer object only indicates the initial pose of the multibody. The rest pose of your simulated multibody is in no way used by the Smart Optimizer.
In our example here, the final solution from the Smart Optimizer is consistent with our expectations from Searle.
A video of this optimization is shown below (playback sped up).
Bicycle/Motorcycle Accident Analysis
In the example below, we attempt to solve for the bullet SUV pre-impact speed that leads to the rest positions of the bicycle, rider, and SUV. Note, as of the initial release, only the yaw angle of the constraint objects is configurable. Therefore, only the yaw angle of the bicycle will be added to the deviation objective function if "use orientation" is enabled.
Below we see the final optimized solution.
A video of this optimization is shown below (playback sped up).
In the example below, we have a motorcycle T-bone crash based on WREX 2000 CT8. A constraint object was set at the rest position and orientation of each vehicle. Here, a user contact was created in order to iterate over impulse centroid locations.
Here the Smart Optimizer stops on a result within a few percent the true motorcycle pre-impact speed.
A video of this optimization is shown below (playback sped up).
Trajectory and Sequence Analysis
The Smart Optimizer can also be used for programming sequences. In the example below, we use three optimizer objects to guide our simulated vehicle around the right turn. The final two optimizer objects help to ensure the vehicle's final trajectory is straight and follows the lane. Our simulated vehicle is programmed with the minimum number of sequences required to complete the desired action (always a good practice).
The time values for sequences 2 and 3 and the target steering angle were solved for by the Smart Optimizer.
A video of this optimization is shown below (playback sped up).
Tractor-Trailer Reversing
In the example below, the Smart Optimizer is used to synchronize the sensitive interplay between steering and timing so as to reverse the tractor-trailer into a warehouse loading bay. Here, three sequences are the minimum number to execute this action. The Smart Optimizer also solves for sequence 3's pedal position to bring the system to rest at the proper location. Note, two constraint objects are used, only for the trailer, so as to attempt to back in a straight line to the loading bay.
Here we see the final optimizer solution.
A video of this optimization is shown below (playback sped up).
© 2025 Virtual CRASH, LLC. All Rights Reserved