Mark Gilbert's Blog

Science and technology, served light and fluffy.

Science & Technology Podcast, Episode 29 – Snap Rover

In this episode, Mark and Lucy build an RC Snap Circuits Rover.

https://markofquality.wordpress.com/2015/03/29/science-technology-podcast-episode-29-snap-rover/

March 29, 2015 Posted by | Podcast, Science | Leave a comment

Science Podcast, Episode 28 – Robot!

In this episode, Mark and Lucy build a robot!

https://markofquality.wordpress.com/2015/02/14/science-podcast-episode-28-robot/

February 14, 2015 Posted by | Podcast | Comments Off on Science Podcast, Episode 28 – Robot!

Science Podcast, Epsiode 27 – Stratoballoon Rigging

Mark and Katherine describe how the capsule, radar reflector, parachute, and balloon were all held together.

https://markofquality.wordpress.com/2015/01/19/science-podcast-episode-27-stratoballoon-rigging/

January 19, 2015 Posted by | Podcast, Science | Comments Off on Science Podcast, Epsiode 27 – Stratoballoon Rigging

Science Podcast, Episode 26 – Stratoballoon Capsule Construction, Part 2 of 2

Mark and Katherine finish the details of the stratoballoon capsule construction:

https://markofquality.wordpress.com/2015/01/14/science-podcast-episode-26-stratoballoon-capsule-construction-part-2-of-2/

January 14, 2015 Posted by | Podcast, Science | Comments Off on Science Podcast, Episode 26 – Stratoballoon Capsule Construction, Part 2 of 2

Science Podcast, Episode 25 – Stratoballoon Capsule Construction, Part 1 of 2

Mark and Katherine walk through Part 1 of the stratoballoon capsule construction:

https://markofquality.wordpress.com/2015/01/13/science-podcast-episode-25-stratoballoon-capsule-construction-part-1-of-2/

January 13, 2015 Posted by | Podcast, Science | Comments Off on Science Podcast, Episode 25 – Stratoballoon Capsule Construction, Part 1 of 2

Science Podcast, Episode 24 – Stratoballoon Capsule Recovery!

Mark and Katherine celebrate the recovery of the capsule with some amazing photographs, and Rainbow Dash’s debriefing:

http://markofquality.wordpress.com/2014/11/04/science-podcast-episode-24-stratoballoon-capsule-recovery/

November 4, 2014 Posted by | Podcast, Science | Comments Off on Science Podcast, Episode 24 – Stratoballoon Capsule Recovery!

Will you just wait a minute?! NUnit and Async/Await

I was being a good-doobie.  Honest.

I had written a prototype – just something to prove that a particular approach could work.  It did, and so now it was time for me to actually bring that code up to production quality.  Part of that meant modifying how I was invoking the third-party web services – they  needed to be done asynchronously.

So I went through and wrote my unit tests to also run asynchronously:

        [Test]
        public async void Divide_4DividedBy2_Equals2()
        {
            AsyncUnitTest.Math MathLibrary = new AsyncUnitTest.Math();

            float Quotient = await MathLibrary.Divide(4, 2);

            Assert.AreEqual(2, (int)Quotient);
        }

I ran it through NUnit on my machine, and everything was peachy-keen.  I ended up writing nearly 50 unit tests* like that, converting over all of my calls.  I committed the code, and let TeamCity take over.

And watched every one of those new tests break.

When I looked at the TeamCity log, the errors seemed to hint that the test runner was simply not waiting for the thing under test to complete before trying to run the asserts.  I started searching for things like "nunit async", and pretty quickly across this two-part series by Stephen Cleary:

In this series, Cleary says that the underlying problem of running async tests is that they don’t have a proper context:

We’ve encountered a situation very similar to async in Console programs: there is no async context provided for unit tests, so they’re just using the thread pool context. This means that when we await our method under test, then our async test method returns to its caller (the unit test framework), and the remainder of the async test method – including the Assert – is scheduled to run on the thread pool. When the unit test framework sees the test method return (without an exception), then it marks the method as “Passed”. Eventually, the Assert will fail on the thread pool.

His solution is to simply give the test an async context, and he provides a very handy wrapper to do just that.  I first had to install his Nito.AsyncEx NuGet package, and then wrap my test in AsyncContext.Run:

        [Test]
        public void Divide_4DividedBy2_Equals2_Asynchrofied()
        {
            AsyncContext.Run(async () =>
            {
                AsyncUnitTest.Math MathLibrary = new AsyncUnitTest.Math();

                float Quotient = await MathLibrary.Divide(4, 2);

                Assert.AreEqual(2, (int)Quotient);
            });
        }

Notice that I’ve removed the "async" keyword from the test itself; AsyncContext.Run does all the work here.  After updating and committing my first test using AsyncContext.Run – a test test, if you will – it ran successfully on TeamCity.  I updated the other 48, and finally got a green build.

***

My build was stable again, but Cleary’s explanation didn’t answer the question of why this worked on my machine in the first place – without using his very awesome library – so, I kept digging.

I first looked up exactly what TeamCity was using to run the tests – it was NUnit, the same as what was on my machine, with a minor different in the version.  My local copy was 2.6.2, while the version on the build server was 2.6.1.  Could there be a difference in how 2.6.1 was handling async?

Why yes.  Yes there was.  In the NUnit 2.6.2 release notes I found this:

When running under .NET 4.5, async test methods are now supported. For test cases returning a value, the method must return Task<T>, where T is the type of the returned value. For single tests and test cases not returning a value, the method may return either void or Task.

– Source: http://nunit.org/index.php?p=releaseNotes&r=2.6.2

Are you serious?  I just happen to have the first version of NUnit that would properly handle async on my machine, but the build server was one notch older, and therefore couldn’t?  *facepalm*

To further prove that this was the real source of my issue, I installed NUnit 2.6.1 and 2.6.2 side by side on my machine.  I took my two tests from above, both of which should have tried to execute the MathLibrary.Divide function which included a 2-second delay:

    public class Math
    {
        public async Task<float> Divide(int Numerator, int Denominator)
        {
            await Task.Delay(2000);
            return Numerator / Denominator;
        }
    }

When I ran these two tests through NUnit 2.6.1, Divide_4DividedBy2_Equals2 completes in a couple hundredths of a second, while Divide_4DividedBy2_Equals2_Asynchrofied takes just over 2 seconds to complete, for a total of just over 2 seconds:

2-6-1

When I ran these through NUnit 2.6.2, EACH test takes just over 2 seconds to complete, for a total of just over 4 seconds:

2-6-2

So, I have two choices – switch my builds on TeamCity to use at least NUnit 2.6.2 to run the tests, or use Cleary’s Nito.AsyncEx library, which will allow me to leave the build server as is.  In any event, at least I have a reasonable explanation for what was happening. 

The funny thing is that it’s usually MSBuild that messes with me.  Apparently NUnit gave him the week off.

 


* Yes, I realize that by calling the service directly, this no longer counts as a "unit" test, but rather an integration test.  That distinction isn’t relevant to the issue described in this post, though, so I’m going to gloss over the mock objects in the real code.

October 23, 2014 Posted by | Agile, Visual Studio/.NET | Comments Off on Will you just wait a minute?! NUnit and Async/Await

Balloon Mapper

Our receiving station for the Stratoballoon project consisted of three major pieces of software:

I’ve gone into great depth about how the first two are configured on my technical blog (“Stratoballoon Radio Details”).  Today, I want to talk about the third one, BalloonMapper.  Here is the basic interface:

10

We would copy a dataline out of dl-fldigi and past it into the "Data Line" box (#1).  We could then hit Enter, or manually click the "Find Position" button in the upper right corner.  This would extract the altitude, and the lat/long from the data string.  It would convert the former into feet and display that in the "Altitude" box (#2).  It would also create the Google Maps URL that would show the lat/long as a pin on the map.

What did the data strings look like?  A picture-perfect data string that came off the radio would look like this:

    KD8VZA-KD8VZA-KD8VZA,120057.00,234.11,4214.7460,8533.3750,*4FF4

This is a comma-delimited string, and is made up of the following:

  • My callsign, repeated 3 times
  • A timestamp, in hhmmss.xx format (where the decimal places are ignored)
  • The altitude, in meters
  • The latitude (format explained below)
  • The longitude (format explained below)
  • A termination string, made up of an asterisk, followed by four alphanumeric characters

In most cases the callsigns came out a bit garbled, so it would look more like this:

    a8czZA-KD8VZA-KD8VZA,120057.00,234.11,4214.7460,8533.3750,*4FF4

The first part of the string got chewed up because it took us a second to tune dl-fldigi to lock onto the signal.  That’s the main reason I start the string with three copies – I wanted to give Katherine or I (whoever was working the radio) a second or two to get ahold of the signal.

Extracting the altitude was very straightforward.  Simply grab the 3rd piece of data in the string, multiple it by 3.28 to convert it from meters to feet, and display it in the box.

        public static String GetAltitude(String DataLine)
        {
            String[] DataLineComponents;
            String RawAltitude;

            DataLine = (DataLine ?? "").Trim();
            if (String.IsNullOrEmpty(DataLine)) { return ""; }

            DataLineComponents = DataLine.Split(',');

            RawAltitude = DataLineComponents[2];

            return String.Format("{0} ft", (double.Parse(RawAltitude) * 3.28).ToString("0"));
        }

The lat/long was a bit tricker.  First, I had to get them into a format that Google Maps would understand.  You can browse directly to a specific lat/long point on Google Maps like so:

    https://www.google.com/maps/place/42°17’44.76"N+85°43’22.50"W

The lat/long values, however, always come off the radio in the 4-dot-4 pattern.  Here is how they broke down:

    4214.7460 = 42° 14.7460′

    8533.3750 = 85° 33.3750′

So, I would need to split the degrees from the rest of the string, then convert the fractional arc-minutes into arc-seconds, before I could drop it into Google Maps:

        public static String GetUrl(String DataLine)
        {
            String[] DataLineComponents;
            String RawLat, RawLong, FormattedLat, FormattedLong;

            DataLine = (DataLine ?? "").Trim();
            if (String.IsNullOrEmpty(DataLine)) { return ""; }

            DataLineComponents = DataLine.Split(',');

            RawLat = DataLineComponents[3];
            RawLong = DataLineComponents[4];

            FormattedLat = String.Format("{0}°{1}'{2}\"", RawLat.Substring(0, 2),
                                                          RawLat.Substring(2, 2),
                                                          (double.Parse(RawLat.Substring(4)) * 60).ToString("00.00"));
            FormattedLong = String.Format("{0}°{1}'{2}\"", RawLong.Substring(0, 2),
                                                           RawLong.Substring(2, 2),
                                                           (double.Parse(RawLong.Substring(4)) * 60).ToString("00.00"));

            return String.Format("https://www.google.com/maps/place/{0}N+{1}W", FormattedLat, FormattedLong);
        }

So, now I had my URL.  I needed a way to embed a browser into BalloonMapper, which was a Windows desktop app.  I looked at a few options, but eventually settled on Gecko Effects: https://bitbucket.org/geckofx/geckofx-29.0/downloads.

I created a Gecko.GeckoWebBrowser object on my form called "GoogleMaps".  To browse to a URL, I simply called the .Navigate() method on the GoogleMaps object, and passed it the URL that I generated above:

                this.GoogleMaps.Navigate(GetUrl(this.DataLineBox.Text));

 

Using it was easy.  Getting the control installed and working was a little more difficult, and I had a few false starts.  In the end, here is what worked:

  • I downloaded Gecko Effects 29.0 (see link above).
  • Gecko requires another application called "xulrunner", which I obtained from here: http://ftp.mozilla.org/pub/mozilla.org/xulrunner/releases/29.0.1/runtimes/
  • I found that I needed to match the version of xulrunner to the version of Gecko, otherwise I got a "Specified cast is not valid" error.
  • I also found that the program has to be installed to a folder called "xulrunner" – all lowercase – or it wouldn’t work.

This made finding the capsule’s current location extremely easy:

20

For full source code and binaries, please visit http://TinyURL.com/MarkGilbertSource, and look for the BalloonMapper.zip archive.

October 10, 2014 Posted by | Science, Visual Studio/.NET | 1 Comment

Science Podcast, Episode 23 – Stratoballoon Eggbeater Ground Antenna

Mark and Katherine build an antenna.  Or mangle a kitchen utensil.  Or possibly both.

http://markofquality.wordpress.com/2014/10/06/science-podcast-episode-23-stratoballoon-eggbeater-ground-antenna/

October 6, 2014 Posted by | Science | Comments Off on Science Podcast, Episode 23 – Stratoballoon Eggbeater Ground Antenna

Stratoballoon – Thank You

Mark and Katherine say a heartfelt "Thank You" to everyone who contributed to the Stratoballoon project.

http://markofquality.wordpress.com/2014/09/23/stratoballoon-thank-you/

September 23, 2014 Posted by | Podcast, Science | Comments Off on Stratoballoon – Thank You

Follow

Get every new post delivered to your Inbox.