Showing posts with label paddling. Show all posts
Showing posts with label paddling. Show all posts

Tuesday, September 15, 2015

Paddle Mate Beta Access

I made good progress on the Paddle Mate "Just Ship It" Release this past weekend. I had to step back, look at my activity state restoration code and fix a couple key problems. With that under control the app is handling backgrounding much better now.

This Beta version also includes:

  • App setting persistence so that the app remembers your last used workout settings (track location, Microsoft Band pairing options)
  • The DOCK view (main landing view of app) now includes a preview of the map from your last workout and some stats from the workout.
  • State Restoration.

With these changes in place, the app is ready for wider Beta Testing. If you are interested in trying out Paddle Mate before I ship it then you can sign up at: Announcing Beta Access to Paddle Mate

Sunday, September 13, 2015

Paddle Mate V 1.0: Just Ship It Release

Past Workout (WAKE) view on the main DOCK view.
I have a couple irons in the fire at the moment which have me spread thin.
  • I'm working on a new site which I will write more about shortly (it is still baking and is not ready for prime time yet).
  • Various home projects.
  • I signed up for a Half Marathon at the end of October and have been ramping up training.
  • Fixed a bug in Selfie Band and shipped the update.
  • I have been finishing up Paddle Mate's first release.
Paddle Mate, the Just Ship It Release, has gotten some well deserved attention the past few days.

I had a couple half baked features and did some triage on those. I decided to move them out into future releases and in the process created a RoadMap. With the RoadMap I have a defined ongoing plan with a focus for each upcoming release.

I just finished off validating that the app works with/without a Microsoft Band attached. Without the Band the experience is not as rich but I am planning to support a richer experience for non-band users over time.

Paddle Mate is now down to 2 gating bugs that I am working on today. In developer lingo, gating means that the product can not pass the release gate to customers until those bugs are fixed.

I have one tester who is out today in this rain that has been testing. Once I get a handle on one of the bugs I will be going out for another test kayak.

The other bug is in the past workout view, I have a handle on the problem and will tackle that later today.

This boat still can't launch when that is all done. My list of tasks after I fix these bugs include:
  • Verify I have no more gating bugs.
  • Write launch page.
  • Write marketing page.
  • Write Privacy Policy for app.
  • Record App Preview
So, with about 1 hour to go in today's dev window I need to get back to getting this app shipped.

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.

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.

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 Fabric.io. 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}"
else
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $appBuild" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
fi
/usr/libexec/PlistBuddy -c "Save" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
echo "Updated ${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 Realm.io and will post on that more later. I am using Realm.io over CoreData since I have never bought into CoreData's overweight API. I like the lightness of the Realm.io 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 Realm.io 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 mark@newthistle.com.

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 http://www.newthistle.com/contact/

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.

Reset


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
Easy302783%
Sprint1010100%
Easy252392%
Sprint201785%
Easy504794%
Mixed1209680%
Easy1008484%

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
course.

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.