Cast for two

Friday, January 31, 2014

Adding virtual power to TCX for the Tacx Blue Motion Cycling Trainer

I recently bought a cycle trainer for indoor training: Tacx Blue Motion T2600 for 185€ at fiets.be, a local cycling store. Using my Garmin 800, i could record my heartrate, cadence and speed while riding a workout. Since I have no power meter on my bike, I was barred from a feature that higher and more expensive trainers offer. But in the documentation of the trainer, I found a graph showing a linear relation between speed and power. So if I just could add this to the recorded file before submitting it to Strava, I would have trainer for less than 200€ with power measurement. This is the graph:

From that graph we can derive that riding at 60 km/h in position 5 (the middle blue line) a power of 500 Watt is developed. Hence power = speed / 60 * 500 = speed / 6 * 50 . Remark that speed must be in Km/h dimensions to obtain the power in Watt. There's even an interactive graph at website of Tacx. The Garmin 800 measures speed by counting the number of revolution of the wheel in a time unit and multiplying this by the circumference of the wheels. I converted the .fit file, I obtained from the Garmin device, in TCX (a XML file) using Garmin Training Center (Free software available for Windows and Mac). This file basically contains a list of trackpoints (1 trackpoint every second). One trackpoint looks like this:
        <Trackpoint>
            <Time>2014-01-29T20:38:59Z</Time>
            <AltitudeMeters>157.4000244</AltitudeMeters>
            <DistanceMeters>14850.7099609</DistanceMeters>
            <HeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t">
              <Value>139</Value>
            </HeartRateBpm>
            <Cadence>92</Cadence>
            <Extensions>
              <TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2" CadenceSensor="Bike">
                <Speed>8.4530001</Speed>
              </TPX>
            </Extensions>
          </Trackpoint>
At this time, the speed was 8.4530001 meter per second. To convert this to km/h, we have to divide by thousand and multiply by 3600 (the number of seconds in an hour). So speed_in_kmperh = speed /1000.0 * 60 *60 = 30.43080036 km/h. The power developed at that moment was : 30.43080036/6.0*50.0 = 253.590003 Watts. We convert to integer : 253 Watt. To add this to the TCX file, we add a line <Watts>253</Watts> as follows:
        <Trackpoint>
            <Time>2014-01-29T20:38:59Z</Time>
            <AltitudeMeters>157.4000244</AltitudeMeters>
            <DistanceMeters>14850.7099609</DistanceMeters>
            <HeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t">
              <Value>139</Value>
            </HeartRateBpm>
            <Cadence>92</Cadence>
            <Extensions>
              <TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2" CadenceSensor="Bike">
                <Speed>8.4530001</Speed>
                <Watts>253</Watts>
              </TPX>
            </Extensions>
          </Trackpoint>
The next step was to automate the calculation of the power and adding it to the TCX file. I wrote the following Python script to do that:
prompt> python vpower.py > vpower_29-01-14\ 20-53-27.tcx
I uploaded the resulting TCX file to Strava and obtained this:
Of course, the power in this workout is based on the fact that I left the lever om my trainer on position 5 during the whole workout. If you change the position of the lever during the workout, this approach will give wrong results.

Is this approach of "virtual power" accurate ? Not as accurate as power meters on the bike but usable I would argue. The concept of "virtual power" is also supported by Trainer Road Software. Later, I found an interactive graph of the speed power relation for Tacx Blue Motion on the website of Tacx. From that graph, I could obtain more precise datapoints : at 60 km/h power is 407 Watt. So next time I use my script, I will use power = speed_in_kmperh / 60.0 * 407.0 as power formula.

Wednesday, January 15, 2014

Euler : great talk by William Dunham

Having a Google Chrome Cast at home increased my longform consumption on Youtube dramatically. For instance, I discovered this talk about the great mathematician Euler by William Dunham:

I learned from it that there's a simple polynomial discovered by Euler that generates 40 consecutive primes: $ \forall n \in [0,40] : x^2+ x+ 41$ is a prime number.
You can check it by running following Python code:
You may wonder if there are other polynomials that generate primes. The article "Prime Generating Polynomials" claims that the polynomial $(x^5 - 133x^4 + 6729x^3 - 158379x^2 + 1720294x - 6823316)/4$ generates 57 consecutive primes for $x \in [0,56]$. Also the Wolfram article " Prime-Generating Polynomial indicates that polynomial as a winner. There are of course formula's to generate prime numbers but i think the Euler polynomial is the fastest.
The solution to Euler problem 27 is also interesting. A second degree polynomial generates 71 primes (but they are not consecutive). The polynomial $x^2 - 61x + 971$ generates 71 primes for $ x \in [0,70]$. This is the longest solution when the absolute values of the coefficients are restricted to thousand. If we drop that restriction, an even stronger polynomial is found : $x^2 -79 x + 1601$ generates 80 primes. Remark that the generated primes are not unique. For example the numbers 1601, 41, 197, 797, 1373, 1523 are generated twice. From the 80 primes generated, 40 are unique. I think Euler would not have been impressed.

Tuesday, December 11, 2012

Random Forests are the new kid in machine learning town

Is was reading "Specialist Knowledge Is Useless and Unhelpful
When data prediction is a game, the experts lose out." I learned about the new algorithm that seems like a silver bullet for data mining problems: random forests. An explanation in layman's terms can be found on Quora. It still don't fully grasp the idea but I think its worth exploring further to add to a toolbox to solve problems. There exist a R package for random forests for some quick exploration on your datas. Happy hacking.

Monday, October 10, 2011

Design inspiration

This weekend I was browsing with zite app on Ipad. Especially in the "webdesign and user experience" section I encountered some interesting links:

Monday, August 22, 2011

Back from holiday

This video sums up how the holiday was. Two of the boys that are jumping are my sons. It was shot with a simple Canon Ixus 300HS. The video video resolution is only 320x240 pixels and was shot at 240 frames per second. Enjoy it.

Saturday, June 25, 2011

It's not the story, the people, the technology, it's the team

I was directed to the blog of Amir Salihefendic, and i bounced into this gem:

Finally, these are the operating principals of Pixar as quoted by Catmull:
  • constant review
  • it must be safe for people to tell the truth
  • communication should not mirror the organizational structure
  • people and how they function is more important than ideas
  • do not let success mask problems, do a deep assessment
  • mix up creative and technical people
So it's not the story, the people, the technology, it's the team, but remember: 
"Once one can articulate an important idea into a concise statement, then one can use the statement and not have to have a fear of changing behavior." (Ed Catmull, pixar).

Maybe I should read the pixar book that's on my reading list for some time now.

Wednesday, March 16, 2011

Tuesday, December 07, 2010

Bye bye battery of MacBook Pro


Today, I replaced for the second time the battery of my Macbook Pro. The battery had 560 reload cycles. Apple's documentation states that normally a battery should be able to deliver about 800 cycles before replacement is needed. I got my (now iconic) Macbook Pro beginning of 2007 and this is already the second time I have to replace the battery. So with my (heavy) usage the battery worked for two years. The new battery is again made in 2006. So problem's again in 2013 ? Or will I have a new Macbook Pro with a fixed battery by then ??? Maybe I have to recalibrate my battery more often.

Saturday, September 11, 2010

Fireworks shot with Canon Ixus 300HS

Yesterday evening, I went to the yearly firework held in Leuven, Belgium. I filmed the finale with my new Canon Ixus 300HS (aka Powershot 4000 SD) at 720p. Here's the result:

I also took some pictures in the fireworks mode. I think the movie catches the moment much more than the pictures. But for those interested, here is a picasa album containing the original unedited files. Here's a nice one:

From Vuurwerk

Saturday, July 31, 2010

Tuesday, July 27, 2010

Hosting my pictures in the cloud: Google Storage

Picasa Web Albums - cast42

Uploaded with plasq's Skitch!

I finally did it: ordered 20 gigabyte of Google Storage to store my pictures in the cloud. I need to pay 5 dollar every year. A real bargain if you ask me. I wished to upgrade my quota because the free gigabyte everybody gets on Picasa Web was getting full. My pictures are stored on my mac and are backuped by Time Machine. So a solution to safeguard my pictures in case of a real catastrophy that destroys both the mac and the backup was not in place yet. With the extra gigabytes on Google storage, I now can store an extra copy in the cloud. It's not only an extra safety for the storage but comes in very handy because of the convience of the Picasa tool and Picasaweb website for sharing pictures.

My workflow is now as follows:

  • Copy the pictures from my digital camera (currently a Canon Ixus 300 HS) to my mac with Iphoto. Iphoto puts the pictures into new events (= pictures taken at the same time of the day)
  • Then I select the pictures I like and put them into an album of Iphoto.
  • Next I export the album on Picasa Web using Picasa Web Albums Uploader, selecting "Actual Size" so that it archives the original files in the cloud. This may take a bit longer for uploading but will save the day when all my pictures disappear from my mac and backup.

If I manage to fill up the 20 Gigabyte, it can upgrade to 80 GByte/ year for 20 dollar/year. So that's save for the future ;-)
My Account
Uploaded with plasq's Skitch!

Wednesday, May 19, 2010

HTML5 example to change the opacity of an image via CSS3

Here's a simple HTML5 example that changes the opacity of an image via CSS3 using an input range element and some Javascript.

<!DOCTYPE html>
<html>
<head>
 <title>HTML5 example to change the opacity of an image via CSS3</title>
</head>
<body>
<img id="img_0576" src="IMG_0576.jpg" alt="My bike"style="opacity: 0.5;" />
<input id="img_op" type='range' min='0' max='100' value='50' onchange="changeOpacity()">
<script>
function changeOpacity() {
 var opacity = document.getElementById('img_op').value/100;
 document.getElementById('img_0576').style.opacity = opacity;
}
</script>
</body>
</html>
This example is mainly to test out the use of code highlighting on Blogger as explained by Luka Marinko. It seems to work well. Huray!
If you're interested in HTML5 you can follow the Friendfeed on HTML5.

Monday, April 26, 2010

Trailer for the episode 3 of the virtual revolution on the Flemish television

On tuesday 24 april 2010, VRT will air a dutch spoken version of the third episode of BBC's Virtual Revolution. Here's the trailer:













The code to embed this:

<!-- BEGIN EMBEDCODE CANVAS-->
<div id='canvasvideo_container_47281' style="width: 507px; height: 320px; border: 1px solid black;">
<object id="canvasvideo_47281" width="507" height="320">
<param name="movie" value="http://static.vrt.be/swf/jwplayer45.swf"/>
<param name="allowScriptAccess" value="always" />
<param name="allowFullScreen" value="true" />
<param name="flashvars" value="config=http://video.canvas.be/embed%3Fvideo%3D47281"/>
<param name="wmode" value="transparent">
<embed type="application/x-shockwave-flash" wmode="transparent" name="media" src="http://static.vrt.be/swf/jwplayer45.swf" quality="high" allowscriptaccess="always" allowfullscreen="true" flashvars="config=http://video.canvas.be/embed%3Fvideo%3D47281" width="507" height="320">
</embed>
</object>
</div>
<!-- EINDE EMBEDCODE CANVAS-->


It's a pitty the embed code is not working on Blogger.....

UPDATE: It tried to solve this by using an Iframe:

usign this code:
<iframe src ="http://programmas.canvas.be/wp-content/uploads/2010/04/The-virtual-revolution-Aflevering-3-trailer.html" width="507" height="320">

But that is still not working. Strange.


UPDATE 3: maybe I have to URL unescape the value of flashvars to
http://video.canvas.be/embed?video=47281













Saturday, March 06, 2010

Skiing in Stuben am Arlberg, Austria

In a yearly tradition, I publish a short movie about the skiing holiday. It's not as cool as with a Go Pro Hero cam but still interesting. This year I edited again with Imovie on the mac. Imovie is really the tool you need for such a job. When finished, I pushed the button to upload to youtube and half an hour later:

This year we stayed in Stuben am Arlberg in Austria. They say that stuben is the capital of off piste skiing, but this year we stayed on the slopes because the danger of snowavalanches was very real.

I only noticed an annoying bug. Although the star wars end trailer is in imovie:

the end of the movie on Youtube is just the black background with white stars but without the moving end credits. Annoying bug !

Monday, February 01, 2010

How to deal with search crawlers for your mobile site

So you've setup your mobile site (for example hosted at http://m.yoursite.com) derived from a desktop version (for example hosted at http://www.yoursite.com).Typically, you're using a Content Management System and by providing adapted templates for your mobile items, you can provide a mobile version of your site. The question is now how to deal with robots that crawl the web to build a search index. The danger exists that the robots detect duplicate content because the mobile version from a content item might contain the same text and pictures but wrapped on another template. I think the following steps should be taken:


  1. Only allow the mobile web crawlers with the following robot.txt in the root of the mobile site (for example http://m.yoursite.com) by allowing bots with user agent "Googlebot-Mobile" or "YahooSeeker/M1A1-R2D2" and to disallow all others:

    User-agent: Googlebot-Mobile
    Disallow:

    User-agent: YahooSeeker/M1A1-R2D2
    Disallow:

    User-agent: *
    Disallow: /

    Also, disallow mobile crawlers to your desktop version of your site by adding the following robot.txt in the root of your site (for example http://www.yoursite.com/robot.txt ):

    User-agent: Googlebot-Mobile
    Disallow: /

    User-agent: YahooSeeker/M1A1-R2D2
    Disallow: /

    User-agent: *
    Disallow:

    With the first robot.txt in the mobile root and the second one (here above) in the root of your desktop site, your mobile site items should only appear when people search with a mobile search engine (for example by using http://m.google.com ) but not when searching with the desktop version (for example http://www.google.com ).

    As far as I know, the MSNbot that crawls for the Microsoft Bing index together does not have a bot version that crawls strickly for the mobile Bing search engine at http://m.bing.com.

  2. Add your mobile site to Google : http://www.google.com/support/webmasters/bin/answer.py?answer=40348 , Bing http://www.bing.com/webmaster/SubmitSitePage.aspx, Yahoo (http://siteexplorer.search.yahoo.com/mobilesubmit) and other relevant mobile indexes

  3. Create a mobile sitesmap : http://www.google.com/support/webmasters/bin/answer.py?answer=34648&cbid=-1rt6r3us7wrvl&src=cb&lev=answer


Let me know I've you have anything to add to this strategy in the comments.

Sunday, August 02, 2009

Set all links target to _blank on a XHTML 1.0 Strict using jquery

As explained here, opening links in a new window is no longer possible via target=_blank in XHTML 1.0 strict. This code is a workaround using Javascript:


function externalLinks() {
if (!document.getElementsByTagName) return;
var anchors = document.getElementsByTagName("a");
for (var i=0; i<anchors.length; i++) {
var anchor = anchors[i];
if (anchor.getAttribute("href") &&
anchor.getAttribute("rel") == "external")
anchor.target = "_blank";
}
}
window.onload = externalLinks;

A link with attribute rel set to external will open in a new window:

<a rel="external" href="http://castfortwo.blogpspot.com/">cast42</a>

On the Friendfeed realtime embed code, I saw they use jquery to do the job:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.js">
<script type="text/javascript">
$("body").mousedown(function(e) {
for (var target = e.target; target; target = target.parentNode) {
if (target.tagName == "A") {
if ((document.location.href.split("#")[0] + "#") == target.href) {
return;
}
target.target = "_blank";
return;
}
}
});
</script>

The advantage is that all links will open in a new window, except if the refere to an anchor in the page. Hence there's no need to add the attribute rel to each anchor.

Tuesday, July 28, 2009

Urbain Airship: a webhook based service for Iphone 3.0 Push Notification

picture about fast internet infrastructure
This morning I discovered a new recipe on Google App Engine Cookbook to send out Iphone 3.0 Push notifications via Google App Engine. In fact, the recipe makes use of a service called Urban Airship. They provide a free service that allows to send upto 5000 Push notifications a month. For larger volumes, the price seems reasonable. Image now that all content producers become pubsubhubbub (the pseudo realtime webhook based enabled publish/subscribe protocol proposed by two Googlers) enabled and maybe we scratch the surface of the future internet architecture that will drive the realtime web. Who knows?

Monday, July 20, 2009

Pubsubhubbub: a webhook based publish/subscribe

On Friday 9 July 2009, Google engineers Brad Fitzpatrick and Brett Slatkin showed a demo of a new realtime protocol called pubsubhubbub. This new technology could lead to a more reactive, pseudo realtime web. I my humble opinion, this might be much bigger news from Google then the announcement of Chrome OS. Of course, only the latter made a big splash in the mainstream news.

The issue of messaging is a topic addressed already many times in the course of computer science. Common wisdom is that the publish-subscribe pattern is a sound solution to this. The problem is that due to all kinds of practicalities it often regresses into a polling solution. Even with pubhubsubbub, the website that want to display realtime updates has to poll the hub to check if an update has happened. So there's still a nut to crack! In the example of a subscriber, a Javascript polls the hub to check for an update.

If anybody would know an implementation of the client that does not poll, please let me know.

In the demo at Techcrunch, updates made by blogger appeared almost realtime in google reader. Currenlty, not all blogger accounts support pubsubhubbub.

To be ready when your blogger account is updated, do not forget to add your feed to Feedburner and to activate Pingshot:
enable pingshot in feedburner
A pubsubhubbub plugin for wordpress exists and the Drupal community is probably already working on it. Check the overview of publisher code for clients on the pubsubhubbub project page.

Pushed on publish post on monday 20 Juli 2009, at 10:41. Updated at 11u17

Tuesday, June 23, 2009

Spore Galactic Adventure Released in Europe, today 23 June 2009

IMG_0791
Spore Ruimteavonturen (Galactic Adventures) Picture 2
This afternoon i received a SMS that my preordered expention kit, called Galactic Adventures for the EA Spore game, was available. I picked it up for 30 euros and installed it. Everything went smooth.
IMG_0794
After a succesfull installation, we clicked on the Spore icon in the dock of the mac and prepared for the new fun....that we didn't find. Looking up the documentation and calling the EA helpdesk brought no prevail. I tried a second install. Nothing helped. Until I went looking in the installation directory Spore in the Applications directory. I saw that a new executable was there called "Spore Ruimteavonturen" (dutch for Spore Galactic Adventures). Dubbel click this new executable and of we go:
IMG_0795

Saturday, May 02, 2009

links to JPEG images in ATOM feed entries must be typed image/jpeg

After some debugging, I found a nasty bug in an ATOM feed that validated by the W3C validator service. I was trying to parse image url's out of an ATOM feed. ATOM 1.0 feeds are defined by the RFC 4287. In paragraph "4.2.7.3. The "type" Attribute" it is defined that the type must conform to the syntax of a MIME media type. The MIME media type is in turn defined by RFC 4288. Media type registrations are listed by the IANA at: http://www.iana.org/assignments/media-types/
If we look up the media subtypes of image/ we find that JPEG images have MIME type image/jpeg . The feed I was parsing had images with MIME type image/jpg instead of image/jpeg as it should have been. Apparently the W3C validator does not validate the type of links. I reported the bug/unconformence. Hopely it will be fixed soon.
A handy list with all MIME types to be used as reference is also provided by w3cschools.