{"id":955,"date":"2017-05-11T18:28:32","date_gmt":"2017-05-11T22:28:32","guid":{"rendered":"https:\/\/blogs.mathworks.com\/developer\/?p=955"},"modified":"2017-05-15T18:19:46","modified_gmt":"2017-05-15T22:19:46","slug":"the-fast-and-the-fouriers","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/developer\/2017\/05\/11\/the-fast-and-the-fouriers\/","title":{"rendered":"The Fast and the Fouriers!"},"content":{"rendered":"\r\n<div class=\"content\"><!--introduction--><p><b>UPDATE:<\/b> We did it and it was a lot of fun! It looks like the tracking worked out as well so that was fun to see. One slight hiccup was that we ended up tracking more than 8000 points and ThingSpeak returns 8000 points per call. No biggie! We just needed to seperate out all our calls to ThingSpeak to get all the data. The data is all there on the ThingSpeak channel I just needed to update the visualization code. I've included the updated version below to show all the points. I also distinguished the drive from MathWorks HQ over to the start from the actual course I took.<\/p><!--\/introduction--><p>Hi folks! Check it out! <a href=\"http:\/\/getinvolved.holeinthewallgang.org\/site\/TR?team_id=2870&amp;fr_id=1262&amp;pg=team\">11 MathWorkers and I<\/a>  are about to embark on a MathWorks adventure running the 200(ish) miles of Cape Cod.  We start running at 2:30 PM Eastern Standard Time tomorrow (Friday May 12th). It should be an adventure, and we were excited to help with a great cause.<\/p><p>I thought it would be fun to use a little MATLAB mobile goodness to broadcast our progress in real time. Check it out and track us either through <a href=\"https:\/\/thingspeak.com\/channels\/261391\">the ThingSpeak page<\/a> or just on this page as the map below should be updated in real time.<\/p><p>Hopefully I don't have any bugs, since I will be busy running and supporting the other runners and it might be tough to fix any mistakes I've made in the code. Remember, it's live folks!<\/p><iframe loading=\"lazy\" width=\"750\" height=\"500\" style=\"border: 1px solid #cccccc;\" src=\"https:\/\/thingspeak.com\/apps\/matlab_visualizations\/149063?width=750&height=500\"><\/iframe><p>For reference, here is the code I will be running from my iPhone using the <a href=\"\">MATLAB Support Package for Apple iOS Sensors<\/a> to send my GPS data. Note I will be doing this from an instance of <a href=\"https:\/\/www.mathworks.com\/products\/matlab-mobile.html#connect-to-the-cloud\">MATLAB in the cloud<\/a>. Awesome! Here's the function. It just takes the instance of <a href=\"\">mobiledev<\/a>:<\/p><pre class=\"language-matlab\">\r\n<span class=\"keyword\">function<\/span> trackTheFouriers(m)\r\n\r\ndisp(<span class=\"string\">\"Tracking the Fouriers: \"<\/span> + string(datetime(<span class=\"string\">'now'<\/span>)))\r\n\r\nm.PositionSensorEnabled = 1;\r\nm.Logging = 1;\r\nm.SampleRate = 1;\r\n\r\nchannel = 261391;\r\nwriteKey = <span class=\"string\">'XXXXXXXXXXXXXXXX'<\/span>; <span class=\"comment\">% Not the real write key :-P<\/span>\r\nreadKey = <span class=\"string\">'XXXXXXXXXXXXXXXX'<\/span>;<span class=\"comment\">% Not the real read key :-P<\/span>\r\n\r\n[Latitude, Longitude, posTS, Speed, ~, Altitude, Accuracy] = m.poslog;\r\n\r\n<span class=\"comment\">% Only write to the channel when there are changes in latitude, longitude, or accuracy<\/span>\r\nTimestamps = datetime(m.InitialTimestamp) + seconds(posTS);\r\n\r\nlastDataPoint = thingSpeakRead(channel, <span class=\"string\">'OutputFormat'<\/span>, <span class=\"string\">'table'<\/span>, <span class=\"string\">'NumPoints'<\/span>, 1, <span class=\"string\">'ReadKey'<\/span>, readKey,<span class=\"string\">'Location'<\/span>,true);\r\nchangeTable = [<span class=\"keyword\">...<\/span>\r\n    lastDataPoint(:,{<span class=\"string\">'Latitude'<\/span>, <span class=\"string\">'Longitude'<\/span>, <span class=\"string\">'Accuracy'<\/span>});\r\n    table(Latitude, Longitude, Accuracy)\r\n    ];\r\n\r\n<span class=\"comment\">% Find changing data<\/span>\r\nhasChanged = @(value) abs(diff(value)) &gt; 1e-5;\r\n\r\nchangeIdx = hasChanged(changeTable.Accuracy) | hasChanged(changeTable.Longitude) | hasChanged(changeTable.Latitude);\r\nT = table(Timestamps(changeIdx), Accuracy(changeIdx), Speed(changeIdx),<span class=\"string\">'VariableNames'<\/span>, {<span class=\"string\">'Timestamps'<\/span>, <span class=\"string\">'Accuracy'<\/span>, <span class=\"string\">'Speed'<\/span>});\r\nh = height(T);\r\n<span class=\"keyword\">if<\/span>  h &gt; 0\r\n    disp(<span class=\"string\">\"Writing \"<\/span> + h + <span class=\"string\">\" data points\"<\/span>)\r\n    thingSpeakWrite(channel, T, <span class=\"string\">'WriteKey'<\/span>, writeKey,<span class=\"string\">'Location'<\/span>, [Latitude(changeIdx), Longitude(changeIdx), Altitude(changeIdx)]);\r\n<span class=\"keyword\">else<\/span>\r\n    disp(<span class=\"string\">\"No data to write\"<\/span>);\r\n<span class=\"keyword\">end<\/span>\r\n\r\nm.discardlogs;\r\n\r\n<\/pre><p>Also, here is the visualization code I used to plot our course continually during the race:<\/p><pre class=\"language-matlab\">\r\ndawnOfTime = datetime(2000,1,1);\r\nendTime = datetime(<span class=\"string\">'now'<\/span>);\r\n\r\n<span class=\"comment\">% Grab the results. Keep asking for results until we have the full dataset.<\/span>\r\nT = table;\r\nintermediateResults = thingSpeakRead(261391,<span class=\"string\">'OutputFormat'<\/span>, <span class=\"string\">'table'<\/span>, <span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'DateRange'<\/span>,[dawnOfTime, endTime] , <span class=\"string\">'ReadKey'<\/span>,<span class=\"string\">'XXXXXXXXXXXXXXXX'<\/span>,<span class=\"string\">'Location'<\/span>,true);\r\n<span class=\"keyword\">while<\/span> ~isempty(intermediateResults)\r\n    T = [intermediateResults; T]; <span class=\"comment\">%#ok&lt;AGROW&gt;<\/span>\r\n    endTime = T.Timestamps(1) - sqrt(eps); <span class=\"comment\">% Adjust our window to get more data<\/span>\r\n    intermediateResults = thingSpeakRead(261391,<span class=\"string\">'OutputFormat'<\/span>, <span class=\"string\">'table'<\/span>, <span class=\"keyword\">...<\/span>\r\n        <span class=\"string\">'DateRange'<\/span>,[dawnOfTime, endTime] , <span class=\"string\">'ReadKey'<\/span>,<span class=\"string\">'XXXXXXXXXXXXXXXX'<\/span>,<span class=\"string\">'Location'<\/span>,true);\r\n<span class=\"keyword\">end<\/span>\r\n\r\n<span class=\"comment\">% Generate the map<\/span>\r\nserverURL = <span class=\"string\">'http:\/\/raster.nationalmap.gov\/arcgis\/services\/Orthoimagery\/USGS_EROS_Ortho_1Foot\/ImageServer\/WMSServer?'<\/span>;\r\ninfo = wmsinfo(serverURL);\r\n\r\nlatlim = [41.4,42.4];\r\nlonlim = [-71.4 -69.9];\r\nheight = round(diff(latlim)*1000);\r\nwidth = round(diff(lonlim)*1000);\r\n[A, R] = wmsread(info.Layer, <span class=\"string\">'Latlim'<\/span>, latlim, <span class=\"string\">'Lonlim'<\/span>, lonlim,<span class=\"keyword\">...<\/span>\r\n    <span class=\"string\">'ImageHeight'<\/span>, height,<span class=\"string\">'ImageWidth'<\/span>,width);\r\n<span class=\"comment\">% Show the map<\/span>\r\nfig = figure;\r\nfig.Position(3:4) = [width height];\r\nax = axes(<span class=\"string\">'Parent'<\/span>,fig);\r\ngeoshow(ax, A,R)\r\nhold <span class=\"string\">on<\/span>\r\naxis <span class=\"string\">tight<\/span>\r\n\r\n<span class=\"comment\">% Show the start &amp; end points<\/span>\r\ngeoshow(ax,42.271, -70.857,<span class=\"string\">'DisplayType'<\/span>, <span class=\"string\">'point'<\/span>, <span class=\"string\">'MarkerSize'<\/span>,20,<span class=\"string\">'LineWidth'<\/span>,4,<span class=\"string\">'Marker'<\/span>, <span class=\"string\">'v'<\/span>);\r\ngeoshow(ax, 42.053, -70.189,<span class=\"string\">'DisplayType'<\/span>, <span class=\"string\">'point'<\/span>, <span class=\"string\">'MarkerSize'<\/span>,20,<span class=\"string\">'LineWidth'<\/span>,4,<span class=\"string\">'Marker'<\/span>, <span class=\"string\">'h'<\/span>);\r\n\r\n\r\n<span class=\"comment\">%T.Timestamps = T.Timestamps + hours(4); % adjust recorded timezone offset<\/span>\r\ndrivingOver = T.Timestamps &lt; datetime(2017,5,12,14,30,0);\r\ndriveData = T(drivingOver,:);\r\ndrivePath = geoshow(ax, driveData.Latitude, driveData.Longitude,<span class=\"string\">'DisplayType'<\/span>, <span class=\"string\">'line'<\/span>, <span class=\"string\">'LineWidth'<\/span>,3,<span class=\"string\">'LineStyle'<\/span>,<span class=\"string\">':'<\/span>,<span class=\"string\">'Color'<\/span>,<span class=\"string\">'red'<\/span>);\r\n\r\nraceData = T(~drivingOver,:);\r\ngeoshow(ax,  raceData.Latitude(end), raceData.Longitude(end),<span class=\"string\">'DisplayType'<\/span>, <span class=\"string\">'point'<\/span>, <span class=\"string\">'MarkerSize'<\/span>,20,<span class=\"string\">'LineWidth'<\/span>,4,<span class=\"string\">'Marker'<\/span>, <span class=\"string\">'o'<\/span>);\r\nracePath = geoshow(ax, raceData.Latitude, raceData.Longitude,<span class=\"string\">'DisplayType'<\/span>, <span class=\"string\">'line'<\/span>, <span class=\"string\">'LineWidth'<\/span>,3);\r\n\r\nlegend([drivePath, racePath], {<span class=\"string\">'Drive from TMW'<\/span>, <span class=\"string\">'Race Path'<\/span>})\r\n\r\n<\/pre><p>Cheer us on! I'll try to check back in from time to time during the race to see how things are working.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_5a54cf49a3e146a594ff2fd0806a5e5e() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='5a54cf49a3e146a594ff2fd0806a5e5e ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 5a54cf49a3e146a594ff2fd0806a5e5e';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2017 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_5a54cf49a3e146a594ff2fd0806a5e5e()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2017a<br><\/p><\/div><!--\r\n5a54cf49a3e146a594ff2fd0806a5e5e ##### SOURCE BEGIN #####\r\n%%\r\n% *UPDATE:* We did it and it was a lot of fun! It looks like the tracking\r\n% worked out as well so that was fun to see. One slight hiccup was that we\r\n% ended up tracking more than 8000 points and ThingSpeak returns 8000\r\n% points per call. No biggie! We just needed to seperate out all our calls\r\n% to ThingSpeak to get all the data. The data is all there on the\r\n% ThingSpeak channel I just needed to update the visualization code. I've\r\n% included the updated version below to show all the points. I also\r\n% distinguished the drive from MathWorks HQ over to the start from the\r\n% actual course I took.\r\n%\r\n%%\r\n% Hi folks! Check it out!\r\n% <http:\/\/getinvolved.holeinthewallgang.org\/site\/TR?team_id=2870&fr_id=1262&pg=team\r\n% 11 MathWorkers and I>  are about to embark on a MathWorks adventure\r\n% running the 200(ish) miles of Cape Cod.  We start running at 2:30 PM\r\n% Eastern Standard Time tomorrow (Friday May 12th). It should be an\r\n% adventure, and we were excited to help with a great cause.\r\n%\r\n% I thought it would be fun to use a little MATLAB mobile goodness to\r\n% broadcast our progress in real time. Check it out and track us either\r\n% through <https:\/\/thingspeak.com\/channels\/261391 the ThingSpeak page> or\r\n% just on this page as the map below should be updated in real time.\r\n% \r\n% Hopefully I don't have any bugs, since I will be busy running and\r\n% supporting the other runners and it might be tough to fix any mistakes\r\n% I've made in the code. Remember, it's live folks!\r\n%\r\n% For reference, here is the code I will be running from my iPhone using\r\n% the\r\n% <\r\n% MATLAB Support Package for Apple iOS Sensors> to send my GPS data. Note I\r\n% will be doing this from an instance of\r\n% <https:\/\/www.mathworks.com\/products\/matlab-mobile.html#connect-to-the-cloud\r\n% MATLAB in the cloud>. Awesome! Here's the function. It just takes the\r\n% instance of\r\n% <\r\n% mobiledev>:\r\n%\r\n% <include>trackTheFouriers.m<\/include>\r\n%\r\n% Also, here is the visualization code I used to plot our course\r\n% continually during the race:\r\n%\r\n% <include>mapItAndVisualize.m<\/include>\r\n%\r\n% Cheer us on! I'll try to check back in from time to time during the race\r\n% to see how things are working.\r\n##### SOURCE END ##### 5a54cf49a3e146a594ff2fd0806a5e5e\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/developer\/files\/iLzrUoX9demxKKr4v6mW6Q-1.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><!--introduction--><p><b>UPDATE:<\/b> We did it and it was a lot of fun! It looks like the tracking worked out as well so that was fun to see. One slight hiccup was that we ended up tracking more than 8000 points and ThingSpeak returns 8000 points per call. No biggie! We just needed to seperate out all our calls to ThingSpeak to get all the data. The data is all there on the ThingSpeak channel I just needed to update the visualization code. I've included the updated version below to show all the points. I also distinguished the drive from MathWorks HQ over to the start from the actual course I took.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/developer\/2017\/05\/11\/the-fast-and-the-fouriers\/\">read more >><\/a><\/p>","protected":false},"author":90,"featured_media":968,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[18],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/955"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/users\/90"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/comments?post=955"}],"version-history":[{"count":11,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/955\/revisions"}],"predecessor-version":[{"id":967,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/955\/revisions\/967"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/media\/968"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/media?parent=955"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/categories?post=955"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/tags?post=955"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}