Garmin Connect IQ is a platform that allows developers to create applications for Garmin's wearable devices. The main components are the SDK and a dedicated, new programming language called Monkey C. Not surprisingly, Garmin also released an application marketplace where developers can publish their creations.
In February 2015, I had agreed to do a review of the mapping and hiking features of the Garmin Epix sports watch in my hunting blog. While waiting for the device, I did some research and found out about the Connect IQ. The possibility of being able to develop applications for it was tempting, and I decided to give it a shot.
Despite the rate new technologies and platforms have emerged during the last years, this was the first time I was one of the very early adopters of a development platform. At first, I hesitated a bit jumping into a field of development so unfamiliar to me: I had never owned a wearable device before and the last time I had done any coding for an actual piece of hardware was at the polytechnic over ten years ago.
Being one of the few
Strangely, I think being an early adopter encouraged me to stop whining and start coding. It felt comforting that things will be bad for everyone, not just me.
I started playing with Garmin's Connect IQ in last March – just two months after the 1.0 version of the Connect IQ SDK had been released. The development environment was simple enough to set up. I downloaded Eclipse, the Connect IQ plugin for it and the actual SDK and was coding in no time.
Having everything set up presented another problem: what would my first wearable app do? I wanted to somehow connect the app to hunting since it was the reason I was getting it in the first place. Though storing and retrieving coordinates was possible, the SDK did not have any map-related functionality available, so developing a map enabled application was not an option. After some studying, I decided to try porting the GNU Ballistics library to Monkey C and build a ballistic calculator around it.
From The Web to watch
Now, creating something for a device is entirely different. Instead of processing one request from start to finish and terminating, a watch application renders a user interface and keeps listening for user actions and handling them as they come. Most of the heavy lifting is done by the framework. Connect IQ SDK provides the developer a solid foundation to build upon, and the programmer is left with the task of implementing the user interface and event handlers.
Instead of doing all the fun UI stuff out of the way, I decided to practice what I preach and started with what I felt presented the most uncertainty in the project, namely porting the ballistics library from C++ (of which I had no experience) to Monkey C (of which no-one had any experience).
The porting was not nearly as bad as I had expected. The source of the GNU Ballistics library was written clearly enough to be understood by even an inexperienced reader, and all I had to do was to rewrite it using Monkey C syntax. Most of my time went converting C++'s typed variables to duck-typed ones used by Monkey C and making sure that too much precision was not lost in the process. Getting started was easy, and after resolving the last run-time error, I had quite satisfying results. The code I ended up with was not the most resource friendly, but it ran in the simulator.
Now all I had to do was to build the rest of the app. Easy, right?
The UI, making-of
Despite never owning a smartwatch, I knew the basic design principles of developing apps for tiny devices with limited hardware and less than perfect user experience: stick with simple user input and give a quick response to user actions. Unfortunately, in this case, it was easier said than done: every rifle and cartridge combination is unique, so there are no universal defaults. Before the application can do any calculations, plenty of variables need to be set by the user and the watch user interface is not exactly well suited to the task.
I decided to put most of the settings under application's main menu. Each setting would get a top level menu entry of its own for quick access. When the user clicks on a menu item, the connected input controller is run presenting an interface to input the requested data. As the CIQ did not have decent generic input elements until v1.2.0, I had to create one myself. I ended up using a piece of code I found in the Garmin's forums as a base for my homebrew generic input class. The class could be extended to allow users to input various types of parameters such as ballistic coefficient (a decimal number), initial bullet speed (in feet per second), the height of the sight from bore centerline (in inches) and so on.
In addition to the menu, the application has two main views. One for displaying the main parameters the user typically sets for each shot: the distance to target, windage and elevation, and a second one for presenting the results after a successful calculation.
The views are built by extending the base class Toybox::WatchUi::View. The class enables the developer to define a layout in an XML file telling the application how the page should look. The application renders a view automatically when it is pushed into the page stack. Rendering can also be triggered manually by the developer when for example the data changes and the user interface needs refreshing.
Putting it all together and failing
After a months work, I had a simple application that could calculate a bullet trajectory correctly. The user would configure their rifle and cartridge properties through the main menu on the first run and the application would save them for later. The first version was not pretty, and the calculations took their time, but it worked.
I still had not received my testing device, but as it worked in the simulator, I decided to publish it nevertheless.
Publishing an application to Connect IQ store is very straightforward compared to releasing a mobile app. The install package is generated in Eclipse and the file uploaded to the store using a simple web form. The application is verified on the first upload, but the verification process should not take more than a couple of days.
After Ballistics was published and people started downloading and using the application, it became apparent that the simulator had issues of its own. While the application worked in the simulator, it crashed immediately when executed in a real watch. And since I had no testing device available, there was nothing I could do.
After finally getting my Epix, I started resolving the issues right away. The app was using way too much memory. When the memory usage exceeded the available 64kb, which unfortunately happened on startup, the user saw a crash screen and the application quit.
After some serious refactoring and with help from the Garmin support team and nice people at the development forum, I was able to keep the memory usage below the limit and people could start using Ballistics.
Overall the experience was great. I had a chance to learn new stuff and managed to deliver in the end despite all the problems during the project. After the first functional release, I've kept adding new features, such as support for on-device sensors and configuring the application through Garmin Connect mobile application.
The application ended up being great. Although the heavy calculations take their time, a small delay would not be a problem in a real-world use case. The current version is 1.39 and it can be downloaded here. Finnish speaking readers can check the blog post I made about Garmin Epix in my other blog: "Ensisilmäilyssä Garmin Epix".