turtlebot:adventures:sensing101_forwarderror
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
turtlebot:adventures:sensing101_forwarderror [2015/10/06 23:26] – pvela | turtlebot:adventures:sensing101_forwarderror [2024/08/20 21:38] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 41: | Line 41: | ||
If your goal here is to go to a static Turtlebot pose, then you should have some kind of stop-control condition that checks to see if the two errors are too small to bother fixing. | If your goal here is to go to a static Turtlebot pose, then you should have some kind of stop-control condition that checks to see if the two errors are too small to bother fixing. | ||
+ | |||
+ | ==== Generating the Desired End Pose ==== | ||
+ | |||
+ | Alright, the above is all fine and good, but the bigger question is: how do I create the desired pose signal to begin with? It actually works in the opposite way as computing the error. | ||
+ | \begin{equation} | ||
+ | \Delta g = g_{curr}^{-1} g_{des}. | ||
+ | \end{equation} | ||
+ | Now, let's rearrange it to solve for $g_{des}$, | ||
+ | \begin{equation} | ||
+ | g_{des} = g_{curr} \Delta g. | ||
+ | \end{equation} | ||
+ | Ha! This final equation is exactly what you want to do. Take the current position, as measured prior to actually performing any feedback, and left-multiply by the desired movement of the Turtlebot. | ||
+ | \begin{equation} | ||
+ | \Delta g_{forward} = \left[ \begin{matrix} 1 & \Delta x + 0j \\ 0 & 1 \end{matrix} \right] | ||
+ | \quad \text{and} \quad | ||
+ | \Delta g_{turn} = \left[ \begin{matrix} e^{j \Delta \theta} & 0 \\ 0 & 1 \end{matrix} \right], | ||
+ | \end{equation} | ||
+ | where $\Delta x$ is the distance to drive forward and $\Delta \theta$ is the angle (in radians most likely) to turn. In future instantiations, | ||
+ | |||
+ | This desired end pose will then be fixed until the proper terminating condition is achieved (e.g., the error is small enough to be negligible). | ||
+ | ==== Complex Matrices in Python ==== | ||
+ | |||
+ | OK, so you are thinking " | ||
+ | < | ||
+ | > import numpy | ||
+ | > import cmath | ||
+ | </ | ||
+ | After that you will be happy because then complex matrices will be supported. Let's build the simplest such matrix, which is the identity matrix of $SE(2)$. | ||
+ | < | ||
+ | > r = cmath.rect(1, | ||
+ | > t = complex(0, | ||
+ | > g = numpy.mat([[r, | ||
+ | > g | ||
+ | </ | ||
+ | If I am not mistaken, you should now have the identity matrix! | ||
+ | < | ||
+ | > r = cmath.rect(1, | ||
+ | > t = complex(5, | ||
+ | > g = numpy.mat([[r, | ||
+ | > g | ||
+ | </ | ||
+ | I recommend using '' | ||
+ | Taking the inverse you should see that the top left part of the matrix gets conjugated: | ||
+ | < | ||
+ | > gInverse = numpy.linalg.inv(g) | ||
+ | > gInverse | ||
+ | </ | ||
+ | If you can get the above working, then that's pretty much all you will need. Matrix multiplication should work how you think it does: | ||
+ | < | ||
+ | > gErr = gCurrInv * gDes | ||
+ | </ | ||
+ | or maybe even | ||
+ | < | ||
+ | > gErr = numpy.linalg.inv(gCurr) * gDes | ||
+ | </ | ||
+ | There is actually a computationally faster way of doing it that exploits the fact that $r$ is a rotation, but that's for another day, or maybe even for you to explore on your own. | ||
--------- | --------- | ||
;#; | ;#; | ||
[[Turtlebot: | [[Turtlebot: | ||
;#; | ;#; |
turtlebot/adventures/sensing101_forwarderror.1444188418.txt.gz · Last modified: 2024/08/20 21:38 (external edit)