Thursday, August 27, 2015

Constraints Give Focus

The more constraints one imposes, the more one frees one's self. And the arbitrariness of the constraint serves only to obtain precision of execution.
Igor Stravinsky

I've spoken of this before, as a creative person, the hardest job can be to know when to stop/when to ship.

Building an app, creating a work of art, planning the weekend, deciding what to make for dinner; all of these things can get out of hand if you don't limit yourself. You need a plan and you need to set a bar for:
  • What is the bare minimum needed to achieve your end result? The Minimum Viable Product.
  • What is the desired feeling you want your consumers to experience? Utility? Joy? Full?
  • What are you desired goals with this product? Ship an app? Showcase your skills?
All of these things need to be considered but many times we want to deliver everything with a dime store budget. This is seldom possible.

My wife, from her experience in product management, was the first to introduce me to the concept that you can have a product Cheap, Fast, or Good. Pick Two! This is called the Project Management Triangle.

As an indie with a full time job and a family, I run into this problem all the time. I feel I am asking too much to pick two when having one with limited time is hard enough.

Here's how many of my projects go:
  • Brilliant Idea!
  • Crave out a block of time to put in a mad dash to get a prototype working.
  • Start to design a MVP.
  • Start to implement the MVP.
  • Run into corners I never foresaw.
  • Start slogging through the corners, rounding everything out.
  • Invest too much time into after hours indie work.
  • Crash, burn, burn.
  • Put project on back burner.
For every project I have completed, there is a mountain of projects I have abandoned.

Is this bad?

Only if you let it get to you. I look at that mountain as wisdom.

Here is what I take away from my "failures", if you want to call them that:
  • Experience
    • To know when I am adding more features than I can complete.
    • To know which ideas will take too much time.
  • Knowledge
    • With new techniques, skills, APIs, etc.
    • Few jobs offer training. As a contractor, I must think of my own training. These side projects help me to expand my skills and train.
  • Resolves
    • To find better ideas to solve, build, and deliver.
  • Efficiency
    • The more projects I work on the better I become at solving problems.
    • The more I projects I deliver the better I get at delivering solutions.
Constraints add focus.

Figure out how to use those constraints to improve your projects.

Learn from your mountain of failures and learn where you can add constraints to increase your pool of successes.

Wednesday, August 26, 2015

Paddle Mate Post Weekend Update

Night Testing

As some saw, over the weekend I took Paddle Mate for a night test and it went well. Here is the workout, which I posted from the water to Strava. This was a final field test after a previous couch test with a shorter test run from a past day.

Backgrounding Bugs

After the successful test on Saturday night I added more features on Sunday. When I went to try out the app for a longer 2 mike kayak I ran into several bugs. The major one being backgrounding related. This raises the issues that I need to refactor my PADDLE view to handle resuming when the app is relaunched after being stopped by the system while in the background.

This is one of the final 2 big bugs to shipping the app for testers. It will be my area of concentration when I find time this week.

Sunday's Features

  • SHARE view
    • Refactored from PADDLE END view
    • Send to Strava complete
    • Send samples to Paddle Mate (this is for testers or users so they can upload samples so I can add them to my testing and algorithm training)
  • WAKE view
    • The WAKE view as I have discussed is the view for looking at previous sessions.
    • Tweaked the scrollview to layout elements with more space for map and charts.
    • Add delete option to delete a session you do not want to keep.
    • Add SHARE option
    • Hooked in Map and Charts
  • PADDLE view
    • Added Map view back in. I was getting distracted by tweaking the Map (for maybe an hour) and put it on the back burner until I had a couple bugs in the PADDLE view metrics fixed. This made it back in and I really like it.
    • Add ability to have Map and Stats view force screen to not sleep. This is on now for my testing but I think I should expose this with an option. I will address that when I fix the backgrounding bug I have.

Next Steps

Well, I am back to reality. My family arrived back home from a visit to Canada and I am back to my normal schedule. This means a decrease in posts and slowing down of the progress I was able to make over a weekend. I can not pull a 29+ hour effort on Paddle Mate for the foreseeable future but I will need to spread that time out.

Ok, so now that I am back to my normal schedule I will refine my list of what I need to ship the MVP. Here are my upcoming tasks I need to ship for testers:

  • Address the backgrounding problem. Not a big deal and I have a handle on how to get the resumption working.
  • Second big bug: I found some limits in the iOS-Charts library and was able to not only freeze my app but my phone (until the system could kill my app and it's out of control chart generation). The library was spinning the CPU up to 100% with a lot of nested CGImage creations as it tried to draw a chart for a very large sample set. I need to address this before I ship and find the upper limit on the libraries chart sample size.
  • Style the DOCK view of Wakes of previous sessions. I have some ideas here and it is not critical to get the app out the door but I need to move from the current placeholder UI.

Follow Up: The Chart Bug

For one of my charts I was using it to view accelerometer samples while testing and am planning to convert it over to a chart with your speed over the workout. The issue I ran into (which I am happy I did since I have an upper bound to work back from) is that I selected the chart with my 28 minutes of accelerometer data and it's approximately 6700 samples kicked the charts ass.

To solve the problem I am going to limit my sample size based on the time. I need to find that upper limit and then calculate out a sample set size that has less entries than the upper limit for reasonable performance for expected kayaking times.

Monday, August 24, 2015

Reuse in App Design

END PADDLE view reused as
SHARE view
Code reuse is important and we take advantage of it all the time with open APIs. When we are designing our own code, UI, or UX we can also get code reuse. Here's how I reused the END PADDLE view for the SHARE view.

I left the implementation of the Past Workouts view (called the WAKE view) and it UX until after I had the basic app functionality working. Once I started to implement the WAKE view I began to see I could make some small changes to the existing END PADDLE view to reuse it as a SHARE view.

Here is the scenario.
Jane is kayaking and is outside of data coverage. She ends her kayaking and can not upload to Strava to share her workout with friends. Jane wants to be able to upload her workout when she gets to lunch where she knows she will be back in data coverage.
To handle this scenario I decided I would put that option in the WAKE view so that you can see which past paddles have been uploaded. From here you can also upload that past paddle.

Here is where the reuse comes in.

The END PADDLE view contains the sharing options; to Strava for example.

So, I refactored the END PADDLE view to support both the End Paddle workflow and the Share from Wake workflow.

This decreases the amount of code I need to write, reduces the number of views in my app, and let's me move faster.

Look for ways to implement your views with reusability in mind. You may be able to save yourself work in the future when you need similar functionality from another location in your app.

Sunday, August 23, 2015

Feature Decisions

I started Paddle Mate 3 weekends ago. The first weekend I started with proving out the the initial algorithm, setup a way to collect and test sample data, and then began the hard work.

Once I decided the app was viable, I began to polish the app for release. First I had to come up with my wish list and then trim that down into a Minimum Viable Product (MVP) list of features.

The MVP features I desire being:

  • Stroke counting
  • Real time workout stats
  • Location tracking
  • Upload to Strava
  • Import into Health App
  • Submit Samples for Stroke Detection Refinement
  • View Past Workouts
  • Delete Past Workouts

It has been a busy 2 weeks and I am into the final stretch before my wife and kids get back from a visit with family in Canada. With them away I was able to throw myself into creating the app. 

Over the last two weeks I have put in about 65 hours over 5 weekend days. I have not tracked the weekday nights as well but needless to say, I have invested time on many nights researching, designing, and cranking out code.

All the work is paying off. Yesterday evening (9pm) I took Paddle Mate for a spin around the lake. I put in just over 2 km with the app over 28 minutes. Notes from that:
  • Dark Mode for nighttime kayaking worked out very well.
  • I need to add an option to not turn off the screen.
  • I am missing an activity indicator during the sample submission file generation.

Yesterday's Features

  • Sample Submission
    • User has ability to choose the data to send.
    • Submission is through a Mail Compose view so the user can view what they are uploading and choose to cancel at multiple stages if they do not want to upload samples.
  • Tweaked my use of the Realm Database to:
    • Decrease write calls.
    • Add delete.
    • Improve use with tableviews.
  • Initial hookup work for Past Workouts (WAKE view) is done.
  • Submit to Strava
    • Hooked up but my GPX data format is being rejected. 
    • More testing/tweaking needed here.
  • Created converter and file writers for my location and sensor data models to support CSV and GPX output formats.

Yesterday's Commit List

  • Updates to UI design in PaintCode.
  • Added tintColor constant.
  • Refresh DOCK tableview when returning to view.
  • Added Delete button to END PADDLE view.
  • Switched navigation from push detail to push in PADDLE workflow to allow pop to root without animation warnings.
  • Added PaddlingEffort enum for user submitted samples.
  • Added logic for incrementing workout id.
  • Added stroke data to sample submission format.
  • Added submit samples to Paddle Mate via email submission.
  • Added convert location data to sample submission format.
  • Fixed warnings in FRDStravaClient.
  • Wrote converter from location readings to GPX output.
  • Wrote converter from location reading to location CSV output.
  • Wrote converter from sensor reading to CSV output.
  • Improved use of Realm with Dock TableView.
  • Improved MathController default configuration.
  • Added Uploading activity indicator and dimmer view.
  • Added upload to Strava method. - GPX file format issue at moment.
  • Hooked up controls in WAKE view to workout values.

Today's List of Features

  • Strava upload
    • Fix GPX format
  • Past Workouts
    • Add Delete option
    • Add Submit Samples Option
    • Add Upload to Strava Option
    • Enable Charts
    • Enable Map with route from workout

Friday, August 21, 2015

UX Testing, Where Bad Designs Go To Die

Bad Design Be Gone

I made some UX decisions during design that I thought would work out. They didn't.

Back to the drawing board.

While testing the app over the past few days (walking the dog, running, driving) and I realized some things did not flow well. So I took Tuesday night to reevaluate the design and work out how to solve some of the flow problems.

Two things I did:
  • I reviewed multiple fitness apps to understand how they handle some of the UX I was having problems with.
  • I showed the app to more people to gather feedback about the UX.
Both of those things brought to light multiple areas that could be improved.

So, I redesigned a couple views, added some missing views, and jotted down some great feature ideas I received. The features I captured for a post V1 release.

Missing Interstitial View

In particular, a problem area I had was the Paddling/Workout workflow. Here is what I had:

  1. User taps PADDLE on the main view.
  2. Transition to Prepare To Launch view.
  3. User chooses if they want to track location and use a paired Microsoft Band.
  4. User taps Play button to start paddling workout.
  5. Transition to PADDLE view, the main workout view.
  6. User decides to stop workout, they tap Pause button.
  7. Transition to Paddle End view.
It was steps 6-7 that had a problem. Here are what the views looked like.
Missing a Pause/Stop Confirmation View

The main problem with the above design is that I am trying to do too much in the PADDLE_End view. I am trying to cover several tasks:
  • CONTINUE: You paused by mistake, did you want to go back?
  • DONE: End the workout.
  • Upload to Strava: Did you want to upload the workout?
  • Send to the Health App: Did you want to store your workout in the iOS Health App?
  • SEND SESSION TO PADDLE MATE: (Too long) Are you a tester and want to submit samples?
Here is what I have done so far to fix a major flaw.

I added an interstitial view between 6&7 which is a Pause view. This will let me move the CONTINUE from PADDLE_End back to the main view.

I think this offloads the decision to end the workout to this new PADDLE_Pause interstitial view. Now the user is not thinking about should they continue or end on the next screen, lower the cognitive work on the PADDLE_End view.

New Paddle Pause with interstitial Pause/Stop Confirmation view added before Paddle End view

At first, I left the CONTINUE in but realized I needed to remove it since the decision to CONTINUE/UNPAUSE is on the interstitial view. Now, I think I have a cleaner UX for ending the workout.

Change Design, Test, Repeat

Then, on Wednesday night I completed the integration of Microsoft Band data, CoreLocation data, and workout metrics into my Realm backend. This is cool since I had implemented the code to load the DOCK view, the main view you land on when launching the app, previously when I designed the data model.

Now I have a lot of workouts showing up on the main view as I test the PADDLE workflow.

Then I released I needed a way to delete a workout on the PADDLE_End view when a user (me) wants to delete a session they do not want to track. So, for this I added a DELETE button to the PADDLE_End view.

I do not think this adds to much to the cognitive load since a review of multiple fitness apps those that many use this concept on their end workout view. I also think it fits to have the DELETE | DONE on the top so the user can choose if they want to keep/delete this workout.

They are along the same line visually and hence they are giving you two options along the same line of vision.

Now with Pause interstitial and Delete option
Now it's time to retest and see how this new design's UX feels after repeated use.

Thursday, August 20, 2015

Adding Custom Fonts to Paddle Mate

Snippet of Console dump of available system fonts
For Paddle Mates design I want a font that has a tight set of numbers on the paddle view (also know as the workout view in other fitness apps). For that I did some research and a lot of looking at fonts last night.

I have a couple fonts I will be testing in the next few internal releases until I settle on the one for the app.

If you need to add custom fonts to your iOS App, a good walk through was done by Chris Ching over at Code with Chris called Common Mistakes With Adding Custom Fonts to Your iOS App.

Some of the sites I reviewed looking for fonts included:

Monday, August 17, 2015

Adding Strava and Health App Integration to Paddle Mate

My Co-pilot stealing me seat
when I went for water

Quantifying Humanity

Like any other Quantified Human (QH for short, or just narcissist for the haters) it doesn't count if it wasn't measured. So, today I got to work on Strava integration into Paddle Mate.

The Strava API has a ton of features and allows:
  • Up to 600 requests every 15 minutes
  • 30,000 requests per day
If I hit that limit with Paddle Mate then there would be worse things to deal with than needing to request a higher limit. One can dream.

To integrate Strava I decided to shortcut as much as possible. In that vein I ended up pulling in the following libraries:
With these in place I was able to get Strava integrated, login, and pull my profile data.

The Health App

After Strava login and profile access was done I integrated Health App support so that I can write to the built in iOS Health App. With this in place, users will be able to store their kayaking working into the Health App and count their kayak against their daily goals.

Now that I have Strava and the Health App connectivity, the next big push will be to convert my current sensor and workout data into formats for Strava and the Health App. I decided to leave the work for this conversion until I had Strava and the Health App ready to go since I look at how I need to convert the data for both at the same time so all the conversion logic is fresh in my head.

Another busy weekend of coding and the app is getting closer to the list of V1 features I have in mind.

Sunday, August 16, 2015

Refactoring Like a Boss

Bringing Order to Chaos

Dark Mode for evening Kayaks
I like to create a lot of sample projects where I can workout features of an app. Though there extra some setup involved, it let's me refine a feature to the least code needed to support the functionality I am want.

For Paddle Mate, I have a project for Charts, one for Barometer tracking, one for Realm, and one for the Stroke Detection algorithm that is the heart of the project.

Today has been a day of bringing those together and things are shaping up as I move parts into place.

Gone is my MVC (Massive View Controller from last weekend) as I have now broken the app down into a clean hierarchy of:

  • Frameworks
  • Source
    • DataModel
    • Managers (For lack of better naming)
    • Utilities
    • Views
    • ViewControllers
  • Tests
  • Products

Design Payoffs

The nights spent reviewing design tips, fonts, colors, and then creating multiple mockups has paid off. I am much happier with the look of the app as I integrate the various features. Having designs to guide me is speeding up development. 

I am occasionally getting slowed down when I find I missed something but refinement is part of the process and learning experience. Now I know I need some additional views to handle the clean starting and stopping of a workout when I need to manage location services, mapping, Microsoft Band connections, pausing, continue, and whatever else I missed.

A big payoff for my workflow has been the purchase of PaintCode. I first heard about PaintCode from friends at Shopify who swore by it. I broke down and bought it few months ago and started to learn how to use it.

Since then I have become more adapt with it and have started to build up a library of icons for my apps. This has helped me speed up development time as I can reuse assets while I work.

Another big help with design assets has been:
  • The Noun Project where I look for inspiration and often use icons from there, with attribution.
  • Entypo+ with it's wealth of SVG pictograms.
Over time I plan to build more of my own icons so that I can build unique assets which I own.

Well, off to bed. Another long day with 15 hours of coding. Today was not a fill the rings kinda day.

Sunday (today) I plan to tackle:
  • Upload workout to a fitness tracking site.
  • Export to Health App Integration.

Saturday, August 15, 2015

Add Charts to your iOS App

Paddle Mate has some charts, as I mentioned earlier I am using ios-charts by Daniel Cohen. The article that put me onto ios-charts was How to Use iOS Charts API to Create Beautiful Charts in Swift. It is well worth the read if you are looking to add charts to your app.

One thing I have noticed is large spikes in memory when zooming in or panning around the chart. That is something to keep an eye on in your app.

Also great about this library is that it is a port of the Android library MPAndroidChart by Philipp Jahoda, which means you only need to learn one charting library that you can use on two platforms since the code is very similar. Handy if you are supporting both Android and iOS.

Machine Learning Research for Paddling Stroke Detection

Part of the rationale behind the creation of Paddle Mate has been to get a better understanding of what Machine Learning really is. The best way to achieve an understanding of something is to do it, hence I came up with Paddle Mate as a platform to build on as I teach it to detect paddle strokes.

Here is my understanding of Machine Learning, in beginners words.

  • Create an algorithm.
  • Create a program to exercise your algorithm.
  • Tell the program the algorithm's parameters it can change.
  • Feed the program some samples to run against the algorithm and mark the points of interest.
  • Next, let the program loose on your algorithm, with more sample sets, letting the program tweak the parameters of the algorithm to find the optimal values to derive the expected outcome of the sample sets.
Ok, but how the hell do you do that?

At first, as I've covered in past posts, I had to sit and play with the sample sets to find patterns that I could boil down into an algorithm that would detect strokes. Next, I had to figure out what values I could tweak to make the stroke detection more accurate. Then I manually tweaked those values until I found some optimal values for my stroke detection algorithm.

As we can see, at the moment I am the machine. Next it will be time to replace my manual work with the machine part of machine learning.

In that vein, I have done some research into what I need to do to get the Machine learning aspect running after I finish prepping Paddle Mate for release.

Why get ready to ship Paddle Mate if it is not perfect? I want to collect more samples from users who opt in and send their kayaking sensor data to me. I can then start to improve Paddle Mate with a wider set of samples. This will really let me exercise the machine learning aspect to improve my algorithm.

Ok, here are some things I have found in my research. I am putting them here so I can refer back to them later.
Now why did I choose R?
  • It is free.
  • I know how to program so learning another programming language does not daunt me.
  • It has good source material (the Introduction to Elements of Statistical Learning book and videos) which I can use to learn this.
  • Did I mention it is free? Have you looked into the cost of Matlab or Mathmatica? Screw that, I don't need a second mortgage to learn this stuff.
Ok, back to productizing Paddle Mate.

Friday, August 14, 2015

Designing Paddle Mate

Programming is my strong suit and designing does not come naturally. Though I am inclined to art and have both drawn and painted, I still find app design is something I struggle to get right.

With that in mind, here are some things I am doing as I work to make Paddle Mate useful (and non-ugly) for users in bright sunlight, while kayaking in the evening, and when reviewing past kayaks or showing the app to a friend.

I am doing some reading first off. Here are some things I have read recently on design:

Here was the UI:

Here are my new designs I plan to test for bright sunlight:

Thursday, August 13, 2015

Paddle Mate: Getting Ready for Testers

Fabric metrics show meSelfie Band
had 22 commits to the master and
has been 100% crash free so far.
For usage metrics and crash reporting I use Once I have an app to a point where I am ready to give it to a friend to test out I add Fabric.

Fabric let's you setup Beta tests (though I use Test Flight once I have an app that can pass App Store Review for Test Flight Betas), track app usage, and retrieve crash reports if you app crashes.

When I add Fabric I also add versioning to my app so I can track the builds that are in the wild with Testers or in the App Store. For that I use a script in the Build Phases.  My script is triggered off my number of commits to the branch I am working on. So a feature branch will have the feature in the version but an AppStore build will have just the number of commits (from the master branch, where I ship from).

Here is the one I use which I have a link to the original in my comments:

# Set the build number to the current git commit count.
# If we're using the Dev scheme, then we'll suffix the build
# number with the current branch name, to make collisions
# far less likely across feature branches.
git=`sh /etc/profile; which git`
appBuild=`"$git" rev-list --all |wc -l`
if [ $CONFIGURATION = "Debug" ]; then
branchName=`"$git" rev-parse --abbrev-ref HEAD`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $appBuild-$branchName" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $appBuild" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
/usr/libexec/PlistBuddy -c "Save" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"

Paddle Mate now has 

Wednesday, August 12, 2015

Paddle Mate: Mapping + Icon

I have added MapKit to Paddle Mate and can now trace my route. That has been pretty cool.

Tomorrow I will test pace, distance, and route updates during a workout. You can also now look at your route while Kayaking.

And I built a first pass for an app icon which i think looks much nicer on the phone than here :-)

Also just started to integrate and will post on that more later. I am using over CoreData since I have never bought into CoreData's overweight API. I like the lightness of the API and I can get behind that. It appears to get out of the way and let me concentrate on the app instead of fighting with CoreData.

We will see in the next few days while I integrate into the app to store sensor data (for submitting samples for post workout analysis) and to store workout data including map locations for post workout review.

Monday, August 10, 2015

Hackathon: Writing a Microsoft Band App In One Weekend - Update 5

Update 5: The Sunlight Strikes Back

Yesterday I start working on MapKit integration and a higher contrast Work View. Though I find the font and weight a little heavy, for bright sunlight I figured I should err on the side of overweight and work backwards.

Here is the last prototype UI I used yesterday:

Here are the new UIs I will try out next:

Map It with MapKit

I also began to add mapping to the app. I want to track distance covered and pace. So, since I am doing that I might as well put in a MapView to let you see where you are. I am undecided on how much I will build that out. A review of other fitness apps shows that most have a full screen MapView but I am unsure that is required for my intended purpose.

Perhaps for someone navigating a series of rivers or along the coast it might be handy to be able to zoom out. I would hope that someone was not using the app for navigation though; as that is not the intended purpose.

My goal with a map view is to see if I am tracking close to a given route I might want to repeat for comparison.

What do you think? Would a full screen MapView be useful?

The Last 20%

To productize this app for sale here are some of the features I think it needs. Let me know if you think I am wrong.
  1. Main Page with list of previous workouts.
  2. Export option to:
    • Health App
    • Strava
    • Runkeeper
    • Endomondo
    • Facebook
    • Twitter
    • Mail Developer Session Samples (So I can continue to refine the algorithm)
  3. View Previous Workout
  4. Workout Mode
    1. Basics working.
    2. Missing MapKit for Distance, Pace
As well, I need to find a unifying design, color scheme, typography, and all the other details to make the app not look terrible.

Hackathon Result

I am calling this a decent start to a new app. Here are some of the wins from this weekend:
  • The basic algorithm is 80%+ accurate on stroke detection.
  • I have a platform to build out skills in algorithm design for a fitness apps.
  • I can export data from the app for post workout analysis.
  • I have a new excuse to hit the water more for some kayaking.
To those that read along, Thanks! It was nice to have feedback and see that people were interested in this topic.

If you kayak and have an iPhone, get in touch with me

If you want to see some of the products I have worked on or get on touch to collaborate on a project check out my company NewThistle LLC.

You can sign up to find out when I do another Hackathon weekend or launch an app at

Sunday, August 9, 2015

Hackathon: Writing a Microsoft Band App In One Weekend - Update 4

Update 4: Hear My Heart Beat

Can you see the 20 strokes in here? Paddle Mate found 17.

It was a dark and storming night. Taylor Swift sang her heart out in downtown Seattle while I coded my heart (beat) out writing Swift in Sammamish.

But enough of that, onto the progress report. Last night I:
  • Added Heart Rate Monitoring into the app.
  • I said what the heck, let's grab that calorie count from the Microsoft Band.
  • Then I lost my mind and decided to add a "Reset" into the app to make collecting data easier.

Oh ya, then I hooked the stroke counter. It was about time I added the feature I started this app for.

Heart Rate

I now collect the Heart Rate samples while I update the current Heart Rate label in the app. Once the workout is complete you can now view the Heart Rate in the in-app graph using the heart rate/stroke toggle icons along the right of the graph.

Calorie Counts

Just displaying the calories burnt during the workout, as reported by the Microsoft Band.


During data collection on Saturday morning I had to force close the app to clear it. I had to do this between each data collection.

We aren't animals here. Force closing apps? What will be next? Side loading apps you got from a friend off of 10x3.5" floppy disks which are really not floppy? No, we won't.

Behold the Holy Reset of Antioch!

Yes, the reset was that good.

Wet And Wild 2: Get Me Some Samples

With only one Sprint Pace sample I decided I needed more samples. Here are the results of today's collection with the Stroke Detector I worked on yesterday.

PaceStrokesDetected StrokesAccuracy

Overall I am pretty happy with the new stroke detector. With an 80%+ accuracy I think that is pretty good for a one day of crash course Linear Regression, Moving Average, Classification, and Standard Deviation coding session.

My next phase of stroke detection I think will involve some machine learning to see how more accurate I can get the algorithm. At the moment I see I need to do a couple things based on the samples:

  • Classify strokes and trailing strokes by pace (Slow, Medium, Fast) and then use that classification to adjust the stroke detection algorithm.
  • Better rejection of garbage samples (non-strokes).

About Class Structure

You know that joke about MVC? Massive View Controller?

That's this app at the moment.

I know, I should hang my head in shame. But screw it, I will put making this an architecture marvel to knock your socks off on my "Backlog".

To be truthful it is not all a MVC. I have the following classes:

  • PaddleCounter class to handle stroke analysis.
  • Ring class to handle the ring buffers for moving average calculations for the PaddleCounter.
The rest of the logic at the moment is in the ViewController but will change once I extend the app.

Notes From Wet Tests

During testing on the lake I made some notes about the app:
  • As we know,trying to read an iPhone in the sun sucks. I am going to need a high contrast UI with very large components if the user has a hope in hell of seeing the strokes, heart rate, etc.
  • The waterproof plastic case I have is soft and as such touching one point on the screen may cause a different location to register the tap. This means that during a workout I will need to add a dialog to prompt a user "Do you really want to stop you workout?"

Saturday, August 8, 2015

Hackathon: Writing a Microsoft Band App In One Weekend - Update 3

Update 3: Wet and Wild

Data! We have Data! We have tons and tons and tons of Data!
Samples for 40 Strokes at Sprint Pace
Those same 40 strokes charted and tweaked for algorithm building

Sample Gathering

This morning I made a first pass of the Stroke Counter algorithm. I then went down to the lake and collected 10 sample groups to run against the Stroke Counter.

The sample groups included:

  • 20 Strokes at an Easy Pace
  • 5 Strokes at an Easy Pace
  • 40 Strokes at a Sprint Pace
  • 60 Strokes at an Easy Pace

Turn Simulation
  • 20 Strokes on Left Side Only
  • 10 Strokes on Left Side Only
  • 20 Strokes on Right Side Only
  • 10 Strokes on Right Side Only

Odd But Why Not
  • 20 Strokes Backwards
  • 20 Strokes Backwards

Algorithm Test Run 1

The first test run of the sample data against the initial Stroke Counter sucked...I mean it was very inaccurate. There goes trying to "guess" my way through this.

Ok, so more work was needed on the algorithm and that was my day. About 9+ hours of tweaking later and I am passing all Easy Pace tests. Tomorrow I will run a new sample session with this algorithm and see how it stands up during use in the kayak.

Improvements For Sprinting

For Sprinting or fast and strong strokes I am going to tackle the problem by looking at peak samples in trailing sample ranges. If a peak reading goes above a known Sprint High Water Mark (HWM) that is outside the normal HWM then I will apply a modifier to my HWM and LWM (Low Water Mark). Then as long as the trailing peak samples above the "Sprint HWM" I will apply a modifier to my stroke classification.

I can see that one of the trickiest problems will be handling the transition from an Easy pace to a Sprint pace. This will be interesting to solve.

Tweaking The Algorithm

So, what did I do to tweak the algorithm today?

The exporter I built into the app exports the sample data into a file with Comma Separated Values, with one reading per line. I am using the Share Sheet from my app so I can easily save my samples to Dropbox after each sample collection.

Once I got back to the house. I imported the sample groups into Numbers and created charts for each sample set.

For each chart I left the chart zoomed out on top and then I created a duplicate chart below and zoomed it in. I applied the following adjustments to my chart:
  • Series
    • Turned on Trendlines with Moving Average and tweaked the Period to find a sweet spot for the algorithm high and low water marks.
    • Turned on Error Bars with Standard Deviation to help isolate the Trendline while reviewing between the 10 sample sets.
    • Changed the Trendlines to Red and increased them to 4 pt. This helped them stand out in the charts.
  • Axis
    • I added Minor Ticks and tweaked each chart so I could better isolate the peaks and valleys of the sample.

Beginning of the Easy Pace 60 Strokes Group

Cool Charts! Now What?

I got several suggestions from friends to do machine learning, use Azure, or many other tools. For many of these, they are overkill for the initial app's stroke counter. As well, I am trying to create the initial app over this weekend so I don't have enough cycles to get the app working and learn machine learning. I did dive into machine learning a bit today and picked up some pointers to help me design the stroke counter.

I plan to take time to do further refining of the stroke counter later and look at how machine learning could help with that. For now, let's get the basics working.

So, I did the tweaking the hard way. I wrote test cases that consume my sample files and run them against the stroke counter algorithm. This has been very helpful and allowed me to tweak the algorithm to the current state (mentioned earlier) where I am correctly detecting strokes for an Easy Pace. I am also 75% correct for Sprint Pace but I want to get this closer to 100% accuracy.

Time for Pizza

It's not a Hackathon without Pizza. Calzones are on the way and then I get back to coding.

Hackathon: Writing a Microsoft Band App In One Weekend - Update 2

Update 2: Stroke Counter First Pass

I imported a sample set I collected of a simulated kayak sitting on the deck. Then I wrote a PaddleCounter class that I can feed accelerometer into. The class calculates the stroke count as it processes the incoming accelerometer data.

This data then needs to be displayed in the awesome UI I cooked up on a budget. Ok, it never cost me anything and it shows, but you get the picture.
As we can see a couple new features are slipping in. I figure I should track Heart Rate and average Heart Rate for the session. I am also going to collect calories burned and compare that later to calorie burn estimates to see if it is reliable. But I will hook those up later this weekend.

Collecting Samples During a Session

I decided to go with NSNotifications to send out stroke updates from the PaddleCounter class. So, when the PaddleCounter detects a stroke it will send a notification that the main ViewController can then use to display the stroke change.

Testing the Stroke Counter

I want to make testing the stroke counter as easy as possible. I plan to collect different samples and track the number of strokes. Then algorithm development will go like this:
  1. Feed my samples into the stroke counter algorithm.
  2. Compare what it dumps out with the expected number of strokes.
  3. Tweak algorithm, rinse, repeat.
My first stroke counter at about 1 AM sucked and came out with terrible results. What to do?

Charting the Samples

Ok, I was trying to eyeball the samples and hence it was hard to track the trends. So, I need to chart these samples to better understand the data I am getting.

Before I try to rewrite the stroke counter I am puttingthe samples on a chart. For this I am going to use ios-charts by Daniel Cohen Gindi to draw my sample set so I can look for trends.

Here's the new UI with the raw data in the chart and then a zoom in on section:
Samples with Default Zoom

Samples Zoomed In

Ok, now it's time to go hit the water and collect some real samples.

Hackathon: Writing a Microsoft Band App In One Weekend - Update 1

2 Hours in and I have:
  • Basic UI for Data Collection
  • Accelerometer Data Collection to CSV file using NSOutputStream.
  • Export of CSV file using the UIActivityViewController.
Next up:
  • Write a stroke counter first pass using some simulated kayaking samples.
Here is the UI for the first set of data collection.

I know, its amazing. Where did I get this UI skills? What can I say, I an old school green on black terminal kinda guy.

Friday, August 7, 2015

Harkathon: Writing a Microsoft Band App in One Weekend

My wife and kids are out of town for the weekend so what's a geek to do? Hold a Markathon of

A Markathon? That's just a Hackathon with a Mark.

What type of App should I create? I've decided I want to learn Machine Learning but I want to be practical and start small so I am going to create a simple stroke counter app for kayaking. For this I will do basic calculations to create the stroke counter. For this weekend the goal to lay the groundwork to do more complex analysis of strokes. 

With this weekends Markathon my goals are:
  • Build a harness to collect sensor data.
  • Be able to export sensor data during a workout from the Microsoft Band to a CSV (Comma Separated Value) format.
  • Collect some Kayaking sample data.
  • Crunch the data and create a basic stroke counter.
  • Create an app front end for the stroke counter.
  • Prep the app for Test Flight.
  • Find some testers who want to try out a stroke counter for the Microsoft Band.
I will post throughout the weekend as I complete stages. Follow along and feel free to tweet me if you have questions.

Thursday, August 6, 2015

Launched! Selfie Band for Microsoft Band

Well, I finally completed an app (again) for the iOS AppStore and launched it. The app is called Selfie Band, a camera app for the iPhone which allows you to use a Microsoft Band as a remote control. Check out more about the app at the NewThistle Blog: Announcing Selfie App

You can also checkout the Selfie Band HomePage.

My first app was launched in 2009. My second app (with a team of 6 Cocoaheads from the Ottawa Cocoaheads) was launched in 2010.

Then I went to work for BlackBerry for a little under 4 years where the employment agreement included a non-compete clause that meant no apps in competing AppStores. Hence, I was a Mac OS X/iOS dev at BlackBerry but could not ship my own apps.

I left BlackBerry at the end of 2013 and hence that restriction was lifted. At first, my biggest problem was what to write?

When I joined the Microsoft Band team (as a contractor) there were no restrictions on releasing my own apps. In fact I have been encouraged since I work on the Public SDK and help third party developers integrate their apps with the Microsoft Band on iOS.

Selfie Band has been several months in the making, though it might not look like that to some. In that time I took on maybe too many after-hours activities. A couple include:
  • Prepping and presenting 2 talks about the Microsoft Band SDK.
  • Writing 3 Band Apps "almost" ready to ship.
  • Starting no less than 4 other Microsoft Band Apps.
  • Helped a pre-investment startup get an early prototype setup for initial integration with their Web API.
So, as time dragged on and I had not shipped anything I knew it was time to concentrate on one app, cut features and ship it. There are many things I would love Selfie Band 1.0 to have but shipping was more important than adding features users might never want/need.

About 5 weeks ago I put the final touches on Selfie Band and prepped for AppStore submission. After a month in review including one rejection, Selfie Band came out of review last Friday and it was left to me to hit Launch.

So, last night, at NSCoder I put the final pieces in place and Launched!

It feels good to be back in the AppStore with something new that I designed and wrote myself.

If you have a Microsoft Band and an iPhone then check out Selfie Band so you can take photos from your iPhone with your Band.

Monday, August 3, 2015

Creating Family Traditions

Dragging the Kayaks back up the lake's "shore"
which is very long due to the use of the
lake as a reservoir for the Yakima Valley
Agriculture industry.
Last year I started taking one of my boys for a camping trip with just them and Dad. This year was time for my youngest to start this tradition with me.

For our trip, I decided I needed to find something where we could use his new Kayak. I got him one for his birthday and it was a hit. He loves kayaking like his older brother loves mountain biking.

So, after some research I decided on Cle Elum Lake since it had lots of camping nearby on the Cle Elum River. It had an interesting lake to kayak and there are lots of opportunities to fish.

Now, why only one of the boys? Having a chance to spend solo time with each boy gives my wife and I a chance to really hear them, bond with them, and not have other demands getting in the way. My wife takes the boys on a trip to a different city and I take them camping.

I learned a lot camping with my Dad and spending many days fishing with him. He never had to deal with the challenge of having multiple kids vying for his attention. For me, taking each boy on a solo camping trip makes the trip more enjoyable for me (lower stress from sibling rivalry) and lets me spend solid quality time with my boys.

I don't have video of Finn kayaking since he decided he wanted to use my kayak so he could have the camera and since I had a new kayak which he had not used. So, I have some footage (thanks to Finn since he worked the camera for most shots) from Finn's perspective as we kayaked in Cle Elum Lake.

The trip went awesome and we had a wonderful time kayaking, fishing, and wandering the banks of the Cle Elum River. It was a beautiful spot that I will be exploring more.
Hiking the very low Cle Elum River near our campsite.