/ErrorProp

Error propagation library.

Primary LanguageHaskellGNU General Public License v2.0GPL-2.0

ErrorProp
=========

TODO: writeme 

Error propagation library.

Installation

    $ git clone git://github.com/hepek/ErrorProp.git
    $ cd ErrorProp
    $ cabal install


Example 1: Two Link Planar Arm
----------------------------


Let's simulate a non-linear transformation by combining translations 
and rotations of a robotic arm and evaluating error propagation at different
operation points.

![Illustration](images/two-link-planar-arm.png "Figure 1.")

Figure 1. A two link planar robotic arm


> import Math.ErrorProp
> import Math.SimpleMx
>

Coordinates

> x = defVar "x"
> y = defVar "y"

Model parameters

> a1 = defVar"a1"
> a2 = defVar"a2"
> l1 = defVar"l1"
> l2 = defVar"l2"

Couple of helper functions for defining rotations and translations

> rotGen var = fromLists
>   [[cos(var), -sin(var), 0]
>   ,[sin(var),  cos(var), 0]
>   ,[0,         0,        1]]
> 
> transGen x y = fromLists
>  [[1, 0, x]
>  ,[0, 1, y]
>  ,[0, 0, 1]]
> 

Our two link planar arm can now be modeled as superposition of two rotations and two translations:

> arm1 = (rotGen a1) >< (transGen l1 0) >< (rotGen a2) >< (transGen l2 0)

To obtain our non-linear transformation we multiply arm1 with [x, y, 1] (homogenous coordinates).

> armT1 = mkTransf $ toList (arm1 >. fromList [x, y, 1])

We can view our set of resulting functions:

> r1 = print armT1

     o1 = (((x * ((cos(a2) * cos(a1)) + (sin(a2) * -sin(a1)))) + (y * ((-sin(a2) * cos(a1)) + (cos(a2) * -sin(a1))))) + ((l2 * ((cos(a2) * cos(a1)) + (sin(a2) * -sin(a1)))) + (l1 * cos(a1))))
     o2 = (((x * ((cos(a2) * sin(a1)) + (sin(a2) * cos(a1)))) + (y * ((-sin(a2) * sin(a1)) + (cos(a2) * cos(a1))))) + ((l2 * ((cos(a2) * sin(a1)) + (sin(a2) * cos(a1)))) + (l1 * sin(a1))))
     o3 = 1.0

We could easily eliminate x and y from the equations as we know the initial coordinates (0,0).
This can be done in two ways:

1. Reevaluate our matrix-vector multiplication from above:

> armT2 = mkTransf $ toList (arm1 >. fromList [0,0,1])

2. Or use our partialEval utility function

> armT2' = (partial armT1 [(x,0), (y,0)])
> r2 = print armT2

    o1 = ((l2 * ((cos(a2) * cos(a1)) + (sin(a2) * -sin(a1)))) + (l1 * cos(a1)))
    o2 = ((l2 * ((cos(a2) * sin(a1)) + (sin(a2) * cos(a1)))) + (l1 * sin(a1)))
    o3 = 1.0


And  the order of input parameters would be:

> r3 = print (variables armT1)

    [a1,a2,l1,l2,x,y]

> r4 = print (variables armT2)

    [a1,a2,l1,l2]


> degrad a = a/180*pi
> r5 = print $ apply armT2 $ 
>       measurement [ degrad 45 +- 0
>                   , degrad 0  +- 0
>                   , 10 +- 0
>                   , 5 +- 0]

    measurement [
      10.606601717798213 +- 0.0,
      10.606601717798211 +- 0.0,
      1.0 +- 0.0]

> r6 =  apply armT1 $ 
>        measurement [ degrad 45 +- degrad 1
>                    , degrad 0  +- degrad 1
>                    , 10 +- 0.01
>                    , 5  +- 0.01
>                    , 0  +- 0
>                    , 0  +- 0] 

    measurement [
      10.606601717798213 +- 0.1953898090314297,
      10.606601717798211 +- 0.1953898090314297,
      1.0 +- 0.0]

> r6' = getCovariance r6

    [4.241908608148729e-3,-4.219686385926508e-3,0.0]
    [-4.219686385926507e-3,4.24190860814873e-3,0.0]
    [0.0,0.0,0.0]


> r7 = print $ apply armT1 $ 
>       measurement [ degrad 0 +- degrad 1
>                   , degrad 0 +- degrad 1
>                   , 10 +- 0.01
>                   , 5  +- 0.01
>                   , 0  +- 0
>                   , 0  +- 0]

    measurement [
      15.0 +- 1.4142135623730952e-2,
      0.0 +- 0.27596078516100275,
      1.0 +- 0.0]