Rijesh AugustineA blog where I detail some of the fun projects I am working on.
http://rijesha.com/
Thu, 18 Apr 2019 20:59:37 +0000Thu, 18 Apr 2019 20:59:37 +0000Jekyll v3.7.4A Peafowl Analysis: Kung Fu Panda 2<p>Have you ever seen a children’s animated tale and thought, “Hmmm, did the artists draw the correct kind of peafowl?”
Well if you haven’t get ready for one of the wildest rides of your life.</p>
<h2 id="peafowl-vs-peacock-vs-peahen">Peafowl vs Peacock vs Peahen</h2>
<p>Let’s start by getting a few semantics out of the way. Peacock is the name given to the male of the peafowl species. Peahen is the female of a species. Lots of other species have similar naming conventions. An example is cattle. The male is called a bull and the female is called a cow.
Any animal of the class Aves (birds) uses the designation cock and hen.</p>
<h2 id="green-vs-blue-peafowl">Green vs Blue Peafowl</h2>
<p>There are a few distinct species of peafowl, the most common being the Indian peafowl (aka Pavo cristatus, aka Blue peafowl) and the green peafowl (aka Pavo muticus, aka Java peafowl). In the wild, the Indian peafowl can only be found in India and the green peafowl can primarily be found in Indonesia. The range of the green peafowl used to be a lot larger, but hunting and habitat destruction have caused the species to lose a lot of their range. In the past, the green peafowl’s range included China.</p>
<h2 id="shen-from-kung-fu-panda">Shen From Kung Fu Panda</h2>
<p><img src="/images/peafowl/kfp (6).jpg" alt="Insert Picture of Shen" />
In Kung Fu Panda 2 the primary antagonist is a white and red peacock named Shen. The movie itself takes place in China so the expectation is that he is a green peafowl. Is this actually the case? Let’s have a look at Shen and his characteristics. His white colouration is very uncommon for a peafowl, especially in nature. Ok, this is a bad start. Instead, let’s look at his crest. Here is a prime example of a green peafowl’s crest.</p>
<p><img src="/images/peafowl/green_peafowl.jpg" alt="green peafowl Crest" /></p>
<p><em>photograph by Haplochromis, distributed under a CC-BY 3.0 license.</em></p>
<p>The crest is very pointy. And now here is an Indian peafowl’s:
<img src="/images/peafowl/peahen.jpg" alt="Blue peafowl Crest" /></p>
<p>So in Shen, we see his crest has a more fan-like structure and that corresponds with an Indian peafowl’s. From the above two pictures note the colour of the head/neck of the green and Indian peafowl. This doesn’t help us because Shen is either an albino (red/pink eyes) or leucistic (he has some pigment in his tail feathers) peafowl. Next piece of evidence from the film is flight. Indian peafowl are relatively poor at flying. They can fly short distances, mostly to avoid predators but primarily they walk to get to where they want to go.</p>
<p><img src="/images/peafowl/kfp (7).png" alt="Shen in flight" /></p>
<p>Shen has an somewhat extended flight sequence. The long flight is more of a green peafowl characteristic. That being said it is mostly a glide, which the Indian peafowl can do just as well. So looking at Shen alone may prove to be somewhat inconclusive. We do briefly see his parents in an opening scene and they can provide us with a bit more information.</p>
<h2 id="shens-parents">Shen’s Parents</h2>
<p><img src="/images/peafowl/kfp (4).jpg" alt="Shens parents" />
First off his father (the one with blue feathers) is indeed blue. His crest is fan-like and he has a very long train (the long tail feathers). His train is partly hidden by the ground but you can clearly see that his mother has no train. In both species, the male has a longer train than the female (another inconclusive fact). In addition, you can see that his mom is quite a bit smaller than the male.
<img src="/images/peafowl/peacock.jpg" alt="Peacock Train" />
Green peahens and green peacocks look very similar (apart from the train). It is actually difficult to tell the male and female green peafowl apart when the male has no train. There colourations are very similar. The Indian peafowl species experiences a lot more sexual dimorphism. The mother looks a lot different than the male and is very easy to tell apart. You can see that the mother’s crest is almost non-existent as well. Here is an example of an Indian peacock with a very similar crest.
<img src="/images/peafowl/bg4.jpg" alt="peacock Lacking Crest" /></p>
<h2 id="so-conclusions">So Conclusions</h2>
<p>Pro Indian peafowl Facts:</p>
<ul>
<li>Crest is fanned out (as is father’s crest)</li>
<li>Father is blue</li>
<li>Mother’s colouration makes her very distinguishable from father</li>
</ul>
<h2 id="what-does-this-mean-for-the-story">What does this mean for the Story??</h2>
<p>Clearly, the story is portraying an Indian peafowl instead of a green peafowl.</p>
<ul>
<li>Option 1: The artists did not do their research.</li>
<li>Option 2: The artists did their research, but thought Indian peafowl would be more artistically pleasing.</li>
<li>Option 3: The story actually is some sort of metaphor for the very short-lived <a href="https://en.wikipedia.org/wiki/Sino-Indian_War">Sino-Indian War</a>.</li>
</ul>
<p>Which option is accurate, that’s up to you to decide.</p>
Sun, 04 Feb 2018 07:00:00 +0000
http://rijesha.com/2018/peafowl_kung_fu/
http://rijesha.com/2018/peafowl_kung_fu/peafowlpeahenpeacockBasics of Coding: Probabilistically Determining pi<h2 id="objectives">Objectives</h2>
<p>One of my favorite problems is calculating pi based on probability. This blog post will show you how to do that with python, c#, and ocaml. Basic knowledge of computer programming, in any one of those languages, will definitely be an asset. This post can also show you how to translate from a language that you know to a new one.</p>
<h2 id="pi">PI</h2>
<p>pi is an irrational constant that is the ratio of a circle’s circumference to its diameter</p>
<script type="math/tex; mode=display">Circumference = \pi \times d \tag{1}</script>
<p>It is also used to calculate a circle’s area.</p>
<script type="math/tex; mode=display">Area_{circ} = \pi \times r^2 \tag{2}</script>
<p>If we overlay a circle on a square as shown below we can compare the differences in the area of the two.</p>
<p><img src="/images/circle_compare.png" alt="Area Comparison" /></p>
<p>So if we were to randomly choose any location on the square what would be the probability that the location would also be inside the circle. The probability is just the ratio of areas.</p>
<script type="math/tex; mode=display">Area_{sqr} = d^2 = (2r)^2 = 4 \times r^2 \tag{3}</script>
<script type="math/tex; mode=display">Probability = \frac{Area_{circ}}{Area_{sqr}} = \frac{ \pi \times r^2}{4 \times r^2} \tag{4}</script>
<script type="math/tex; mode=display">Probability = \frac{\pi}{4} \tag{5}</script>
<p>So the chance that we hit the inside of the circle is <script type="math/tex">\frac{\pi}{4}</script>.</p>
<h2 id="making-it-computationally-easier">Making it computationally easier.</h2>
<p>Let’s just look at <script type="math/tex">\frac{1}{4}</script> of the drawing. This will make a bit more sense later on.</p>
<p><img src="/images/quarter_circle_compare.png" alt="Quarter Area Comparison" /></p>
<p>In this diagram, the radius of the circle is 1. The probability of being in the <script type="math/tex">\frac{1}{4}</script> circle when choosing a random position inside the smaller square is still the same probability as in eq 5. This is because we have divided the area of both by 4. This diagram also shows an x and y-axis with an origin at the centre of the original circle.</p>
<p>Ok. So if we can generate two random numbers between 0 and 1, we can use the first random number to represent an x coordinate and the second number to represent a y coordinate. We just need some equation to govern whether the randomly chosen x and y coordinate are inside the <script type="math/tex">\frac{1}{4}</script> circle.</p>
<p>We can use the Pythagorean theorem to help us. We know that the radius of the circle is always 1. So…</p>
<script type="math/tex; mode=display">% <![CDATA[
\sqrt{x^2 + y^2} < 1 \tag{6} %]]></script>
<h2 id="calculating-with-python">Calculating with Python</h2>
<p>Ok, let’s start with python.</p>
<p>We will be using a few premade python libraries. So the first step is to import these libraries in.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">import</span> <span class="nn">math</span>
<span class="kn">import</span> <span class="nn">random</span></code></pre></figure>
<p>this allows us to use math functions like square root and power as well as a function to generate random numbers. We can perform those operations like this.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">sqrt_2</span> <span class="o">=</span> <span class="n">math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="c"># return square root of 2 inside the variable sqrt_2</span>
<span class="n">nine</span> <span class="o">=</span> <span class="n">math</span><span class="o">.</span><span class="nb">pow</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span> <span class="c"># returns 9 inside the variable nine</span>
<span class="n">random_num</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">()</span> <span class="c"># returns a random number between 0 and 1 inside the variable random_num</span></code></pre></figure>
<p>It is a little tedious to keep writing the words math and random, so instead, we can import all functions of these two libraries and call the functions directly.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">from</span> <span class="nn">math</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="o">*</span></code></pre></figure>
<p>After importing the libraries we need to generate a variable to hold the total number of iterations we will perform and the number of times those iterations succeed in being inside the <script type="math/tex">\frac{1}{4}</script> circle.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="n">total_iterations</span> <span class="o">=</span> <span class="mi">1000000</span>
<span class="n">count_inside_quarter_circle</span> <span class="o">=</span> <span class="mi">0</span></code></pre></figure>
<p>Next, we can start looping through all of the iterations. The easiest way to make a for loop in python is using the range keyword. This block of code will run multiple times while changing the value of i from 0 to total_iterations.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">total_iterations</span><span class="p">):</span>
<span class="o">...</span></code></pre></figure>
<p>With Python, we have to be careful about our indentations and note that there is a colon after a function, loop, or if statement.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">total_iterations</span><span class="p">):</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">random</span><span class="p">()</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">random</span><span class="p">()</span>
<span class="k">if</span> <span class="n">sqrt</span><span class="p">(</span><span class="nb">pow</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nb">pow</span><span class="p">(</span><span class="n">y</span><span class="p">,</span><span class="mi">2</span><span class="p">))</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">count_inside_quarter_circle</span> <span class="o">=</span> <span class="n">count_inside_quarter_circle</span> <span class="o">+</span> <span class="mi">1</span></code></pre></figure>
<p>Finally, we can then print out our answer for pi.</p>
<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="k">print</span><span class="p">(</span><span class="mi">4</span> <span class="o">*</span> <span class="n">count_inside_quarter_circle</span> <span class="o">/</span> <span class="n">total_iterations</span><span class="p">)</span></code></pre></figure>
<p>You can test this online at https://repl.it/ or https://www.python.org/shell/.</p>
<p>The full file should look like this.</p>
<script src="https://gist.github.com/d74802badf35c47cb6651cddc05dade6.js?file=calculatingpi.py"> </script>
<h2 id="calculating-with-c">Calculating with C#</h2>
<p>Ok, so this starts off very similar to python. Start off with our imports. In c# we use the using keyword.</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="k">using</span> <span class="nn">System</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System.Math</span><span class="p">;</span></code></pre></figure>
<p>Next, we construct the main body of our program. We need to make a class and the main function. This is how the compiler knows where the program starts. You need to do something similar in python when you have larger projects, but python interprets everything at runtime line by line, so smaller projects are fine.</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="k">class</span> <span class="nc">MainClass</span> <span class="p">{</span>
<span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span> <span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//Program Code</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>In c# we need to define variables and the type of data associated with them. We will be using integer variables and doubles. Doubles are numbers that can hold decimal values.</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="kt">int</span> <span class="n">total_iterations</span> <span class="p">=</span> <span class="m">100000000</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">count_inside_quarter_circle</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span></code></pre></figure>
<p>We can generate random numbers using the Random class.</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="n">Random</span> <span class="n">r</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Random</span><span class="p">();</span> <span class="c1">//initialize a new object of the class random</span>
<span class="kt">double</span> <span class="n">x</span> <span class="p">=</span> <span class="n">r</span><span class="p">.</span><span class="nf">NextDouble</span><span class="p">();</span> <span class="c1">//return random number between 0 and 1 stored in variable x</span>
<span class="kt">double</span> <span class="n">y</span> <span class="p">=</span> <span class="n">r</span><span class="p">.</span><span class="nf">NextDouble</span><span class="p">();</span> <span class="c1">//return random number between 0 and 1 stored in variable y</span></code></pre></figure>
<p>With for-loops, we may pass three different operations. The first may be a variable initializer, the second is a condition that will stop the loop, and finally, we have an operation that will be done at the end of each loop. Any or all of these may be blank.</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="kt">int</span> <span class="n">k</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p"><</span> <span class="n">total_iterations</span><span class="p">;</span> <span class="n">i</span><span class="p">++){</span>
<span class="k">if</span> <span class="p">(</span><span class="n">LOGIC_STATEMENT</span><span class="p">)</span>
<span class="n">k</span><span class="p">++;</span> <span class="c1">//only do the very next line because there are no brackets</span>
<span class="k">if</span> <span class="p">(</span><span class="n">OTHER_LOGIC</span> <span class="n">STATEMENT</span><span class="p">){</span>
<span class="c1">//Do this line</span>
<span class="c1">//and this line</span>
<span class="n">k</span><span class="p">++;</span> <span class="c1">//increase the value of k by 1</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Our full loop will llok like this.</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="kt">var</span> <span class="n">r</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Random</span><span class="p">();</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p"><</span> <span class="n">total_iterations</span><span class="p">;</span> <span class="n">i</span><span class="p">++){</span>
<span class="kt">double</span> <span class="n">x</span> <span class="p">=</span> <span class="n">r</span><span class="p">.</span><span class="nf">NextDouble</span><span class="p">();</span>
<span class="kt">double</span> <span class="n">y</span> <span class="p">=</span> <span class="n">r</span><span class="p">.</span><span class="nf">NextDouble</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nf">Sqrt</span><span class="p">(</span><span class="nf">Pow</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="m">2</span><span class="p">)</span> <span class="p">+</span> <span class="nf">Pow</span><span class="p">(</span><span class="n">y</span><span class="p">,</span><span class="m">2</span><span class="p">))</span> <span class="p"><</span> <span class="m">1</span><span class="p">)</span>
<span class="n">count_inside_quarter_circle</span><span class="p">++;</span>
<span class="p">}</span></code></pre></figure>
<p>And finally, print out the answer. Note we are casting to a double. Otherwise, the arithmetic will return an integer value.</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">((</span><span class="kt">double</span><span class="p">)</span><span class="m">4</span> <span class="p">*</span> <span class="n">count_inside_quarter_circle</span> <span class="p">/</span> <span class="n">total_iterations</span><span class="p">);</span></code></pre></figure>
<p>You can test this online at https://repl.it/ or http://rextester.com/.</p>
<p>The full file should look like this. C, C++, C#, will all have very similar implementations as what is shown in the following file.</p>
<script src="https://gist.github.com/d74802badf35c47cb6651cddc05dade6.js?file=calculatingpi.cs"> </script>
<h2 id="calculating-with-ocaml">Calculating with Ocaml</h2>
<p>Ocaml is a functional programming language so it is quite different than the last two examples. There are no type declarations like in C# but the type is inferred based on context. Arithmetic operators must be specifically chosen for the type being used.</p>
<p>Basic function:</p>
<figure class="highlight"><pre><code class="language-ocaml" data-lang="ocaml"><span class="k">let</span> <span class="n">f</span> <span class="n">x</span> <span class="o">=</span> <span class="n">float_of_int</span> <span class="n">x</span> <span class="k">in</span></code></pre></figure>
<p>The name of this function is f and takes in one parameter x. The return of this function is the return of the function float_of_int x. Basically, you can think of this function as an alias. We don’t want to write float_of_int x everywhere. Instead, we would rather write f x. The in keyword is defining function f in the all of the code leading up to a ;;.</p>
<figure class="highlight"><pre><code class="language-ocaml" data-lang="ocaml"><span class="k">let</span> <span class="n">hyp</span> <span class="n">a</span> <span class="n">b</span> <span class="o">=</span> <span class="n">sqrt</span><span class="p">((</span><span class="n">a</span> <span class="o">*.</span> <span class="n">a</span> <span class="p">)</span> <span class="o">+.</span> <span class="p">(</span><span class="n">b</span> <span class="o">*.</span> <span class="n">b</span><span class="p">))</span> <span class="k">in</span></code></pre></figure>
<p>This function called hyp takes in two parameters a and b. You will notice that the expression on the right-hand side has *. and +. operators. These are operators used on floating point numbers. By using these the ocaml compiler knows that a and b must be floats and will issue an error if we try to pass in an integer.</p>
<figure class="highlight"><pre><code class="language-ocaml" data-lang="ocaml"><span class="k">let</span> <span class="n">randcheck</span> <span class="bp">()</span> <span class="o">=</span> <span class="n">hyp</span> <span class="p">(</span><span class="nn">Random</span><span class="p">.</span><span class="n">float</span> <span class="mi">1</span><span class="o">.</span><span class="mi">0</span><span class="p">)</span> <span class="p">(</span><span class="nn">Random</span><span class="p">.</span><span class="n">float</span> <span class="mi">1</span><span class="o">.</span><span class="mi">0</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="o">.</span><span class="mi">0</span> <span class="k">in</span></code></pre></figure>
<p>The randcheck function takes in an empty parameter. This makes sure that each time the function is called it will be reevaluated. This functions passes 2 random floats to the hypotenuse function and returns a logical true and false depending on if the hypotenuse is less than or greater than 1. Note that the Random.float function takes a float value as an argument. This argument limits the maximum return value and also note that it is 1.0 (a float) and not 1 (an int).</p>
<figure class="highlight"><pre><code class="language-ocaml" data-lang="ocaml"><span class="k">let</span> <span class="n">total_iterations</span> <span class="o">=</span> <span class="mi">1000000</span> <span class="k">in</span></code></pre></figure>
<p>This function is only evaluated once since no arguments are passed into it.</p>
<figure class="highlight"><pre><code class="language-ocaml" data-lang="ocaml"><span class="k">let</span> <span class="n">count_inside_quarter_circle</span> <span class="o">=</span> <span class="n">ref</span> <span class="mi">0</span> <span class="k">in</span></code></pre></figure>
<p>This function defines a reference to a variable. This way we can change the value of the variable. By default, it is set to 0.</p>
<p>Finally lets deal with the for loop.</p>
<figure class="highlight"><pre><code class="language-ocaml" data-lang="ocaml"><span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">to</span> <span class="n">total_iterations</span> <span class="k">do</span>
<span class="k">let</span> <span class="n">a</span> <span class="o">=</span> <span class="k">if</span> <span class="p">(</span><span class="n">randcheck</span> <span class="bp">()</span><span class="p">)</span> <span class="k">then</span> <span class="mi">1</span> <span class="k">else</span> <span class="mi">0</span> <span class="k">in</span>
<span class="n">count_inside_quarter_circle</span> <span class="o">:=</span> <span class="o">!</span><span class="n">count_inside_quarter_circle</span> <span class="o">+</span> <span class="n">a</span><span class="p">;</span>
<span class="k">done</span><span class="p">;</span></code></pre></figure>
<p>the ! and := operators are how we derefence the value inside count_inside_quarter_circle and how we then put a new value in.</p>
<p>Finally let’s print.</p>
<figure class="highlight"><pre><code class="language-ocaml" data-lang="ocaml"><span class="n">print_string</span> <span class="p">(</span><span class="n">string_of_float</span> <span class="p">(</span> <span class="mi">4</span><span class="o">.</span><span class="mi">0</span> <span class="o">*.</span> <span class="p">(</span> <span class="p">(</span><span class="n">f</span> <span class="o">!</span><span class="n">count_inside_quarter_circle</span><span class="p">)</span> <span class="o">/.</span> <span class="p">(</span><span class="n">f</span> <span class="n">total_iterations</span><span class="p">)</span> <span class="p">)));;</span></code></pre></figure>
<p>You can try this online at <a href="https://www.tutorialspoint.com/compile_ocaml_online.php">tutorialspoint.</a></p>
<p>The full file should look like this.</p>
<script src="https://gist.github.com/4ce0fc35c5907f0c422cb670ad78f2e0.js"> </script>
<h2 id="making-it-your-own">Making it your Own</h2>
<p>Your turn to make some changes. We have set the number of iterations as an endpoint for each loop. Instead try modifying the code to stop looping once a minimum accuracy has been reached.</p>
<script type="math/tex; mode=display">minimum\_error > \pi - \pi\_calcuated \tag{7}</script>
<h2 id="thats-all-folks">That’s All Folks</h2>
Fri, 19 Jan 2018 07:00:00 +0000
http://rijesha.com/2018/basics-of-coding-probabilistically-determining-pi/
http://rijesha.com/2018/basics-of-coding-probabilistically-determining-pi/picodingprobabilityc#ocamlpythonAerial Camera Ground Footprint with a gimbal<h2 id="questions">Questions</h2>
<ul>
<li>If I have a camera pointing straight down from a UAV what area on the ground will be captured in the image?</li>
<li>How does this change if the UAV experiences roll/pitch/yaw?</li>
<li>What happens if this camera is on a gimbal?</li>
</ul>
<p>Do you have these questions? Well, let’s see the answers.</p>
<h2 id="preliminary-information">Preliminary Information</h2>
<p>Before we get started it is important to cover a few basics. This tutorial will use the angle units of degrees, distance units of meters, and GPS coordinates in UTM. <a href="https://en.wikipedia.org/wiki/Trigonometry">Basic trigonometry</a> and knowledge of <a href="https://en.wikipedia.org/wiki/Rotation_(mathematics)">rotations</a> will be an asset.</p>
<p>It is important that when converting from UTM->WGS84 or WGS84->UTM that all of your units start in the same coordinate system. This tutorial will not cover how to convert between units, but it is important that all conversions follow the same math and are reversible. (Don’t obtain coordinates from different sources or formats because they may have used a slightly different conversion method than what you will.)</p>
<p>In this tutorial, we will be using Tait-Bryan angles. This is an angle naming convention so you can personally use whatever you like. The only changes in the math will be a negative sign here and there. <a href="https://en.wikipedia.org/wiki/Euler_angles">Angle Conventions</a></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Taitbrianzyx.svg/245px-Taitbrianzyx.svg.png" alt="Tait-Bryan Angle Convention. Courtesy Wikimedia" /></p>
<h2 id="basic-ground-footprint">Basic Ground Footprint</h2>
<p>The footprint of a camera pointing straight down is determined by some very basic trigonometry. A camera’s sensor and lens combination will produce a certain angle of view (AOV). You can look this up for your camera. AOV can be broken into a horizontal field of view (HFV), and a vertical field of view (VFV). <a href="https://en.wikipedia.org/wiki/Field_of_view">Check out this Wikipedia page for more info</a></p>
<p>So from our UAV, we can make a triangle with the ground, using AOV and altitude.
<img src="/images/simple_triangle.png" alt="The camera angle of view makes a triangle" /></p>
<p>If we cut this triangle, by drawing a straight line from the UAV to the ground, we can get 2 smaller triangles. Each of these smaller triangles is a right triangle so we can use trigonometric identities to solve for distance on the ground.</p>
<script type="math/tex; mode=display">ground\_in\_image = (\tan{\frac{AOV}{2}} \times altitude) \times 2 \tag{1}</script>
<script type="math/tex; mode=display">horizontal\_ground = (\tan{\frac{HFV}{2}} \times altitude) \times 2 \tag{2}</script>
<script type="math/tex; mode=display">vertical\_ground = (\tan{\frac{VFV}{2}} \times altitude) \times 2 \tag{3}</script>
<p>Now, this is great and all, but it does not take into account the utm location of the UAV nor does it take into account the yaw of the UAV. So let’s do that.</p>
<p>Let’s start by defining two new variables, that represent the distance of the ground from a point directly below the UAV. (in our case this will end up being exactly half of the ground.)</p>
<script type="math/tex; mode=display">dx = (\tan{\frac{HFV}{2}} \times altitude) \tag{4}</script>
<script type="math/tex; mode=display">dy = (\tan{\frac{VFV}{2}} \times altitude) \tag{5}</script>
<p>This dx and dy disregard any yaw, so we will need to convert them into x and y in the UTM system by incorporating yaw. (Also called psi in Tait_bryan)</p>
<script type="math/tex; mode=display">dutmx = dx \times \cos{\psi} - dy \times \sin{\psi} \tag{6}</script>
<script type="math/tex; mode=display">dutmy = -dx \times \sin{\psi} - dy \times \cos{\psi} \tag{7}</script>
<p>Great now we just need to add that to the current UTM coordinates of the UAV.</p>
<script type="math/tex; mode=display">utmx_1 = utmx + dutmx \tag{8}</script>
<script type="math/tex; mode=display">utmy_1 = utmy + dutmy \tag{9}</script>
<p>So this will provide the first corner of your ground footprint. To get additional corners change the values in equations 4,5. Use the remaining combinations of:</p>
<script type="math/tex; mode=display">(\frac{HFV}{2},-\frac{VFV}{2}),(-\frac{HFV}{2},\frac{VFV}{2}),(-\frac{HFV}{2},-\frac{VFV}{2})</script>
<h2 id="so-my-uav-is-pitching-and-rolling-about-now-what-do-i-do">So my UAV is pitching and rolling about, Now what do I do?</h2>
<p>Ok, I get you. This is actually really easy since we have no yet included a gimbal. All you need to do is modify equations 4,5 like this:</p>
<script type="math/tex; mode=display">dx = (\tan{(\frac{HFV}{2} + \phi)} \times altitude) \tag{10}</script>
<script type="math/tex; mode=display">dy = (\tan{(\frac{VFV}{2}+ \theta)} \times altitude) \tag{11}</script>
<h2 id="lets-include-a-gimbal">Let’s include a gimbal</h2>
<p>This is where things get complicated. Essentially we have two rotations and there is no simple fix like in 10 and 11. When I first attempted this problem, I tried to take the two rotations, combine them together, and then apply them to expanded versions of equations 10, and 11… but that proved to be a headache. I attempted . The problem is that when you combine the two rotations you are throwing away information on which direction of the image is up. What I learned was that I needed to look at each corner independently and then apply the rotations.</p>
<p>Ok so let’s do it. First, we need to represent each corner as a quaternion. (We will be using quaternions to perform the rotations). Also, I’ll be doing the following section in C#, but it should still be easy to follow along. The source code for the math is linked at the end of this section.</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="n">Quaternion</span> <span class="n">TR</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Quaternion</span><span class="p">(-</span><span class="n">hfv</span><span class="p">.</span><span class="n">Value</span> <span class="p">/</span> <span class="m">2</span><span class="p">,</span> <span class="n">vfv</span><span class="p">.</span><span class="n">Value</span> <span class="p">/</span> <span class="m">2</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span>
<span class="n">Quaternion</span> <span class="n">TL</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Quaternion</span><span class="p">(</span> <span class="n">hfv</span><span class="p">.</span><span class="n">Value</span> <span class="p">/</span> <span class="m">2</span><span class="p">,</span> <span class="n">vfv</span><span class="p">.</span><span class="n">Value</span> <span class="p">/</span> <span class="m">2</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span>
<span class="n">Quaternion</span> <span class="n">BR</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Quaternion</span><span class="p">(-</span><span class="n">hfv</span><span class="p">.</span><span class="n">Value</span> <span class="p">/</span> <span class="m">2</span><span class="p">,</span> <span class="p">-</span><span class="n">vfv</span><span class="p">.</span><span class="n">Value</span> <span class="p">/</span> <span class="m">2</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span>
<span class="n">Quaternion</span> <span class="n">BL</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Quaternion</span><span class="p">(</span> <span class="n">hfv</span><span class="p">.</span><span class="n">Value</span> <span class="p">/</span> <span class="m">2</span><span class="p">,</span> <span class="p">-</span><span class="n">vfv</span><span class="p">.</span><span class="n">Value</span> <span class="p">/</span> <span class="m">2</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span></code></pre></figure>
<p>Please note that the constructor for the quaternion is converting from euler angles into quaternion representation. <a href="https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles">There’s an entire wikipedia article on the topic</a></p>
<p>Next we will create quaternions for the UAV rotation and the gimbal rotation.</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="n">Quaternion</span> <span class="n">gimRot</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Quaternion</span><span class="p">(</span><span class="n">gimRoll</span><span class="p">.</span><span class="n">Value</span><span class="p">,</span> <span class="n">gimPitch</span><span class="p">.</span><span class="n">Value</span><span class="p">,</span> <span class="n">gimYaw</span><span class="p">.</span><span class="n">Value</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span>
<span class="n">Quaternion</span> <span class="n">acRot</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Quaternion</span><span class="p">(</span><span class="n">acRoll</span><span class="p">.</span><span class="n">Value</span><span class="p">,</span> <span class="n">acPitch</span><span class="p">.</span><span class="n">Value</span><span class="p">,</span> <span class="n">acYaw</span><span class="p">.</span><span class="n">Value</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span></code></pre></figure>
<p>Next we will multiply to get new quaternion representations for each corner.</p>
<figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="n">Quaternion</span> <span class="n">TR1</span> <span class="p">=</span> <span class="n">acRot</span><span class="p">.</span><span class="nf">Multiply</span><span class="p">(</span><span class="n">gimRot</span><span class="p">.</span><span class="nf">Multiply</span><span class="p">(</span><span class="n">TR</span><span class="p">));</span>
<span class="n">Quaternion</span> <span class="n">TL1</span> <span class="p">=</span> <span class="n">acRot</span><span class="p">.</span><span class="nf">Multiply</span><span class="p">(</span><span class="n">gimRot</span><span class="p">.</span><span class="nf">Multiply</span><span class="p">(</span><span class="n">TL</span><span class="p">));</span>
<span class="n">Quaternion</span> <span class="n">BR1</span> <span class="p">=</span> <span class="n">acRot</span><span class="p">.</span><span class="nf">Multiply</span><span class="p">(</span><span class="n">gimRot</span><span class="p">.</span><span class="nf">Multiply</span><span class="p">(</span><span class="n">BR</span><span class="p">));</span>
<span class="n">Quaternion</span> <span class="n">BL1</span> <span class="p">=</span> <span class="n">acRot</span><span class="p">.</span><span class="nf">Multiply</span><span class="p">(</span><span class="n">gimRot</span><span class="p">.</span><span class="nf">Multiply</span><span class="p">(</span><span class="n">BL</span><span class="p">));</span></code></pre></figure>
<p>And that is pretty much it. We can now convert back into Euler angles (<a href="https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles">Remember this link</a>) Once we get back Euler angles, we can utilize roll and pitch into modified versions of equations 4 and 5. Modified versions of equations 6 and 7 will then use the yaw angle we got back from the quaternion.</p>
<script type="math/tex; mode=display">dx = (\tan{roll} \times altitude) \tag{12}</script>
<script type="math/tex; mode=display">dy = (\tan{pitch} \times altitude) \tag{13}</script>
<script type="math/tex; mode=display">dutmx = dx \times \cos{yaw} - dy \times \sin{yaw} \tag{14}</script>
<script type="math/tex; mode=display">dutmy = -dx \times \sin{yaw} - dy \times \cos{yaw} \tag{15}</script>
<p>Then follow up with 8 and 9.</p>
<p><a href="https://github.com/rijesha/CamFootprintTester/blob/master/CamFootprintTester/Quaternion.cs">C# Quaternion class used to perform multiplications and conversions</a></p>
<h2 id="c-cam-footprint-tester">C# Cam Footprint Tester</h2>
<p>I wrote a small c# application to test this out.</p>
<p><img src="/images/cam_footprint_tester.PNG" alt="Screenshot of tester application" /></p>
<p><a href="https://github.com/rijesha/CamFootprintTester/">You can find the full code here</a></p>
<p><a href="https://github.com/rijesha/CamFootprintTester/blob/master/CamFootprintTester/MainWindow.xaml.cs">The main program file that includes all the steps</a></p>
<h2 id="real-life-usage">Real Life Usage.</h2>
<p>I wrote this code for the Paparazzi UAV project. It is written in OCaml.
<a href="https://github.com/paparazzi/paparazzi/pull/2103">Here is the pull request with all of the relevant files changed.</a></p>
<p>Thanks for reading. I hope this helps somebody out!!</p>
Mon, 15 Jan 2018 04:33:00 +0000
http://rijesha.com/2018/aerial-cam-footprint/
http://rijesha.com/2018/aerial-cam-footprint/UAVCamerafootprintaerialfield of viewquaternionsanglesOoh I made a blog<p>So this is my first post on this blog. Hopefully, it will be filled with some interesting subject matter. The following is mostly a poorly worded reference for myself, but could also help you set up a similar site.</p>
<h3 id="setting-up-the-splash-page">Setting Up the Splash Page</h3>
<p>The splash homepage (found at <a href="rijesha.com">rijesha.com</a>) is based on a template from <a href="https://html5up.net/">html5up.net</a>. html5up.net produces free responsive html5 themes. A responsive website changes for different devices and screen sizes. A few modifications were made to the original template, particularly the Javascript, to allow for a dynamic “about me” section. Check out the original <a href="https://html5up.net/identity">here</a>.</p>
<h3 id="enabling-github-pages">Enabling GitHub pages</h3>
<p>The website was then pushed to a GitHub repo with the name <a href="https://github.com/rijesha/rijesha.github.io">rijesha.github.io</a>. This is the default name that is required for the base GitHub pages site. In addition, you may need to set up DNS name forwarding. There are plenty of instructions for this floating around the internet. <a href="https://help.github.com/articles/using-a-custom-domain-with-github-pages/">GitHub Instructions</a></p>
<h3 id="setting-up-the-blog-site">Setting up the blog site</h3>
<p>GitHub pages allow for the creation of <a href="https://help.github.com/articles/user-organization-and-project-pages/">project pages</a>. This is a convenient way to generate a subsite while keeping all the <a href="https://github.com/rijesha/blog">files separate</a>. The subrepository is based on a <a href="http://artemsheludko.pw/flexible-jekyll/">jekyll theme</a>. <a href="https://github.com/rijesha/blog/tree/master/_posts">Raw blog posts</a> are written in markup and are generated after being uploaded to GitHub. Finally, in the repository settings you will <a href="https://help.github.com/articles/configuring-a-publishing-source-for-github-pages/">need to enable githubpages</a>.</p>
Tue, 26 Sep 2017 04:32:00 +0000
http://rijesha.com/2017/ooh-i-made-a-blog/
http://rijesha.com/2017/ooh-i-made-a-blog/JekyllGitHub Pages