June is an exciting month. Not only because of personal/family changes, but I am launching a pet project that I’ve called SetInMotion – something that I’ve worked on little by little over the course of the last couple of years. It’s been the “go-to” weekend project for a while now. It’s been an interesting road, but it’s nearly functional enough to let it out in the wild and see what folks can do with it and figure out if it’s a hit.
So what is it?
Over the last couple years I’ve always loved doing short projects with hardware. At work, I do prototyping projects a lot, at home, I drive my wife crazy by automating the house, and on the weekends I volunteer at church with kids. Software is magical – it affords endless possibilities for “I wish I could…” scenarios, and changes are only a line of code away. Hardware is another story. The final straw when I decided it was time for SetInMotion was the quarter shooter project.
I forget what the fundraiser was – but kids were bringing quarters to raise money for a good cause. I decided it would be much more fun if the kids could drop quarters into something that does something exciting with them. What’s more fun than projectiles? So, I created a “quarter shooter” that used the following components:
- A PC, so I could trigger when to “shoot” quarters (safety first!)
- A quarter “gun” made out of plexiglass, nuts and bolts, and an air compressor
- A train horn solenoid (basically an air cutoff switch that electronically opens/shuts the air hose)
- An Arduino that received the “trigger” messages from the PC, and activated the air solenoid to shoot the quarter
Simple enough, right? I spent a couple hours building the actual “shooter”, got it working, and then all I had left to do was the software. I ended up in a software cycle that is probably quite familiar to a lot of people:
- Write the Arduino microcontroller code to turn a pin off and on when a trigger message is received.
- Write the PC application that sends the trigger message.
- Test it together. It works!
- Refactor the Arduino code since it randomly stops working when PC messages have a certain end-of-line character or something.
- Test it again. Working!
- Stand back and realize that it needs sounds to make it more exciting.
- Find media player library for .NET and the sound effect I want.
- Integrate sound effect into application. That’s better, now quarters shoot with a satisfying “launch” sound effect.
- Realize that the “launch” sound would be much better if it were played through a big sound system instead of little laptop speakers.
- I can’t move the laptop to the sound system because it has to be connected to the Arduino 50 ft away. There is already a PC connected to the sound system. So I just need a way to trigger the sound to come from that PC.
- Move media player code to PC with the sound system with some sort of a “remote agent” functionality (sockets, remoting, or WCF or something, can’t remember).
- Find bug in communication to the remote agent.
- Redeploy both applications every time I want to re-test.
- Stand back and realize that I wish I could trigger it from my phone.
- Write embedded web server in trigger application.
- Spend next couple hours writing and debugging HTTP handlers and mobile web pages.
- Make sure my phone is connected to the same Wi-Fi network, and I’m in business. Awesome!
- Stand back and realize that it really needs some lighting effects to go along with it when the quarter shoots.
- Forget it, it’s midnight.
Now, that took all day. For all that work, all I got was a sound effect and a command sent to an Arduino. I searched around for show control systems that solved the problem. There was nothing flexible enough that allowed me to do what I wanted, or didn’t allow me to integrate with it the way I wanted.
I decided that I would never again end up in this cycle, where I spend way too much time fighting the plumbing of it all – I needed a flexible framework and platform that let me write specific “plugins” for hardware interactions, and then just let it take care of the rest. This is when SetInMotion was born.
So to answer the question – SetInMotion is a modular platform that connects devices to your PCs and the cloud, and allows you to easily design interactions with them.
SetInMotion brings devices into a common ‘Channel’ concept, and allows you to create virtual controls for those channels, as well as define triggers and actions.
In order to create a common language for all devices, SetInMotion revolves around a “Channels” and “Channel Properties” concept. Most devices, input and output, can be represented in this way. Let’s take a joystick, for example:
MyJoystick (the channel)
- PositionX (a channel property) = 38%
- PositionY (a channel property) = 52%
- Button1 (a channel property) = Off
… or a dimmable desk lamp as an output:
- Intensity = 42%
That’s great, but why do I care about Channels?
The power of SetInMotion begins with the control of those channels. Channels can be controlled in the following ways:
- A virtual on-screen control (like a fader or button).
- A channel action can cause a channel’s values to change based on activity from another channel (for example, have PositionX from the Joystick assign the Desk Lamp’s Intensity, so that moving the joystick controls the desk lamp’s brightness).
- A sequence script can set them (there’s a lot of scripting support built-in).
- Another app or PC connected to the cloud can change it.
The cloud, you say?
Things really get powerful when the cloud gets involved. The SetInMotion Cloud allows multiple machines, devices, and apps to connect to the same SetInMotion Show.
Let’s say my desk lamp is in New York, and I want my other machine in Los Angeles to control it. Spin up SetInMotion on the Los Angeles machine, connect the two machines to the same Cloud Show, and both machines see the MyLamp channel and it becomes available for control. No firewall tricks – all of the relaying is done in the cloud.
In addition, any device or app that could access a URL similar to this:
… would set the lamp to 98% intensity. When you can interact with your devices via a URL, the world opens up. There are endless possibilities with the cloud API.
What good is a platform like this if you can’t make your own custom plugins? Any .NET developer can make a SetInMotion plugin for a new device or scriptable command, and even publish it for others to use if they wish. Want to use an Xbox Controller as an input device to trigger sound effects, control lighting devices, or do something else crazy? A couple clicks and you have the Xbox Controller plugin. The more plugins developers share, the easier everything becomes.
There’s already a SetInMotion Plugin API on NuGet. I made a plugin tonight and it took less than 5 minutes from File > New to publish. For serious.
Feeling the hotness yet?
So now what?
There are a few more features to polish, some web site work to be done, and in the next couple days, all of the hundreds of thousands of people reading this eagerly will be able to get their hands on it. (OK, I really hope a few people give it a go at least.)
We have already used SetInMotion for quite a few projects, mostly private, but some public like the Christmas snowball machine. It has proven to be an incredible platform for scenarios both simple and complex. Can’t wait to share it with the world and get some initial feedback.
Preview release coming in the next couple days. If you got excited reading this and enjoy beta testing, shoot me an e-mail for the hook up.
I imagine there are a lot of ways a Migration installation on Win 8 could fail, but just to share my fix…
I did a Windows 8 Upgrade from Windows 7, and about 30% into the Migration phase, this error:
Setup has failed to apply migration data.
… Followed by a rollback to Windows 7.
This error tells you nothing – very frustrating. Look in the logs located in C:\$WINDOWS.~BT\Sources (surf around in there and you’ll find the log file that applies, possibly in the \Migration folder).
In my case, I noticed an entry that pointed to a Migration Error – it couldn’t move my desktop.ini file in my Music folder. It was looking for C:\Users\bpotter\Music\desktop.ini and couldn’t find it, failed the migration, and triggered a rollback.
I deleted the desktop.ini file (I don’t really care if I lose the folder view settings for my Music folder) and the install and migration completed successfully.
It’s been a little while since the last Christmas project, so it was time to do something again.
This year, I started out with the following criteria for the Christmas for the City display:
- Something interactive
- Something that gets more fun as more people join in
- Something that lets groups of people compete
The weekend before, my wife came home with a Nestle model train she got at a toy sale for $20:
This was great – trains and Christmas go together, and if the train could be driven by some input, we have the beginning of an interactive display. My plan at this point was to mount a series of industrial buttons, and wire them to a Netduino. The faster more kids pushed buttons, the faster the train would go.
However, I was running a little low on time at this point, so I needed something a little simpler. I was thinking of what might be possible while I was watching TV, and noticed my Kinect sitting under the TV. That was perfect. The more motion in front of the depth camera, the faster the train goes.
Using the Kinect library, I wrote a small app that grabbed each camera frame and passed it into an AForge.NET motion detection library. This gave me a motion analysis similar to this picture, where red areas represent “things that have moved in the last second or so”.
By counting the number of “motion pixels” each second, I ended up with what I coined to be the “motion number”. This could be 0 to 150,000 to 600,000 depending on how much motion was happening. I translated this into a percentage based on the max value seen since application start. So now we have a “motion percentage” from 0-100%. This will more or less serve as the value we need for the train throttle.
Mounting the Train
Trains, sensitive electronics, and anything else not bolted down or secured don’t last very long in front of kids, so in order to keep the train from being kicked, shoved, punched, or stolen, it needed some kind of enclosure.
For this I used some Bosch Aluminum Profiles – this stuff is amazing, we use it for just about everything. Our awesome distributor we use at work fabbed/cut pieces for me in a day and then it was off to the assembly area – the area between the couch and the dining room table.
This is also the point where I found out our new puppy hates portable drills..
OK, so one problem.
I set up the Nestle train and… it didn’t work. Either the engine or the controller didn’t work. Still not sure what the issue was, but I had come too far now to abandon this one.
This was Saturday. I had the rest of the night and Sunday to finish this thing. I called The Train Loft in Winston-Salem Saturday evening. They were closing in 15 mins but Jeff stayed late so I could come get another train. They had an amazing display – not something I was going to attempt:
Anyway, Jeff hooked me up with a Polar Express train set, and tricked up the track a little bit with a figure-8 instead of just the oval. Project officially over-budget at that point, but hey, Polar Express and Christmas go together, right?
Controlling the Train Throttle
What I thought was the easy part actually became the hardest. Turns out that train voltage is weird in a lot of ways (this train used AC, not DC), and controlling it via a computer is not that easy. I looked at various options for this, even trying to use an AC dimmer limited in software as to not overload the train. This got risky quickly, so I opted for a more simple mechanical control on the actual train controller. I pulled out the Lego Mindstorm NXT programmable controller and modified the train controller handle to attach to NXT…
While it looked cool, the “conveyor track” had a lot of slippage in it. Had to modify it further to couple the servo motor directly to the controller, and then I was in business.
Making it into a Game
So, now I had a “motion percentage” to use as a throttle value, a way to control the train via software, and a mounting rig.
Now, I just had to make it into a game. So I wrote an app with this workflow:
- Plays a Polar Express intro clip with the instructions (“move your body to make the train go”)
- Gives a 3, 2, 1 countdown
- For 30 seconds, enables Kinect, plays a Polar Express theme song while the train runs, displays the “motion percentage” in 0-400mph (yes, not really to scale, but hey…), and displays the “distance traveled” by the train
- After 30 seconds, stop train and display high scores (how far the train went in the 30 seconds)
I wrapped all that up, and our awesome Christmas for the City volunteers helped set up the rig at the convention center. Here are some pics of what it looked like:
Overall, this worked out great. It was a self-contained rig most of the time running one “round” every minute. Kids participated in nearly every round in the 6-hour period during the event. We had groups of kids competing, groups of adults competing, and a few “die-hards” with sweat pouring down their faces, and most of all a ton of smiles.
One of my favorite parts of the night was when one kid came over and played a few rounds, and then went to see Santa across the room and asked him for “a Polar Express dance game just like that one”.
All in all, I think I achieved the initial objectives, and combined some great hardware components together in a short amount of time!
Just for fun, I tested Big Buck Bunny being served through IIS Media Services from the local disk, running on an Amazon EC2 Micro instance (the smallest available). This is a fairly lightweight server, i.e. something you would never want to run in a production environment. Consider this the streaming equivalent of “Will it Blend?”…
The results are in – when it’s going well, it’s surprisingly great, and when it’s not going well, it’s terrible. ;)
Total Chunks: 2691
Chunks Tested: 2691
Manifest Download Time: 310ms
Avg Video Chunk Response Time: 357ms
Avg Audio Chunk Response Time: 61ms
Excellent Chunks: 590 (21.92%)
Good Chunks: 1821 (67.67%)
Warning Chunks: 68 (2.53%)
Degraded Chunks: 6 (0.22%)
Poor Chunks: 206 (7.66%)
Stream 0: video, 2962kbps, 2056kbps, 1427kbps, 991kbps, 688kbps, 477kbps, 331kbps, 230kbps
Stream 1: audio, 128kbps
Things go OK around 89% of the time. But when they don’t, it crashes and burns…
Yikes. You can almost feel the Silverlight players freaking out. ;)
If you are deploying a Smooth Streaming infrastructure, you already know it’s all HTTP-based. Requests for little video chunks hit your web server, and your web server looks up the correct video “chunk” within the audio/video file and serves it up.
However, it’s can be difficult to get a good benchmark on how your infrastructure is doing at serving up chunks, especially when your Silverlight clients are seeing random buffering errors or you run into scaling problems.
First off, there is a lot of information available from the Smooth Streaming Health Monitor app – In a couple seconds you can have a trace of what decisions the Silverlight Adaptive Streaming Media Element is making and export that out to Excel.
But when you just need comprehensive chunk data on all bitrates to diagnose how your origin/CDN is doing, I made this app (almost called it “Chunker”):
Enter the manifest URL of the on-demand smooth stream you want to test (note that this does not currently support live or composite manifests), for example: http://server.com/streams/BigBuckBunny.ism/Manifest
Once you click Begin Test, a new test tab will open and start requesting chunks based on the manifest information. The results will tell you if you may have a problem with your disk IO on your origin or some other problem preventing chunks being delivered in a timely manner.
Note: Only the first 1000 bytes (almost 1K) of each chunk is downloaded. The point here is not to test bandwidth, but rather test your infrastructure’s performance as it relates to reading/seeking fragments and assembling chunks.
Hopefully based on the assessment of each chunk, you can get an idea of how your CDN / origin / standalone box is doing at delivering chunks.
Run Smooth Stream Performance Testing Tool (ClickOnce)
I’ve gotten to the point where I don’t like #region tags in code – it’s what you do when you need to sweep some code under a rug.
As such, it’s really annoying to me when implementing an interface and VS generates nice #region tags all the time.
Props to this StackOverflow question/answer for the solution.
Tools > Options > Text Editor > C# > Advanced > uncheck “Surround generated code with #region”.
This one was a new one… I thought having to avoid toolbars bundled with the application I actually wanted was the punishment, but here’s a new one: When I unchecked “Install the new Bing Bar”, the Next button actually turned into a disabled 30-second countdown!
I guess this is a new technique… Punish with Patience. ;)