Kinecting The Dots-Developing with the Kinect SDK at Tech.Ed Australia

blogBling_150x150_02 Just had confirmation one of my submissions for Tech Ed Australia has been approved so I’m quite excited as I’ll be doing a session on the Microsoft Kinect SDK Beta.

We’ll be giving the session while we’re in New York in a few weeks at the N3UG and Alt.Net Group so should be nice and polished by the time the Aussies get to see it in action Smile

 

Stayed tuned for more info on rooms etc. but to wet your appetite a bit here’s the official blurb:KinectSensor_thumb

Kinecting The Dots – Developing with the Kinect SDK

The Microsoft Kinect holds the Guiness World Record as the fastest-selling consumer electronics device ever, selling 8 million units in the first 2 months.

With the recent release of the official SDK, you are the controller, with the ability to change the face of future applications.

Learn how to take advantage of depth sensing, skeletal tracking and sound source localisation in a sub $200 device in your next project using your current .Net skills.

When: 31 Aug 15:30-16:45

Technorati Tags: ,

Solar Panels 1 Year on-how much have we saved?

solarOver the weekend I reached my 1 year anniversary of having my 6 KWh solar system installed at home so I thought it’d be nice to work out how much we’ve saved. In 12 months we generated 9044 KWh which is around 24 KWh / day which I thought was pretty good considering the number of very overcast and wet days we’ve had in the last 12 months. My best output this year was a day that we generated 43 KWh but it was the most perfect, blue, non-cloudy and not too hot day I’ve ever seen so I’m not expecting that to ever happen again.

We use about 12 KWh per day so it’s great that we’re generating about twice the power we need and it means the electricity company gets to send me a cheque at the end of each quarter. The first read they did after the solar was installed they came back a second time just to double check Smile

So that’s the money side..but how much of the environment does that save? There weren’t too many Australian calculators so I’ll give the figures from two I found:

Carbon Neutral – which allows you to enter the number of KWh and the state says that 9044 KWh is equivalent to 9.22 Tons of CO2 emissions.

Small Business Carbon Footprint Calculator – which only allows you to enter the number of KWh says 9044 KWh is 10.10 tons of emissions and equivalent to having 60.6 trees.

It’ll be interesting to see how we fair over coming years to see if panels consistently generate that kind of power.

 

Technorati Tags: ,

Skeleton Custom Control for Kinect SDK WPF

I’ve been using the Microsoft Research SDK for Kinect for a little over a week in my spare hours, it is tonnes of fun and so much more stable then the previous frameworks I had been using. One thing that I think everyone will want to do is show a nice skeleton of up to two people being tracked by the Kinect.

image

I’ve created a Custom WPF Control ready for you to use or to style to your taste in Blend. It uses András Velvárt Bone Behaviour to create awesome little bones between the tracked joints.

So how do you use it?

Step 1 – Add a reference to your WPF project to the following:

  • Microsoft.Research.Kinect.dll – this is the core dll for using the Kinect SDK
  • System.Windows.Interactivity.dll – this comes with Blend 4, you will want the .Net version (not silverlight) to allow the behaviours to work
  • Coding4Fun.Kinect.Wpf.dll – the guys from channel9/Coding4Fun have a little helper, I use the scaleto method.
  • SoulSolutions.Skeleton.dll – the custom control itself

Step 2 – Open up your xaml page and reference the controls namespace

xmlns:s="clr-namespace:SoulSolutions.Kinect.Controls.Skeleton;assembly=SoulSolutions.Kinect.Controls.Skeleton"

Step 3 – Add an instance of the control to your page (or two)

<s:SkeletonControl x:Name="skeleton" />

Step 4 – Wireup the Kinect’s events to your skeleton(s)

in your code behind wire up the SkeletonData on the SkeletonFrameReady event (Full code sample at the end if this isn’t familiar)

private void NuiSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
    SkeletonFrame allSkeletons = e.SkeletonFrame;

    //get the first tracked skeleton
    skeleton.SkeletonData = (from s in allSkeletons.Skeletons
                        where s.TrackingState == SkeletonTrackingState.Tracked
                        select s).FirstOrDefault();
}

Making it look awesome in Blend

The control is ready for you to style in Blend (or Visual Studio if you’re a code ninja). The simple properties wire up in the default template are:

  • Foreground – wired up to the Fill on the 20 Ellipses tracking the joints, default is a B&W gradient
  • BoneFill – wired up to the Fill on the Bones that link the joints, default is light gray
  • Width – need to explicitly set a width in this version, default is 640
  • Height – again need to explicitly set a height, default 480
  • Background
  • BorderBrush
  • BorderThickness

Don’t stop here, simply make a copy of the default template and modify to your taste:

image

Add more then one

This is where it all starts to make sense, drop two on your page, wire up the second skeleton to the second tracked user, ready for some Red vs Blue Kinect Skeleton combat?

Some basic Poses

Looking for your help and pushing this into a more collaborative project, it does make sense for your skeleton to know about it’s current pose, I’m not sure ultimately the best best approach on this but I’ve included 7 poses I used at a recent event to control a 2.5 Gigapixel image:

  • Jump
  • LeftArmOut
  • RightArmOut
  • RightArmUp
  • LeftArmUp
  • Crouched
  • HandsTogether

Future Thoughts

I have kept this control very simple on purpose, I know people want something to start working with and to pull in their direction. Feel free to modify this code to your likely, love to know if you use it and what you do with it. These are the things I will be looking to improve on:

  1. It would be great to not have to specify the height and width, I need to do more testing to see if setting the control to the ActualHeight and ActualWidth works in all cases, let me know what i need to change if you spot it
  2. Bones don’t render in Blend design time.
  3. Bones behaviour doesn’t come across in the Blend “Edit a Copy”
  4. I’d like to simply bind the control to a skeleton data rather then having to write code behind, may need to write a little wrapper control for the Kinect and use element to element binding
  5. The whole Pose and Gesture thing is huge, I’ve seen two radically different approaches so far, look forward to seeing even more. I’d like to keep the skeleton separate somehow.

 

The code

Since you made it this far here are the two source code files written out and afterwards a link to download the full source with sample app. I will do my best to update the linked sourced code but these listing will not change:

Generic.xaml – the default template

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    xmlns:Skeleton="clr-namespace:SoulSolutions.Kinect.Controls.Skeleton">
    <Style TargetType="{x:Type Skeleton:SkeletonControl}">
        <Setter Property="Foreground">
            <Setter.Value>
                <LinearGradientBrush EndPoint="1,1" MappingMode="RelativeToBoundingBox" StartPoint="0,0">
                    <GradientStop Color="Black"/>
                    <GradientStop Color="White" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
        <Setter Property="BoneFill" Value="LightGray" />
        <Setter Property="Width" Value="640" />
        <Setter Property="Height" Value="480" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Skeleton:SkeletonControl}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <Canvas Name="MainCanvas" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" >
                            <Rectangle x:Name="NeckBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0">
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_ShoulderCenter" StartJointElementName="PART_Head"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="Spine" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0">
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_ShoulderCenter" StartJointElementName="PART_Spine"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="LowerSpine" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0">
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_HipCenter" StartJointElementName="PART_Spine"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="LCollarBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_ShoulderCenter" StartJointElementName="PART_ShoulderLeft"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="RCollarBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_ShoulderCenter" StartJointElementName="PART_ShoulderRight"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="RUpperArmBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_ElbowRight" StartJointElementName="PART_ShoulderRight"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="LUpperArmBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_ElbowLeft" StartJointElementName="PART_ShoulderLeft"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="RLowerArmBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_ElbowRight" StartJointElementName="PART_WristRight"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="LLowerArmBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_ElbowLeft" StartJointElementName="PART_WristLeft"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="RHandBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_HandRight" StartJointElementName="PART_WristRight"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="LHandBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_HandLeft" StartJointElementName="PART_WristLeft"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="LHipBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_HipCenter" StartJointElementName="PART_HipLeft"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="RHipBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_HipCenter" StartJointElementName="PART_HipRight"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="RUpperLegBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_KneeRight" StartJointElementName="PART_HipRight"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="LUpperLegBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_KneeLeft" StartJointElementName="PART_HipLeft"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="RLowerLegBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_KneeRight" StartJointElementName="PART_AnkleRight"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="LLowerLegBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_KneeLeft" StartJointElementName="PART_AnkleLeft"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="RFootBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_FootRight" StartJointElementName="PART_AnkleRight"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Rectangle x:Name="LFootBone" Fill="{TemplateBinding BoneFill}" Height="4" Width="10" StrokeThickness="0" >
                                <i:Interaction.Behaviors>
                                    <Skeleton:BoneBehavior EndJointElementName="PART_FootLeft" StartJointElementName="PART_AnkleLeft"/>
                                </i:Interaction.Behaviors>
                            </Rectangle>
                            <Ellipse x:Name="PART_Head" Fill="{TemplateBinding Foreground}" Height="40" Canvas.Left="90" Width="40"/>
                            <Ellipse x:Name="PART_HandLeft" Fill="{TemplateBinding Foreground}" Height="20" Canvas.Top="150" Width="20"/>
                            <Ellipse x:Name="PART_HandRight" Fill="{TemplateBinding Foreground}" Height="20" Canvas.Left="195" Canvas.Top="150" Width="20"/>
                            <Ellipse x:Name="PART_HipCenter" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="105" Canvas.Top="155" Width="10"/>
                            <Ellipse x:Name="PART_FootRight" Fill="{TemplateBinding Foreground}" Height="20" Canvas.Left="140" Canvas.Top="275" Width="20"/>
                            <Ellipse x:Name="PART_FootLeft" Fill="{TemplateBinding Foreground}" Height="20" Canvas.Left="65" Canvas.Top="275" Width="20"/>
                            <Ellipse x:Name="PART_AnkleLeft" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="75" Canvas.Top="255" Width="10"/>
                            <Ellipse x:Name="PART_AnkleRight" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="135" Canvas.Top="255" Width="10"/>
                            <Ellipse x:Name="PART_ElbowLeft" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="40" Canvas.Top="100" Width="10"/>
                            <Ellipse x:Name="PART_ElbowRight" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="165" Canvas.Top="100" Width="10"/>
                            <Ellipse x:Name="PART_HipLeft" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="75" Canvas.Top="170" Width="10"/>
                            <Ellipse x:Name="PART_HipRight" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="135" Canvas.Top="170" Width="10"/>
                            <Ellipse x:Name="PART_KneeLeft" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="75" Canvas.Top="215" Width="10"/>
                            <Ellipse x:Name="PART_KneeRight" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="135" Canvas.Top="215" Width="10"/>
                            <Ellipse x:Name="PART_ShoulderCenter" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="105" Canvas.Top="55" Width="10"/>
                            <Ellipse x:Name="PART_ShoulderLeft" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="70" Canvas.Top="65" Width="10"/>
                            <Ellipse x:Name="PART_ShoulderRight" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="140" Canvas.Top="65" Width="10"/>
                            <Ellipse x:Name="PART_Spine" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="105" Canvas.Top="130" Width="10"/>
                            <Ellipse x:Name="PART_WristLeft" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="20" Canvas.Top="135" Width="10"/>
                            <Ellipse x:Name="PART_WristRight" Fill="{TemplateBinding Foreground}" Height="10" Canvas.Left="185" Canvas.Top="135" Width="10"/>
                        </Canvas>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

SkeletonControl.cs

//This code is provided as is and with no warrentee. Use at your own risk, license is MS-PL, feel free to modifiy and use in your projects as needed.

#region

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Coding4Fun.Kinect.Wpf;
using Microsoft.Research.Kinect.Nui;

#endregion

namespace SoulSolutions.Kinect.Controls.Skeleton
{
    /// <summary>
    /// Kinect Skeleton for you to customise and simply drop into your projects and style in Blend.
    /// </summary>
    [TemplatePart(Name = PartHead, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartHandLeft, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartHandRight, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartHipCenter, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartFootRight, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartFootLeft, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartAnkleLeft, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartAnkleRight, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartElbowLeft, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartElbowRight, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartHipLeft, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartHipRight, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartKneeLeft, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartKneeRight, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartShoulderCenter, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartShoulderLeft, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartShoulderRight, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartSpine, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartWristLeft, Type = typeof (FrameworkElement))]
    [TemplatePart(Name = PartWristRight, Type = typeof (FrameworkElement))]
    public class SkeletonControl : Control
    {
        private const string PartHead = "PART_Head";
        private const string PartHandLeft = "PART_HandLeft";
        private const string PartHandRight = "PART_HandRight";
        private const string PartHipCenter = "PART_HipCenter";
        private const string PartFootRight = "PART_FootRight";
        private const string PartFootLeft = "PART_FootLeft";
        private const string PartAnkleLeft = "PART_AnkleLeft";
        private const string PartAnkleRight = "PART_AnkleRight";
        private const string PartElbowLeft = "PART_ElbowLeft";
        private const string PartElbowRight = "PART_ElbowRight";
        private const string PartHipLeft = "PART_HipLeft";
        private const string PartHipRight = "PART_HipRight";
        private const string PartKneeLeft = "PART_KneeLeft";
        private const string PartKneeRight = "PART_KneeRight";
        private const string PartShoulderCenter = "PART_ShoulderCenter";
        private const string PartShoulderLeft = "PART_ShoulderLeft";
        private const string PartShoulderRight = "PART_ShoulderRight";
        private const string PartSpine = "PART_Spine";
        private const string PartWristLeft = "PART_WristLeft";
        private const string PartWristRight = "PART_WristRight";
        public static readonly DependencyProperty BoneFillProperty = DependencyProperty.Register("BoneFill", typeof (Brush), typeof (SkeletonControl), null);

        private FrameworkElement ankleLeftUi;
        private FrameworkElement ankleRightUi;
        private FrameworkElement elbowLeftUi;
        private FrameworkElement elbowRightUi;
        private FrameworkElement footLeftUi;
        private FrameworkElement footRightUi;
        private FrameworkElement handLeftUi;
        private FrameworkElement handRightUi;
        private FrameworkElement headUi;
        private FrameworkElement hipCenterUi;
        private FrameworkElement hipLeftUi;
        private FrameworkElement hipRightUi;
        private FrameworkElement kneeLeftUi;
        private FrameworkElement kneeRightUi;
        private FrameworkElement shoulderCenterUi;
        private FrameworkElement shoulderLeftUi;
        private FrameworkElement shoulderRightUi;
        private SkeletonData skeletonData;
        private FrameworkElement spineUi;
        private FrameworkElement wristLeftUi;
        private FrameworkElement wristRightUi;

        static SkeletonControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof (SkeletonControl), new FrameworkPropertyMetadata(typeof (SkeletonControl)));
        }

        public Brush BoneFill
        {
            get { return (Brush) GetValue(BoneFillProperty); }
            set { SetValue(BoneFillProperty, value); }
        }

        public SkeletonData SkeletonData
        {
            get { return skeletonData; }
            set
            {
                skeletonData = value;
                SetUiPosition(headUi, skeletonData.Joints[JointID.Head]);
                SetUiPosition(handLeftUi, skeletonData.Joints[JointID.HandLeft]);
                SetUiPosition(handRightUi, skeletonData.Joints[JointID.HandRight]);
                SetUiPosition(hipCenterUi, skeletonData.Joints[JointID.HipCenter]);
                SetUiPosition(footRightUi, skeletonData.Joints[JointID.FootRight]);
                SetUiPosition(footLeftUi, skeletonData.Joints[JointID.FootLeft]);
                SetUiPosition(ankleLeftUi, skeletonData.Joints[JointID.AnkleLeft]);
                SetUiPosition(ankleRightUi, skeletonData.Joints[JointID.AnkleRight]);
                SetUiPosition(elbowLeftUi, skeletonData.Joints[JointID.ElbowLeft]);
                SetUiPosition(elbowRightUi, skeletonData.Joints[JointID.ElbowRight]);
                SetUiPosition(hipLeftUi, skeletonData.Joints[JointID.HipLeft]);
                SetUiPosition(hipRightUi, skeletonData.Joints[JointID.HipRight]);
                SetUiPosition(kneeLeftUi, skeletonData.Joints[JointID.KneeLeft]);
                SetUiPosition(kneeRightUi, skeletonData.Joints[JointID.KneeRight]);
                SetUiPosition(shoulderCenterUi, skeletonData.Joints[JointID.ShoulderCenter]);
                SetUiPosition(shoulderLeftUi, skeletonData.Joints[JointID.ShoulderLeft]);
                SetUiPosition(shoulderRightUi, skeletonData.Joints[JointID.ShoulderRight]);
                SetUiPosition(spineUi, skeletonData.Joints[JointID.Spine]);
                SetUiPosition(wristLeftUi, skeletonData.Joints[JointID.WristLeft]);
                SetUiPosition(wristRightUi, skeletonData.Joints[JointID.WristRight]);
            }
        }


        //*EXPERIMENTAL*//
        //Poses to build on need more models to verify correct, works well for 6foot4 Male :)
        //Smaller children have already proved these values need to be changed to be proportional rather then absolute.

        public bool Jump
        {
            get { return SkeletonData.Joints[JointID.FootLeft].Position.Y > -0.7 && SkeletonData.Joints[JointID.FootRight].Position.Y > -0.7; }
        }

        public bool LeftArmOut
        {
            get { return ((SkeletonData.Joints[JointID.HandLeft].Position.X - SkeletonData.Joints[JointID.ShoulderLeft].Position.X) < -0.5); }
        }

        public bool RightArmOut
        {
            get { return ((SkeletonData.Joints[JointID.HandRight].Position.X - SkeletonData.Joints[JointID.ShoulderRight].Position.X) > 0.5); }
        }

        public bool RightArmUp
        {
            get { return ((SkeletonData.Joints[JointID.HandRight].Position.Y - SkeletonData.Joints[JointID.Head].Position.Y) > 0); }
        }

        public bool LeftArmUp
        {
            get { return ((SkeletonData.Joints[JointID.HandLeft].Position.Y - SkeletonData.Joints[JointID.Head].Position.Y) > 0); }
        }

        public bool Crouched
        {
            get { return (Math.Abs(SkeletonData.Joints[JointID.FootLeft].Position.Y - SkeletonData.Joints[JointID.HandLeft].Position.Y) < 0.2); }
        }

        public bool HandsTogether
        {
            get
            {
                return (Math.Abs(SkeletonData.Joints[JointID.HandRight].Position.Y - SkeletonData.Joints[JointID.HandLeft].Position.Y) +
                        Math.Abs(SkeletonData.Joints[JointID.HandRight].Position.X - SkeletonData.Joints[JointID.HandLeft].Position.X) < 0.3);
            }
        }

        public override void OnApplyTemplate()
        {
            headUi = GetTemplateChild(PartHead) as FrameworkElement;
            handLeftUi = GetTemplateChild(PartHandLeft) as FrameworkElement;
            handRightUi = GetTemplateChild(PartHandRight) as FrameworkElement;
            hipCenterUi = GetTemplateChild(PartHipCenter) as FrameworkElement;
            footRightUi = GetTemplateChild(PartFootRight) as FrameworkElement;
            footLeftUi = GetTemplateChild(PartFootLeft) as FrameworkElement;
            ankleLeftUi = GetTemplateChild(PartAnkleLeft) as FrameworkElement;
            ankleRightUi = GetTemplateChild(PartAnkleRight) as FrameworkElement;
            elbowLeftUi = GetTemplateChild(PartElbowLeft) as FrameworkElement;
            elbowRightUi = GetTemplateChild(PartElbowRight) as FrameworkElement;
            hipLeftUi = GetTemplateChild(PartHipLeft) as FrameworkElement;
            hipRightUi = GetTemplateChild(PartHipRight) as FrameworkElement;
            kneeLeftUi = GetTemplateChild(PartKneeLeft) as FrameworkElement;
            kneeRightUi = GetTemplateChild(PartKneeRight) as FrameworkElement;
            shoulderCenterUi = GetTemplateChild(PartShoulderCenter) as FrameworkElement;
            shoulderLeftUi = GetTemplateChild(PartShoulderLeft) as FrameworkElement;
            shoulderRightUi = GetTemplateChild(PartShoulderRight) as FrameworkElement;
            spineUi = GetTemplateChild(PartSpine) as FrameworkElement;
            wristLeftUi = GetTemplateChild(PartWristLeft) as FrameworkElement;
            wristRightUi = GetTemplateChild(PartWristRight) as FrameworkElement;
            base.OnApplyTemplate();
        }

        private void SetUiPosition(FrameworkElement ui, Joint joint)
        {
            if (ui != null && ActualWidth > 0 && ActualHeight > 0)
            {
                var scaledJoint = joint.ScaleTo((int) ActualWidth, (int) ActualHeight, 1f, 1f);
                Canvas.SetLeft(ui, scaledJoint.Position.X - ui.ActualWidth/2);
                Canvas.SetTop(ui, scaledJoint.Position.Y - ui.ActualHeight/2);
            }
        }
    }
}

Download the code here.

Comments, Suggestions, Feedback? Catch me on twitter @soulsolutions

Some Kinect Fun with QLD Mosaic

IMG_8452

A month or so ago John entered a massive deep zoom mosaic – Mosaic of Queensland – into the Library Hack 2011 competition. He was invited to exhibit the entry at the announcement party on Friday held at The Edge. Rather than get the attendees to explore the 2.5 Gigapixel DeepZoom using a mouse he decided it’d be fun to hook it up to the Kinect and get them all actively navigating using their bodies.

He hooked up a bunch of poses using the Kinect SDK that would allow users to navigate up, down, left, right, zoom in, zoom out and a quick reset using a big range of motion. The skeletal points and joining lines are overlayed on the mosaic so the attendees could see what the Kinect thought they were doing. I made up a nice sign explaining what the poses were and what they did but everyone that had a go just walked straight past and went with trail and error instead.

IMG_8448

We ended up turning the Kinect around as we were having a few issues with people walking in front of the person playing and it tracking/interfering with what was going on.

We had a bunch of people have a go throughout the event but the children at the event were by far the most enthusiastic about having a go, experimenting with the gestures and just having some fun. It worked really well on all that tried it except for Anna, who was about 8. It seemed that our user testing using our adult sized arms didn’t quite cater for her small sized child arms for panning left and right but she would find ways to work around that and still have lots of fun.

IMG_8454IMG_8463IMG_8471IMG_8474IMG_8475

I’ve got a quick video of one of the attendees navigating around with the Kinect below.

 

My first Windows Phone 7 application-it’s all about us!

173pxWhiteOnBlack

I wanted to put together a simple Windows Phone 7 application that I could put through the marketplace just so I can go through the process of getting an application submitted, approved and up on the marketplace. I decided to build an application “about us” so I used Nick and Dave’s Social Viewer Template to pull together our blog posts, twitter mentions, You Tube videos etc. into one application.

I used the latest released version and it was really simple to add the feeds that I wanted to show. As is the way when you’re graphically challenged, I think it took me longer to get the icons, backgrounds and splash screen images etc. how I wanted them. The thing that drove me nuts thinking I’d done something wrong was my Application Icon. For the life of me I couldn’t get my highlight colour to show up on it thinking we’d done something wrong with the output of the image only to find the hightlight colour doesn’t come through for this version.

If you want to check out the application, you can download it from HERE.

screenshot1screenshot2

The next biggest hurdle for me was to actually submit the application. Not sure if it was because I was submitting on a Monday but it took me about 6 attempts to get all of the images (which are all tiny) up on the site so I could submit the application. The site kept randomly giving out errors and was quite frustrating. After it was submitted, it made it through certification after 2 days and then took another day to actually appear on the marketplace. So if you have a deadline coming up, even if your application makes it through first time you need to give yourself a few days before it actually appears.

 

NuGet Package: Reference unable to find assembly compatible with target framework

nugetI was playing with my first NuGet package install today as I tried out Jake’s Windows Phone MVC framework and hit my first error: Unable to find assembly references that are compatible with the target framework ‘Silverlight,Version=v4.0,Profile=WindowsPhone’.

Turns out the package is built for the Mango bits (which uses SL4) while I’m still running the “original” bits (uses Silverlight 3 and a bit).

Technorati Tags: ,,

Kinecting The Dots-Developing with the Kinect SDK at Alt.Net New York

altnetny

I’ll be in New York in July for the Imagine Cup 2011 Software Design finals and while we’re there we are fortunate to be able to present at some local user groups. We’ll be presenting on the newly released Microsoft Kinect SDK at the New York Alt.Net group. We’re pretty excited to be able to show off features in the SDK Beta that was released yesterday and looking forward to meeting some locals while we’re there.

 

 

 

KinectSensorThe official blurb:

Kinecting The Dots – Developing with the Kinect SDK

The Microsoft Kinect holds the Guiness World Record as the fastest-selling consumer electronics device ever, selling 8 million units in the first 2 months.

With the recent release of the official SDK, you are the controller, with the ability to change the face of future applications.

Learn how to take advantage of depth sensing, skeletal tracking and sound source localisation in a sub $200 device in your next project using your current .Net skills.

Meeting Details

When: Tuesday, July 19, 2011 6:30 PM

Where: EMC/VMWare/SpringSource NYC offices – 2 Penn Plaza New York, NY

How to register: Head to the Meetup site and register here

 

Finalist Judging for Imagine Cup 2011 in New York

ic2011    I have been very fortunate again this year to be to be involved with Imagine Cup as one of many round judges for Game Design and have been selected as one of the finalist judges for Software Design.  I was involved last year in the Software Design finals, held in Poland in 2010, which was an awesome experience! The energy, enthusiasm and the actual solutions that were presented were overwhelming! Here you had finalist teams from over countries all over the world truly tackling some of the world’s biggest problems. Listening to the students presentations, motivations and how their software had actually changed people’s lives was really a touching experience. I’m really excited to see what the students come up with this year as well as checking out all the Game Design finalists!

 

Technorati Tags: ,

Microsoft Kinect SDK-Could not load file or assembly INuiInstancHelper.dll

KinectSensor

I was excited to see the official Microsoft Kinect SDK released today! If you haven’t checked it out yet I recommend heading to the official site and giving it a go.

After I downloaded all the bits and did all the installs without issues I was keen to check out the skeletal tracking samples and that’s where I hit my first roadblock. I had two errors consistently across any projects needing to track my movements:

1. “Could not load file or assembly ‘INuiInstanceHelper.dll’ or one of it’s dependencies. The specified module could not be found.”

2. “The invocation of the constructor on type “xxxx” that matches the specified binding constraints threw and exception.’ Line number ‘2’ and line position ‘9’.”

Seems I wasn’t the only one when I checked the forums.

I checked that I had the dlls, that there were in my gac i.e

C:\Windows\system32>gacutil /l INuiInstanceHelper
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.

The Global Assembly Cache contains the following assemblies:
  INuiInstanceHelper, Version=1.0.0.10, Culture=neutral, PublicKeyToken=31bf3856
ad364e35, processorArchitecture=x86

Number of items = 1

 

I’d done all the other usual things, like reboot, open/close visual studio, make sure I could see Kinect in device manager etc. So how did I fix it?

1. I uninstalled the INuiInstanceHelper from the GAC using gacutil /u

2. then rebooted (to make sure)

3. reinstalled to gac with gacutil /i

 

And it’s all happy now. That fixed both of the issue above. Hope this helps someone else.