.. _world-flow-control: World XML files flow control -------------------------------------------- MVSim's XML world files support programming-like flow control structures to enable dynamic world generation, reduce code repetition, and create parametric scenarios. For loops ============ The ```` tag allows you to repeat XML blocks with an iteration variable, similar to for-loops in programming languages. Basic syntax ^^^^^^^^^^^^^^^ .. code-block:: xml - **var**: Name of the iteration variable (can be dereferenced with ``${variable_name}``) - **from**: Starting value (inclusive, integer) - **to**: Ending value (inclusive, integer) The loop body is executed for each value from ``from`` to ``to``, and the variable can be used in any XML attribute or content within the loop. Simple example ^^^^^^^^^^^^^^^ Create a row of blocks: .. code-block:: xml ${i} 0 0 This creates 10 blocks named ``box_0`` through ``box_9`` positioned at x-coordinates 0 through 9. Using expressions with loop variables ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Loop variables can be used in mathematical expressions with the ``$f{...}`` notation: .. code-block:: xml $f{i*2.5} $f{sin(i*0.3)*5} 0 $f{0.8 + i*0.02} This creates 20 lamp posts with: - Spacing of 2.5 meters along X-axis - Sinusoidal Y-position variation - Gradually increasing scale from 0.8 to 1.2 Nested loops ^^^^^^^^^^^^^^^ Loops can be nested to create 2D patterns: .. code-block:: xml $f{col*2} $f{row*2} 0 #FF0000FF This creates a 5×5 grid of colored cubes. Advanced loop examples ^^^^^^^^^^^^^^^^^^^^^^^^^ Creating a circular arrangement: .. code-block:: xml $f{RADIUS*cos(i*2*M_PI/NUM_ITEMS)} $f{RADIUS*sin(i*2*M_PI/NUM_ITEMS)} $f{i*30} Creating a parametric path: .. code-block:: xml $f{5*sin(t*0.1)} $f{5*cos(t*0.15)} 0 Conditional parsing ======================= The ```` tag allows conditional inclusion of XML content based on a boolean condition. Basic syntax ^^^^^^^^^^^^^^^ .. code-block:: xml The **condition** attribute is evaluated as a boolean expression. The content inside the ```` tag is only parsed and included if the condition evaluates to true. Simple conditionals ^^^^^^^^^^^^^^^^^^^^^ Using variables: .. code-block:: xml 0 0 0 Using mathematical expressions: .. code-block:: xml 5 5 0 Combining with loops ^^^^^^^^^^^^^^^^^^^^^^^ Conditionals can be used inside loops for selective generation: .. code-block:: xml ${i} 0 0 Creating conditional patterns: .. code-block:: xml ${x} ${y} 0 #FFFFFF ${x} ${y} 0 #000000 Environment-based conditionals ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use environment variables for configuration: .. code-block:: xml 0 0 0 0 0 0 Then run with: .. code-block:: bash SIM_MODE=true mvsim myworld.world.xml Combining flow control features ================================= Complex world generation ^^^^^^^^^^^^^^^^^^^^^^^^^^ Combine loops, conditionals, and variables for sophisticated scenarios: .. code-block:: xml $f{x*2} $f{y*2} 0 #$f{int(rand()*255):02X}$f{int(rand()*255):02X}$f{int(rand()*255):02X} $f{ROOM_SIZE} 0 0 0 0 0 0 $f{ROOM_SIZE} 0 0 0 0 Parametric vehicle placement ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: xml $f{i*3} 0 0 $f{5*cos(i*2*M_PI/NUM_ROBOTS)} $f{5*sin(i*2*M_PI/NUM_ROBOTS)} $f{i*360/NUM_ROBOTS} Best practices ================ Performance considerations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1. **Minimize deep nesting**: Excessive nested loops can slow world parsing 2. **Use conditionals to skip unnecessary objects**: Filter early to avoid creating objects that won't be used 3. **Cache computed values**: Store repeated calculations in variables .. code-block:: xml $f{i*SPACING} 0 0 Code organization ^^^^^^^^^^^^^^^^^^ 1. **Use descriptive variable names**: ``NUM_OBSTACLES`` instead of ``N`` 2. **Group related configurations**: Keep variables together at the top 3. **Comment complex logic**: Explain non-obvious conditions or expressions 4. **Extract to included files**: Move reusable patterns to separate files .. code-block:: xml Debugging ^^^^^^^^^^ Enable verbose parsing to see variable evaluations: .. code-block:: bash MVSIM_VERBOSE_PARSE=1 mvsim myworld.world.xml This will print each variable substitution and expression evaluation, helping you debug complex flow control logic. Expression syntax reference ============================ Within ``$f{...}`` expressions, you can use: Mathematical operators ^^^^^^^^^^^^^^^^^^^^^^^^ - Arithmetic: ``+``, ``-``, ``*``, ``/``, ``%``, ``^`` (power) - Comparison: ``<``, ``>``, ``<=``, ``>=``, ``==``, ``!=`` - Logical: ``and``, ``or``, ``not`` - Bitwise: ``&``, ``|``, ``~``, ``<<``, ``>>`` Functions ^^^^^^^^^^ - **Trigonometric**: ``sin``, ``cos``, ``tan``, ``asin``, ``acos``, ``atan``, ``atan2`` - **Math**: ``sqrt``, ``abs``, ``exp``, ``log``, ``log10``, ``pow``, ``ceil``, ``floor``, ``round`` - **Random**: ``rand()`` (0 to 1), ``randn()`` (normal distribution) - **String**: ``strcmp(s1, s2)`` (returns 0 if equal) - **Conversion**: ``int(x)`` (convert to integer) Constants ^^^^^^^^^^^ - ``M_PI``: π (3.14159...) - ``M_E``: e (2.71828...) See the `ExprTk documentation `_ for the complete expression language reference. Complete example ================== Here's a complete world demonstrating advanced flow control: .. code-block:: xml ${zone_x} 0 0 #00FF00 true $f{zone_x + i*2} $f{i*2} 0 $f{zone_x + 10 + 8*cos(i*2*M_PI/10)} $f{10 + 8*sin(i*2*M_PI/10)} 0 $f{zone_x + rand()*WORLD_SIZE} $f{rand()*WORLD_SIZE} $f{rand()*360} This example creates three distinct zones, each with a different obstacle pattern, and includes debug markers that can be toggled on/off.