From 3ac9fc6e633ff76aa8ecf47671b8e63d53deca1c Mon Sep 17 00:00:00 2001
From: Kevin O'Connor <kevin@koconnor.net>
Date: Tue, 19 Jun 2018 00:50:59 -0400
Subject: [PATCH] docs: Update documentation with iterative solver changes

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
---
 docs/Code_Overview.md          | 134 ++++++----------
 docs/Kinematics.md             | 104 ++++++-------
 docs/img/delta-tower.svg       | 273 ---------------------------------
 docs/img/delta-tower.svg.png   | Bin 8371 -> 0 bytes
 docs/img/virtual-tower.svg     | 241 -----------------------------
 docs/img/virtual-tower.svg.png | Bin 5865 -> 0 bytes
 docs/img/xy+z-tower.svg        | 241 -----------------------------
 docs/img/xy+z-tower.svg.png    | Bin 6653 -> 0 bytes
 8 files changed, 101 insertions(+), 892 deletions(-)
 delete mode 100644 docs/img/delta-tower.svg
 delete mode 100644 docs/img/delta-tower.svg.png
 delete mode 100644 docs/img/virtual-tower.svg
 delete mode 100644 docs/img/virtual-tower.svg.png
 delete mode 100644 docs/img/xy+z-tower.svg
 delete mode 100644 docs/img/xy+z-tower.svg.png

diff --git a/docs/Code_Overview.md b/docs/Code_Overview.md
index 7a0df7ca9..c038f49d0 100644
--- a/docs/Code_Overview.md
+++ b/docs/Code_Overview.md
@@ -163,28 +163,37 @@ provides further information on the mechanics of moves.
   kinematic class is given a chance to audit the move
   (`ToolHead.move() -> kin.check_move()`) before it goes on the
   look-ahead queue, but once the move arrives in *kin*.move() the
-  kinematic class is required to handle the move as specified. The
-  kinematic classes translate the three parts of each move
-  (acceleration, constant "cruising" velocity, and deceleration) to
-  the associated movement on each stepper. Note that the extruder is
-  handled in its own kinematic class. Since the Move() class specifies
-  the exact movement time and since step pulses are sent to the
-  micro-controller with specific timing, stepper movements produced by
-  the extruder class will be in sync with head movement even though
-  the code is kept separate.
+  kinematic class is required to handle the move as specified. Note
+  that the extruder is handled in its own kinematic class. Since the
+  Move() class specifies the exact movement time and since step pulses
+  are sent to the micro-controller with specific timing, stepper
+  movements produced by the extruder class will be in sync with head
+  movement even though the code is kept separate.
 
-* For efficiency reasons, the stepper pulse times are generated in C
-  code. The code flow is: `kin.move() -> MCU_Stepper.step_const() ->
-  stepcompress_push_const()`, or for delta kinematics:
-  `DeltaKinematics.move() -> MCU_Stepper.step_delta() ->
-  stepcompress_push_delta()`. The MCU_Stepper code just performs unit
-  and axis transformation (millimeters to step distances), and calls
-  the C code. The C code calculates the stepper step times for each
-  movement and fills an array (struct stepcompress.queue) with the
-  corresponding micro-controller clock counter times for every
-  step. Here the "micro-controller clock counter" value directly
-  corresponds to the micro-controller's hardware counter - it is
-  relative to when the micro-controller was last powered up.
+* Klipper uses an
+  [iterative solver](https://en.wikipedia.org/wiki/Root-finding_algorithm)
+  to generate the step times for each stepper. For efficiency reasons,
+  the stepper pulse times are generated in C code. The code flow is:
+  `kin.move() -> MCU_Stepper.step_itersolve() ->
+  itersolve_gen_steps()` (in klippy/chelper/itersolve.c). The goal of
+  the iterative solver is to find step times given a formula that
+  calculates a stepper position from a given time in a move. This is
+  done by repeatedly "guessing" various times until the stepper
+  position formula returns the desired position of the next step on
+  the stepper. The feedback produced from each guess is used to
+  improve future guesses so that the process rapidly converges to the
+  desired time. The kinematic stepper position formulas are located in
+  the klippy/chelper/ directory (eg, kin_cart.c, kin_corexy.c,
+  kin_delta.c, kin_extruder.c).
+
+* After the iterative solver calculates the step times they are added
+  to an array: `itersolve_gen_steps() -> queue_append()` (in
+  klippy/chelper/stepcompress.c). The array (struct
+  stepcompress.queue) stores the corresponding micro-controller clock
+  counter times for every step. Here the "micro-controller clock
+  counter" value directly corresponds to the micro-controller's
+  hardware counter - it is relative to when the micro-controller was
+  last powered up.
 
 * The next major step is to compress the steps: `stepcompress_flush()
   -> compress_bisect_add()` (in klippy/chelper/stepcompress.c). This
@@ -293,8 +302,7 @@ This section provides some tips on adding support to Klipper for
 additional types of printer kinematics. This type of activity requires
 excellent understanding of the math formulas for the target
 kinematics. It also requires software development skills - though one
-should only need to update the host software (which is written in
-Python).
+should only need to update the host software.
 
 Useful steps:
 1. Start by studying the
@@ -304,74 +312,30 @@ Useful steps:
    and delta.py. The kinematic classes are tasked with converting a
    move in cartesian coordinates to the movement on each stepper. One
    should be able to copy one of these files as a starting point.
-3. Implement the `get_postion()` method in the new kinematics
-   class. This method converts the current stepper position of each
-   stepper axis (stored in millimeters) to a position in cartesian
-   space (also in millimeters).
-4. Implement the `set_postion()` method. This is the inverse of
-   get_position() - it sets each axis position (in millimeters) given
-   a position in cartesian coordinates.
-5. Implement the `move()` method. The goal of the move() method is to
-   convert a move defined in cartesian space to a series of stepper
-   step times that implement the requested movement.
-   * The `move()` method is passed a "print_time" parameter (which
-     stores a time in seconds) and a "move" class instance that fully
-     defines the movement. The goal is to repeatedly invoke the
-     `stepper.step()` method with the time (relative to print_time)
-     that each stepper should step at to obtain the desired motion.
-   * One "trick" to help with the movement calculations is to imagine
-     there is a physical rail between `move.start_pos` and
-     `move.end_pos` that confines the print head so that it can only
-     move along this straight line of motion. Then, if the head is
-     confined to that imaginary rail, the head is at `move.start_pos`,
-     only one stepper is enabled (all other steppers can move freely),
-     and the given stepper is stepped a single step, then one can
-     imagine that the head will move along the line of movement some
-     distance. Determine the formula converting this step distance to
-     distance along the line of movement. Once one has the distance
-     along the line of movement, one can figure out the time that the
-     head should be at that position (using the standard formulas for
-     velocity and acceleration). This time is the ideal step time for
-     the given stepper and it can be passed to the `stepper.step()`
-     method.
-   * The `stepper.step()` method must always be called with an
-     increasing time for a given stepper (steps must be scheduled in
-     the order they are to be executed). A common error during
-     kinematic development is to receive an "Internal error in
-     stepcompress" failure - this is generally due to the step()
-     method being invoked with a time earlier than the last scheduled
-     step. For example, if the last step in move1 is scheduled at a
-     time greater than the first step in move2 it will generally
-     result in the above error.
-   * Fractional steps. Be aware that a move request is given in
-     cartesian space and it is not confined to discreet
-     locations. Thus a move's start and end locations may translate to
-     a location on a stepper axis that is between two steps (a
-     fractional step). The code must handle this. The preferred
-     approach is to schedule the next step at the time a move would
-     position the stepper axis at least half way towards the next
-     possible step location. Incorrect handling of fractional steps is
-     a common cause of "Internal error in stepcompress" failures.
-6. Other methods. The `home()`, `check_move()`, and other methods
+3. Implement the C stepper kinematic position functions for each
+   stepper if they are not already available (see kin_cart.c,
+   kin_corexy.c, and kin_delta.c in klippy/chelper/). The function
+   should call `move_get_coord()` to convert a given move time (in
+   seconds) to a cartesian coordinate (in millimeters), and then
+   calculate the desired stepper position (in millimeters) from that
+   cartesian coordinate.
+4. Implement the `set_position()` method in the python code. This also
+   calculates the desired stepper positions given a cartesian
+   coordinate.
+5. Implement the `get_position()` method in the new kinematics
+   class. This method is the inverse of set_position(). It does not
+   need to be efficient as it is typically only called during homing
+   and probing operations.
+6. Implement the `move()` method. This method generally invokes the
+   iterative solver for each stepper.
+7. Other methods. The `home()`, `check_move()`, and other methods
    should also be implemented. However, at the start of development
    one can use empty code here.
-7. Implement test cases. Create a g-code file with a series of moves
+8. Implement test cases. Create a g-code file with a series of moves
    that can test important cases for the given kinematics. Follow the
    [debugging documentation](Debugging.md) to convert this g-code file
    to micro-controller commands. This is useful to exercise corner
    cases and to check for regressions.
-8. Optimize if needed. One may notice that the existing kinematic
-   classes do not call `stepper.step()`. This is purely an
-   optimization - the inner loop of the kinematic calculations were
-   moved to C to reduce load on the host cpu. All of the existing
-   kinematic classes started development using `stepper.step()` and
-   then were later optimized. The g-code to mcu command translation
-   (described in the previous step) is a useful tool during
-   optimization - if a code change is purely an optimization then it
-   should not impact the resulting text representation of the mcu
-   commands (though minor changes in output due to floating point
-   rounding are possible). So, one can use this system to detect
-   regressions.
 
 Time
 ====
diff --git a/docs/Kinematics.md b/docs/Kinematics.md
index eb0cb94c3..7e61b3d2a 100644
--- a/docs/Kinematics.md
+++ b/docs/Kinematics.md
@@ -139,15 +139,32 @@ tracked in millimeters, seconds, and in cartesian coordinate space.
 It's the task of the kinematic classes to convert from this generic
 coordinate system to the hardware specifics of the particular printer.
 
-In general, the code determines each step time by first calculating
-where along the line of movement the head would be if a step is
-taken. It then calculates what time the head should be at that
-position. Determining the time along the line of movement can be done
-using the formulas for constant acceleration and constant velocity:
+Klipper uses an
+[iterative solver](https://en.wikipedia.org/wiki/Root-finding_algorithm)
+to generate the step times for each stepper. The code contains the
+formulas to calculate the ideal cartesian coordinates of the head at
+each moment in time, and it has the kinematic formulas to calculate
+the ideal stepper positions based on those cartesian coordinates. With
+these formulas, Klipper can determine the ideal time that the stepper
+should be at each step position. The given steps are then scheduled at
+these calculated times.
 
+The key formula to determine how far a move should travel under
+constant acceleration is:
 ```
-time = sqrt(2*distance/accel + (start_velocity/accel)^2) - start_velocity/accel
-time = distance/cruise_velocity
+move_distance = (start_velocity + .5 * accel * move_time) * move_time
+```
+and the key formula for movement with constant velocity is:
+```
+move_distance = cruise_velocity * move_time
+```
+
+The key formulas for determining the cartesian coordinate of a move
+given a move distance is:
+```
+cartesian_x_position = start_x + move_distance * total_x_movement / total_movement
+cartesian_y_position = start_y + move_distance * total_y_movement / total_movement
+cartesian_z_position = start_z + move_distance * total_z_movement / total_movement
 ```
 
 Cartesian Robots
@@ -157,54 +174,35 @@ Generating steps for cartesian printers is the simplest case. The
 movement on each axis is directly related to the movement in cartesian
 space.
 
+Key formulas:
+```
+stepper_x_position = cartesian_x_position
+stepper_y_position = cartesian_y_position
+stepper_z_position = cartesian_z_position
+```
+
+CoreXY Robots
+----------------
+
+Generating steps on a CoreXY machine is only a little more complex
+than basic cartesian robots. The key formulas are:
+```
+stepper_a_position = cartesian_x_position + cartesian_y_position
+stepper_b_position = cartesian_x_position - cartesian_y_position
+stepper_z_position = cartesian_z_position
+```
+
 Delta Robots
 ------------
 
-To generate step times on Delta printers it is necessary to correlate
-the movement in cartesian space with the movement on each stepper
-tower.
-
-To simplify the math, for each stepper tower, the code calculates the
-location of a "virtual tower" that is along the line of movement.
-This virtual tower is chosen at the point where the line of movement
-(extended infinitely in both directions) would be closest to the
-actual tower.
-
-![delta-tower](img/delta-tower.svg.png)
-
-It is then possible to calculate where the head will be along the line
-of movement after each step is taken on the virtual tower.
-
-![virtual-tower](img/virtual-tower.svg.png)
-
-The key formula is Pythagoras's theorem:
+Step generation on a delta robot is based on Pythagoras's theorem:
 ```
-distance_to_tower^2 = arm_length^2 - tower_height^2
+stepper_position = (sqrt(arm_length^2
+                         - (cartesian_x_position - tower_x_position)^2
+                         - (cartesian_y_position - tower_y_position)^2)
+                    + cartesian_z_position)
 ```
 
-One complexity is that if the print head passes the virtual tower
-location then the stepper direction must be reversed. In this case
-forward steps will be taken at the start of the move and reverse steps
-will be taken at the end of the move.
-
-### Delta movements beyond simple XY plane ###
-
-Movement calculation is more complicated if a single move contains
-both XY movement and Z movement. These moves are rare, but they must
-still be handled correctly. A virtual tower along the line of movement
-is still calculated, but in this case the tower is not at a 90 degree
-angle relative to the line of movement:
-
-![xy+z-tower](img/xy+z-tower.svg.png)
-
-The code continues to calculate step times using the same general
-scheme as delta moves within an XY plane, but the slope of the tower
-must also be used in the calculations.
-
-Should the move contain only Z movement (ie, no XY movement at all)
-then the same math is used - just in this case the tower is parallel
-to the line of movement.
-
 ### Stepper motor acceleration limits ###
 
 With delta kinematics it is possible for a move that is accelerating
@@ -236,8 +234,10 @@ independently from the step time calculations of the print head
 movement.
 
 Basic extruder movement is simple to calculate. The step time
-generation uses the same constant acceleration and constant velocity
-formulas that cartesian robots use.
+generation uses the same formulas that cartesian robots use:
+```
+stepper_position = requested_e_position
+```
 
 ### Pressure advance ###
 
@@ -264,7 +264,7 @@ through the nozzle orifice (as in
 key idea is that the relationship between filament, pressure, and flow
 rate can be modeled using a linear coefficient:
 ```
-extra_filament = pressure_advance_coefficient * extruder_velocity
+stepper_position = requested_e_position + pressure_advance_coefficient * nominal_extruder_velocity
 ```
 
 See the [pressure advance](Pressure_Advance.md) document for
diff --git a/docs/img/delta-tower.svg b/docs/img/delta-tower.svg
deleted file mode 100644
index 98dc0951a..000000000
--- a/docs/img/delta-tower.svg
+++ /dev/null
@@ -1,273 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="97.22496mm"
-   height="32.550285mm"
-   viewBox="0 0 344.49789 115.33566"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="delta-tower.svg">
-  <defs
-     id="defs4">
-    <marker
-       inkscape:isstock="true"
-       style="overflow:visible"
-       id="marker6618"
-       refX="0"
-       refY="0"
-       orient="auto"
-       inkscape:stockid="Arrow1Mend">
-      <path
-         transform="matrix(-0.4,0,0,-0.4,-4,0)"
-         style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         id="path6620"
-         inkscape:connector-curvature="0" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="marker6500"
-       style="overflow:visible;"
-       inkscape:isstock="true">
-      <path
-         id="path6502"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1;fill:#4b4b4b;fill-opacity:1"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-    <marker
-       inkscape:isstock="true"
-       style="overflow:visible;"
-       id="marker6082"
-       refX="0.0"
-       refY="0.0"
-       orient="auto"
-       inkscape:stockid="Arrow1Mend"
-       inkscape:collect="always">
-      <path
-         transform="scale(0.4) rotate(180) translate(10,0)"
-         style="fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1;fill:#4b4b4b;fill-opacity:1"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         id="path6084" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mend"
-       style="overflow:visible;"
-       inkscape:isstock="true"
-       inkscape:collect="always">
-      <path
-         id="path5747"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1;fill:#4b4b4b;fill-opacity:1"
-         transform="scale(0.4) rotate(180) translate(10,0)" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mstart"
-       orient="auto"
-       refY="0.0"
-       refX="0.0"
-       id="Arrow1Mstart"
-       style="overflow:visible"
-       inkscape:isstock="true">
-      <path
-         id="path5744"
-         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
-         style="fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1;fill:#4b4b4b;fill-opacity:1"
-         transform="scale(0.4) translate(10,0)" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0"
-       refX="0"
-       id="Arrow1Mend-1"
-       style="overflow:visible"
-       inkscape:isstock="true"
-       inkscape:collect="always">
-      <path
-         inkscape:connector-curvature="0"
-         id="path4329-1"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
-         transform="matrix(-0.4,0,0,-0.4,-4,0)" />
-    </marker>
-    <marker
-       inkscape:isstock="true"
-       style="overflow:visible"
-       id="marker6082-9"
-       refX="0"
-       refY="0"
-       orient="auto"
-       inkscape:stockid="Arrow1Mend"
-       inkscape:collect="always">
-      <path
-         inkscape:connector-curvature="0"
-         transform="matrix(-0.4,0,0,-0.4,-4,0)"
-         style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         id="path6084-2" />
-    </marker>
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.75"
-     inkscape:cx="172.24895"
-     inkscape:cy="45.708959"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     inkscape:window-width="928"
-     inkscape:window-height="628"
-     inkscape:window-x="162"
-     inkscape:window-y="50"
-     inkscape:window-maximized="0"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     showborder="false"
-     inkscape:snap-global="false"
-     showguides="false">
-    <inkscape:grid
-       type="xygrid"
-       id="grid3436" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(-135.22429,-249.96955)">
-    <ellipse
-       style="fill:#4d4d4d;stroke:#4b4b4b;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:2, 1, 0.5, 1;stroke-dashoffset:0;stroke-opacity:1"
-       id="path4255"
-       cx="353.79568"
-       cy="327.87662"
-       rx="4.2857141"
-       ry="4.8571429" />
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
-       d="M 181.50998,381.87664 359.22427,275.01949"
-       id="path5510"
-       inkscape:connector-curvature="0" />
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="371.22427"
-       y="354.44806"
-       id="text6058"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan6060"
-         x="371.22427"
-         y="354.44806">stepper</tspan><tspan
-         sodipodi:role="line"
-         x="371.22427"
-         y="366.94806"
-         id="tspan9337">tower</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="166.65283"
-       y="304.16235"
-       id="text6062"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan6064"
-         x="166.65283"
-         y="304.16235">line of movement</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-weight:normal;font-size:10.0000006px;line-height:125%;font-family:'DejaVu Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;-inkscape-font-specification:'DejaVu Sans, Normal';font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr;"
-       x="252.93855"
-       y="384.16235"
-       id="text6066"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan6068"
-         x="252.93855"
-         y="384.16235">move</tspan></text>
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#marker6618)"
-       d="m 382.65284,344.73378 c -0.19273,-13.52091 -9.87887,-14.83602 -20.57143,-14.85715"
-       id="path6070"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker6500)"
-       d="m 254.65284,374.44806 c 3.39239,-12.86009 -2.06023,-20.09154 -15.42857,-22.28571"
-       id="path6072"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker6082)"
-       d="m 257.50997,296.16234 c 31.05376,-3.13332 32.38959,-1.23784 42.28572,10.28572"
-       id="path6074"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
-       d="m 219.61431,358.80126 57.78715,-34.48307"
-       id="path3514-5"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:0.50000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
-       d="m 351.22427,323.59092 -20.57143,-32"
-       id="path3358"
-       inkscape:connector-curvature="0" />
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="244.36713"
-       y="257.30521"
-       id="text4460"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan4462"
-         x="244.36713"
-         y="257.30521">virtual tower</tspan><tspan
-         sodipodi:role="line"
-         x="244.36713"
-         y="269.80521"
-         id="tspan5867">location</tspan></text>
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker6082-9)"
-       d="m 310.90661,257.14111 c 21.29088,8.40268 18.35244,16.28958 20.57143,29.7143"
-       id="path6074-6"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-  </g>
-</svg>
diff --git a/docs/img/delta-tower.svg.png b/docs/img/delta-tower.svg.png
deleted file mode 100644
index 9ab53ea16db4becbbda609b131105e07062a60fb..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 8371
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

diff --git a/docs/img/virtual-tower.svg b/docs/img/virtual-tower.svg
deleted file mode 100644
index 9ba254d51..000000000
--- a/docs/img/virtual-tower.svg
+++ /dev/null
@@ -1,241 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="64.619751mm"
-   height="27.45583mm"
-   viewBox="0 0 228.96762 97.284438"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="virtual-tower.svg">
-  <defs
-     id="defs4">
-    <marker
-       inkscape:isstock="true"
-       style="overflow:visible"
-       id="marker6618"
-       refX="0"
-       refY="0"
-       orient="auto"
-       inkscape:stockid="Arrow1Mend">
-      <path
-         transform="matrix(-0.4,0,0,-0.4,-4,0)"
-         style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         id="path6620"
-         inkscape:connector-curvature="0" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0"
-       refX="0"
-       id="marker6500"
-       style="overflow:visible"
-       inkscape:isstock="true">
-      <path
-         id="path6502"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
-         transform="matrix(-0.4,0,0,-0.4,-4,0)"
-         inkscape:connector-curvature="0" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0"
-       refX="0"
-       id="Arrow1Mend"
-       style="overflow:visible"
-       inkscape:isstock="true"
-       inkscape:collect="always">
-      <path
-         id="path5747"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
-         transform="matrix(-0.4,0,0,-0.4,-4,0)"
-         inkscape:connector-curvature="0" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mstart"
-       orient="auto"
-       refY="0"
-       refX="0"
-       id="Arrow1Mstart"
-       style="overflow:visible"
-       inkscape:isstock="true">
-      <path
-         id="path5744"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
-         transform="matrix(0.4,0,0,0.4,4,0)"
-         inkscape:connector-curvature="0" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0"
-       refX="0"
-       id="Arrow1Mend-1"
-       style="overflow:visible"
-       inkscape:isstock="true"
-       inkscape:collect="always">
-      <path
-         inkscape:connector-curvature="0"
-         id="path4329-1"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
-         transform="matrix(-0.4,0,0,-0.4,-4,0)" />
-    </marker>
-    <marker
-       inkscape:isstock="true"
-       style="overflow:visible"
-       id="marker6082"
-       refX="0"
-       refY="0"
-       orient="auto"
-       inkscape:stockid="Arrow1Mend"
-       inkscape:collect="always">
-      <path
-         inkscape:connector-curvature="0"
-         transform="matrix(-0.4,0,0,-0.4,-4,0)"
-         style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         id="path6084" />
-    </marker>
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.75"
-     inkscape:cx="169.7719"
-     inkscape:cy="-4.0565054"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     inkscape:window-width="922"
-     inkscape:window-height="628"
-     inkscape:window-x="162"
-     inkscape:window-y="50"
-     inkscape:window-maximized="0"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     showborder="false"
-     inkscape:snap-global="false"
-     showguides="false">
-    <inkscape:grid
-       type="xygrid"
-       id="grid3436"
-       originx="-14.085234"
-       originy="-95.286988" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(-149.30952,-172.73378)">
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
-       d="m 176.36712,256.16235 200.00001,-0.57143"
-       id="path5510"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="-254.01012"
-       y="369.20834"
-       id="text6058"
-       sodipodi:linespacing="125%"
-       transform="matrix(-0.01833576,-0.99983189,0.99983189,-0.01833576,0,0)"
-       inkscape:transform-center-x="-8.0000002"
-       inkscape:transform-center-y="12.571429"><tspan
-         sodipodi:role="line"
-         id="tspan10365"
-         x="-254.01012"
-         y="369.20834">virtual tower</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="148.36713"
-       y="269.87662"
-       id="text6062"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan6064"
-         x="148.36713"
-         y="269.87662">line of movement</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="237.50998"
-       y="251.01949"
-       id="text6066"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan6068"
-         x="237.50998"
-         y="251.01949">move</tspan></text>
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:7.00000048;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       d="m 358.08141,255.01949 0,-82.28571"
-       id="path10351"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       d="M 220.36713,255.01949 357.50998,173.30521"
-       id="path10373"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="200.36713"
-       y="187.59093"
-       id="text10375"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan10377"
-         x="200.36713"
-         y="187.59093">virtual arm</tspan></text>
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker6082)"
-       d="m 261.76375,182.85539 c 22.73118,-0.70136 26.45506,3.7437 40.00001,18.28573"
-       id="path6074"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
-       d="m 219.61431,255.37268 70.93001,0.37408"
-       id="path3514-5"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-  </g>
-</svg>
diff --git a/docs/img/virtual-tower.svg.png b/docs/img/virtual-tower.svg.png
deleted file mode 100644
index 7856192c73a049f6b5f854a3c6989ad8dddcfb5c..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5865
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
b{(?1;xQC7<7OB9sG{{ibOs7uU@yY)HFa`$d

diff --git a/docs/img/xy+z-tower.svg b/docs/img/xy+z-tower.svg
deleted file mode 100644
index b1f3101f7..000000000
--- a/docs/img/xy+z-tower.svg
+++ /dev/null
@@ -1,241 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="64.619751mm"
-   height="27.45583mm"
-   viewBox="0 0 228.96762 97.284438"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="xy+z-tower.svg">
-  <defs
-     id="defs4">
-    <marker
-       inkscape:isstock="true"
-       style="overflow:visible"
-       id="marker6618"
-       refX="0"
-       refY="0"
-       orient="auto"
-       inkscape:stockid="Arrow1Mend">
-      <path
-         transform="matrix(-0.4,0,0,-0.4,-4,0)"
-         style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         id="path6620"
-         inkscape:connector-curvature="0" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0"
-       refX="0"
-       id="marker6500"
-       style="overflow:visible"
-       inkscape:isstock="true">
-      <path
-         id="path6502"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
-         transform="matrix(-0.4,0,0,-0.4,-4,0)"
-         inkscape:connector-curvature="0" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0"
-       refX="0"
-       id="Arrow1Mend"
-       style="overflow:visible"
-       inkscape:isstock="true"
-       inkscape:collect="always">
-      <path
-         id="path5747"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
-         transform="matrix(-0.4,0,0,-0.4,-4,0)"
-         inkscape:connector-curvature="0" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mstart"
-       orient="auto"
-       refY="0"
-       refX="0"
-       id="Arrow1Mstart"
-       style="overflow:visible"
-       inkscape:isstock="true">
-      <path
-         id="path5744"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
-         transform="matrix(0.4,0,0,0.4,4,0)"
-         inkscape:connector-curvature="0" />
-    </marker>
-    <marker
-       inkscape:stockid="Arrow1Mend"
-       orient="auto"
-       refY="0"
-       refX="0"
-       id="Arrow1Mend-1"
-       style="overflow:visible"
-       inkscape:isstock="true"
-       inkscape:collect="always">
-      <path
-         inkscape:connector-curvature="0"
-         id="path4329-1"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
-         transform="matrix(-0.4,0,0,-0.4,-4,0)" />
-    </marker>
-    <marker
-       inkscape:isstock="true"
-       style="overflow:visible"
-       id="marker6082"
-       refX="0"
-       refY="0"
-       orient="auto"
-       inkscape:stockid="Arrow1Mend"
-       inkscape:collect="always">
-      <path
-         inkscape:connector-curvature="0"
-         transform="matrix(-0.4,0,0,-0.4,-4,0)"
-         style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
-         d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
-         id="path6084" />
-    </marker>
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.75"
-     inkscape:cx="169.7719"
-     inkscape:cy="-4.0565054"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     inkscape:window-width="922"
-     inkscape:window-height="628"
-     inkscape:window-x="162"
-     inkscape:window-y="50"
-     inkscape:window-maximized="0"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     showborder="false"
-     inkscape:snap-global="false"
-     showguides="false">
-    <inkscape:grid
-       type="xygrid"
-       id="grid3436"
-       originx="-14.085234"
-       originy="-95.286988" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(-149.30952,-172.73378)">
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
-       d="m 176.36712,256.16235 200.00001,-0.57143"
-       id="path5510"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="-119.27526"
-       y="434.37329"
-       id="text6058"
-       sodipodi:linespacing="125%"
-       transform="matrix(0.32454206,-0.94587127,0.94587127,0.32454206,0,0)"
-       inkscape:transform-center-x="-3.9400734"
-       inkscape:transform-center-y="14.789029"><tspan
-         sodipodi:role="line"
-         id="tspan10365"
-         x="-119.27526"
-         y="434.37329">virtual tower</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="148.36713"
-       y="269.87662"
-       id="text6062"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan6064"
-         x="148.36713"
-         y="269.87662">line of movement</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="237.50998"
-       y="251.01949"
-       id="text6066"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan6068"
-         x="237.50998"
-         y="251.01949">move</tspan></text>
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:7.00000048;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       d="m 354.70239,255.76769 28.12779,-77.32895"
-       id="path10351"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       d="M 220.36713,255.01949 380.93855,178.44807"
-       id="path10373"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
-       x="200.36713"
-       y="187.59093"
-       id="text10375"
-       sodipodi:linespacing="125%"><tspan
-         sodipodi:role="line"
-         id="tspan10377"
-         x="200.36713"
-         y="187.59093">virtual arm</tspan></text>
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker6082)"
-       d="m 261.76375,182.85539 c 22.73118,-0.70136 26.45506,3.7437 40.00001,18.28573"
-       id="path6074"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-    <path
-       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
-       d="m 219.61431,255.37268 70.93001,0.37408"
-       id="path3514-5"
-       inkscape:connector-curvature="0"
-       sodipodi:nodetypes="cc" />
-  </g>
-</svg>
diff --git a/docs/img/xy+z-tower.svg.png b/docs/img/xy+z-tower.svg.png
deleted file mode 100644
index 96c5480884f07766ce26bf73f68f26b46d10b6d9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 6653
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
Nn>Q?>b=TdW{tw0B5>@~J