Welcome to MSDN Blogs Sign in | Join | Help

I just burned an hour chasing down a JSON serialization issue in .NET 3.5.  Watch out for trying to serialize DateTime values that are MaxValue or MinValue.  This is an issue whether you are using the DataContractJsonSerializer directly or if you are using a WebInvoke with response formatting set to Json.  The latter can be much trickier to detect.

The following line of code was my problem:

        // This will hose you in when using WCF's DataContractJsonSerializer
        flight.ActualArrivalTime = DateTime.MaxValue;

I stepped through to find this dialog below.  
JSONError 
After removing MaxValue, it worked fine.

In my last post, I described the maze generator I developed in C#.  This was trivial to build as to be expected.  The larger challenge for me was to learn enough about the simulator in MSRS 1.5 to build a 3D maze and let me virtual robot navigate through it. 

After a few more hours of development, I was able to integrate my maze generation library into the Robotics Studio 1.5 Simulator environment.  I had to learn some basics around the coordinate system, the physics engine, textures, etc. 

Creating the 3D Maze

The core code for generating the maze in the simulator is shown below.  It uses the Maze Library I built (discussed earlier).  The Start() method is overridden, as is normal, and adds the sky and the ground.  It then allocates a new Maze object and creates the maze layout.

        protected override void Start()
        {
            base.Start();
           
            AddSky();           // skydome and sun
            AddGround();        // basic ground

            float scale = 1.0f;
            float floorHeight = 0.03f;
            float wallWidth = 0.15f * scale;
            float wallHeight = scale;
           
            Maze maze = new Maze();     // Construct a maze object
            maze.Create(15, 15);                                // Initialize a new maze
            AddMaze(maze, scale, floorHeight, wallHeight, wallWidth);

            float robotX = maze.Finish.X * scale + (scale / 2);
            float robotY = 0.5f;
            float robotZ = maze.Finish.Y * scale + (scale / 2);

            AddModularRobot(new Vector3(robotX, robotY, robotZ));   // geometric Pioneer robot

            SetupCamera(robotX, robotY, robotZ, scale * 1.5f, robotZ + scale*3.0f);
        }

 

The AddMaze() method simply adds a base platform for the maze itself and then iterates over every cell and draws each enabled wall.

        private void AddMaze(Maze maze, float scale, float floorHeight, float wallHeight, float wallWidth)
        {
            if (maze == null) return;

            int width = maze.Width;
            int height = maze.Height;

            // Add a floor
            Vector3 dimensions = new Vector3(width * scale, floorHeight, height * scale);
            BoxShapeProperties tBoxShape = new BoxShapeProperties(1000000f, new Pose(), dimensions);
            tBoxShape.Material = new MaterialProperties("tbox", 0f, 0.3f, 0.3f);
            SingleShapeEntity tBoxEntity = new SingleShapeEntity(new BoxShape(tBoxShape), new Vector3(dimensions.X / 2, dimensions.Y / 2, dimensions.Z / 2));
            tBoxEntity.State.Assets.DefaultTexture = "wood_cherry.jpg";
            tBoxEntity.State.Name = "MazeFloor";
            SimulationEngine.GlobalInstancePort.Insert(tBoxEntity);

            // Iterate over the maze and add the object
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (maze.GetWall(x, y, WallFlags.Top)) DrawWall(maze, x, y, WallFlags.Top, floorHeight, wallHeight, wallWidth, scale);
                    if (maze.GetWall(x, y, WallFlags.Left)) DrawWall(maze, x, y, WallFlags.Left, floorHeight, wallHeight, wallWidth, scale);
                    if (maze.GetWall(x, y, WallFlags.Bottom)) DrawWall(maze, x, y, WallFlags.Bottom, floorHeight, wallHeight, wallWidth, scale);
                    if (maze.GetWall(x, y, WallFlags.Right)) DrawWall(maze, x, y, WallFlags.Right, floorHeight, wallHeight, wallWidth, scale);
                }
            }

            // Now we are done with this
            System.Diagnostics.Debug.WriteLine("Done with adding the maze.");
        }

The DrawWall() method calculates the dimensions and position of the wall, constructs a visual model and a physics model, and then adds it to the world.  Note that the positions of objects are the position of their center point, not a bounding corner.

        private void DrawWall(Maze maze, int x, int y, WallFlags wall, float elevation, float wallHeight, float wallWidth, float scale)
        {
            float x1 = x;
            float x2 = x;
            float y1 = y;
            float y2 = y;

            bool top = maze.GetWall(x, y, WallFlags.Top);
            bool left = maze.GetWall(x, y, WallFlags.Left);
            bool bottom = maze.GetWall(x, y, WallFlags.Bottom);
            bool right = maze.GetWall(x, y, WallFlags.Right);
            
            if (wall == WallFlags.Top) 
            { 
                x1 = x * scale; x2 = (x + 1) * scale; y1 = (y) * scale; y2 = y * scale + wallWidth;
                if (x < (maze.Width - 1))
                {
                    bool topLeftCornerSet = !maze.GetWall(x + 1, y, WallFlags.Top) && !maze.GetWall(x + 1, y, WallFlags.Left);
                    if (topLeftCornerSet) x2 += wallWidth;
                }
            }
            if (wall == WallFlags.Left) 
            {
                y1 = y * scale; y2 = (y + 1) * scale; x1 = (x) * scale; x2 = (x) * scale + wallWidth; if (top) y1 += wallWidth; 
            }

            // Now create the wall where it goes
            Vector3 dimensions = new Vector3(x2 - x1, wallHeight, y2 - y1);
            Vector3 position = new Vector3(x1 + dimensions.X/2, dimensions.Y/2 + elevation, y1+dimensions.Z/2);
            BoxShapeProperties tBoxShape = new BoxShapeProperties(1000f, new Pose(), dimensions);
            tBoxShape.Material = new MaterialProperties("tbox", 0.4f, 0.4f, 0.6f);
            tBoxShape.DiffuseColor = new Vector4(0.5f, 0.5f, 0.5f, 1.0f);
            SingleShapeEntity tBoxEntity = new SingleShapeEntity(new BoxShape(tBoxShape), position); ;
            tBoxEntity.State.Assets.DefaultTexture = "env2.bmp";
            tBoxEntity.State.Name = string.Format("Wall_{0}_{1}_{2}", x, y, wall);
            
            // Add the wall to the environment
            SimulationEngine.GlobalInstancePort.Insert(tBoxEntity);
        }

Running the Simulation

The initial loading of the simulation with the auto-generated maze puts the robot at the entrance.  The camera is set to look at the robot from behind.

 Startup screen with robot entering the maze

Zooming out you can see the dots from the laser range finder and what they hit.

 Zoomed out and above about 20 feet

This next view is from a camera mounted on the robot.  Notice the laser's reach and the potential for discovering the maze paths that way.

View from the robot's camera of the maze and the laser range finder results

The robotics dashboard used in this simulation allows you to drive the robot with the mouse or an XBOX controller.  You can also visualize the results from the laser range finder scans as shown at the bottom (in blue). 

Dashboard1

This screen shows a top-down view of the maze with the robot at the entrance.  I can generate arbitrarily complex mazes, such as a 100x100 maze, and it would be much larger. 

Top down view o the maze high enough to see it all

There are performance issues with the rendering and the physics calculations due to the way in which I construct the maze.  Each maze wall is a separate model with its own physics and rendering.  Rendering larger mazes degrades at an N^2 rate, so it's not too scalable.  I could have created one complicated shape from the surfaces of all of the connected walls, making the physics calculations constant.  I could also do some optimization of combining walls for cells that are side-by-side.  But I opted to make it more flexible for now.

The diagrams below show the maze at a distance with normal gravity. 

  View of the maze with an angle

The next picture shows the gravity inverted and the impact to all of the individual maze walls!

  Maze lifting up in the air due to inverted physics I added

I turned gravity back on and it came crashing to the ground-- the maze walls scattered like dominos on a falling table.  I thoroughly enjoyed this destruction for some reason.

 Maze crashing to the ground

Next Steps

This code is not complete.  I need to add a service to the robot which uses a wall-following approach to solve the maze.  This algorithm is simple but certainly non-optimal.  I'll explore more optimal solutions later.

So what about the source?  I'm checking with the Microsoft Robotics Team before I release it.  I expect to have this ready in less than a week for posting.  I'd like to add a Readme and some other stuff.

 

I was recently talking with Marc about some potentially interesting challenges in robotics programming that we could implement using the Microsoft Robotics Studio 1.5 Simulator.  We discussed a number of scenarios that ranged from simple to insanely hard.  One of the more approachable challenges he proposed involved having a simple, autonomous robot navigate through a maze. 

This has actually been explored within MSRS 1.5 by the community to various degrees.  Here is an impressive sample from Ben Axelrod that let's you load any image file and construct a 3D environment from it (including mazes if the image is that of a maze).  Trevor Taylor has expanded upon that sample and it's really quite impressive.  But while there are many interesting samples available for MSRS 1.5 which can be used to construct 3D environments from files, I didn't find anything that actually generated a maze. 

Maze Explorer in Windows Forms

I thought about the problem a few nights ago and decided it would be fun to develop an automated maze generator in C# and then to build a Maze Simulator sample for MSRS 1.5 that constructs this maze using 3D shapes within the Robotics Studio Simulator. I implemented a maze generator in a couple of hours using a depth-first search algorithm and very basic data structures in C#.  I built a class library for the maze itself and a viewer as a Windows Forms application. 

Some screen shots are below:

 MazeExplorer1 MazeExplorer2 MazeExplorer3

Maze Creation Algorithm

The depth-first-search algorithm I used goes something like this:

  1. Start at the exit cell (chosen at random on the edge)
  2. Set the current cell to visited.  For each neighbor, starting with a randomly selected neighbor:
    1. If this neighbor has not been visited, remove the wall between the current cell and the this neighbor
    2. Recursively call the Maze routine with this neighbor as the new current cell

I admit the code has not been optimized for execution time, space, or efficiency-- I just used a 2-dimensional array that represented walls with bit flags.  My algorithm also uses the stack, so it's sufficient for creating a 150x150 maze or so will work in release mode, but not much larger.  I could have stored backtracking in the maze output to remove the stack overflow problem in large mazes, but that's left as a future exercise.

Windows Form Client

I built a simple Windows Form client that display the maze bitmap that was generated.  I basically display an image inside a PictureBox, and I render to the image to reduce redraws.  I used rectangles for all walls because the 2D layout needs to map into the MSRS 1.5 3D Simulation environment.  Rendering in 2D with lines will not translate well into this 3D world.  There are some special cases in rendering in 2D which I handle when drawing certain walls, such as elongating them to compensate for empty corners, but this is for the rending only.

Next Steps

I'm working on implementing a Maze Simulation project for the MSRS 1.5 environment now.  I've basically taken one of the Simulation Tutorials and stripped it down for use.  I plan on adding the Maze class library to the project and then rendering the maze in 3D instead of 2D.  This will be a little tedious, especially given the duality of the visual and the physics engine layer.  When this is done, I'll add a virtual robot instance to the maze and allow it to navigate via the dashboard.

I found an interesting site with information of the origins of XYZZY in Adventure, and later Zork.  It's also use as a cheat code for a number of products in the market. So was "XYZZY" defined randomly, or does it have some deeper meaning?  You'll have to read on.

I'm in Redmond this week to do some work around Web Services management.  Right now I'm trying to finish my WSE 2.0 SP3 Performance Counter implementation.  Although there are performance counter implementations out there (here is one) for WSE, I need specific counters per service and per operation.  I'm also trying to use WSE 2.0 SP3 on Whidbey Beta 2 for this.

I did some searching for the DebuggerVisualizer topic, trying to find out if my post had been found yet.  It has been found, in fact, and in only a few hours.  During my searching, I also found a number of interesting links to solid work around debugger visualizers.  Scott Nonnenberg has an excellent blog with quite a few posts around this topic.  He's a PM on the Debugging group within Visual Studio.  Scott's building an index of debugger visualizer entries, and some of them are very compelling.  It turns out that an image debugger visualizer is somewhat rudimentary, as I expected.  Scott's site has links to a graphical XML visualizer from Howard van Rooijen that is very cool.

On another note, Seth Demsey has some interesting posts about the RSS Advertising Syndication.  This is a very interesting development, which could be either very good or very bad, depending on your perspective.

I have been working with Visual Studio 2005 Beta 2 quite a bit.  One of the more compelling debugging features in VS2005 Beta 2 is the ability to create new extensions to the debugger for supporting custom visualization of objects that are being inspected.  The basic object types in .NET are already supported by the debugger, but sometimes it can be useful to inspect an object type in a visually customized way, depending on the type of object.  Some examples might be:

  • Visualize business objects in a rich, application-specific manner
  • Visualize RegEx objects at debug time in a way that allows you to interact with them
  • Visualize an Image object at debug time that you might have loaded from disk or via a network call
  • Visualize a custom shape object type used in a 3D Game engine
  • Visualize Windows handle objects and examine details associated with them

Visual Studio 2005 allows you to extend your debugger's visualization capabilities by creating a new DebuggerVisualizer class.  This class simply registers itself with an appropriate assembly-level attribute, and when it is invoked by the debugger, it displays a custom form, control, or dialog that can render the passed type.  It must be installed in a specific subfolder at either the user or the machine level.  It's simple enough that you can build one in 5 minutes.

Building a DebuggerVisualizer in 5 minutes

While on the plane coming home from London this weekend, I built a debugger visualizer for Images.  I earlier read an article in DevX from Julia Lerman that was very helpful with regard to debugger visualizers in general.  There have been some minor changes since Beta 1 in this area, and the process seems to be even easier now.

There are only a few simple steps to building a basic debugger visualizer.  First, you create a new solution as a class library.  You then create a class that derives from DebuggerVisualizer, override it's Show() method, and add an assembly-level attribute that VS 2005 will look for when it starts a debugging session.  The next step is to create a custom Form object to display the object that is being inspected during debugging.  Finally, you compile it all and copy the assembly to a special directory.  That's it-- you can probably implement one in less than 5 minutes.  I will walk through the steps in detail now.  Alternately, you can download my project if you wish.

Step 1: Create a new project as a C# class library

Create a new project within Visual Studio 2005 Beta 2 as a C# class library with a name of GDIDebugVisualizers.  Delete the Class1.cs file that was added.

Step 2: Add a DebuggerVisualizer item to the project

Right-click on the new project and select Add -> New Item.  Choose the DebuggerVisualizer item type, and give it a name of ImageDebuggerVisualizer.cs.  The new class should look like the code block below:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Windows.Forms;
   4:  using Microsoft.VisualStudio.DebuggerVisualizers;
   5:   
   6:  namespace GDIDebuggerVisualizers
   7:  {
   8:      // TODO: Add the following to SomeType's defintion to see this visualizer 
   9:      //       when debugging instances of SomeType:
  10:      // 
  11:      //  [DebuggerVisualizer(typeof(ImageDebuggerVisualizer))]
  12:      //  [Serializable]
  13:      //  public class SomeType
  14:      //  {
  15:      //   ...
  16:      //  }
  17:      // 
  18:      /// <summary>
  19:      /// A Visualizer for SomeType.  
  20:      /// </summary>
  21:      public class ImageDebuggerVisualizer : DialogDebuggerVisualizer
  22:      {
  23:          protected override void Show(IDialogVisualizerService windowService, 
  24:                                       IVisualizerObjectProvider objectProvider)
  25:          {
  26:              // TODO: Get the object to display a visualizer for.
  27:              //       Cast the result of objectProvider.GetObject() 
  28:              //       to the type of the object being visualized.
  29:              object data = (object)objectProvider.GetObject();
  30:   
  31:              // TODO: Display your view of the object.
  32:              //       Replace displayForm with your own custom Form or Control.
  33:              using (Form displayForm = new Form())
  34:              {
  35:                  displayForm.Text = data.ToString();
  36:                  windowService.ShowDialog(displayForm);
  37:              }
  38:          }
  39:   
  40:          // TODO: Add the following to your testing code to test the visualizer:
  41:          // 
  42:          //    ImageDebuggerVisualizer.TestShowVisualizer(new SomeType());
  43:          // 
  44:          /// <summary>
  45:          /// Tests the visualizer by hosting it outside of the debugger.
  46:          /// </summary>
  47:          /// <param name="objectToVisualize">The object to display in the visualizer.</param>
  48:         public static void TestShowVisualizer(object objectToVisualize)
  49:          {
  50:              VisualizerDevelopmentHost visualizerHost = 
  51:                  new VisualizerDevelopmentHost(objectToVisualize, typeof(ImageDebuggerVisualizer));
  52:              visualizerHost.ShowVisualizer();
  53:          }
  54:      }
  55:  }

Step 3: Create an custom form for visualization

This is the most interesting part because it is where you render the debug-time object visually.  Simply add a new Form object to the project and call it ImageFormViewer.cs.  In the designer, change the FormBorderStyle to FormBorderStyle.SizableToolWindow.  Next add a PictureBox control to the new form, configure it's Dock property to DockStyle.Fill, and set it's SizeMode property to PictureBoxSizeMode.Zoom.  See the diagram below:

 

Finally, add a new property to this ImageFormViewer class called CurrentImage, implementing get and set in a way that directly returns the picturebox's Image object.  See the code snippet below:

   1:  public Image CurrentImage
   2:  {
   3:     get { return currentPicture.Image; }
   4:     set { currentPicture.Image = value; }
   5:  }

 

Step 4: Modify the code to use the new ImageFormViewer form

Remove the TODO comments after following the instructions, and add the logic to load the custom form.  You will somehow need to send the object itself to this form.  The end result should be something that looks like this:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Windows.Forms;
   4:  using System.Drawing;
   5:  using Microsoft.VisualStudio.DebuggerVisualizers;
   6:   
   7:  [assembly: System.Diagnostics.DebuggerVisualizer(
   8:   typeof(GDIDebuggerVisualizers.ImageDebuggerVisualizer), typeof(VisualizerObjectSource), 
   9:   Target = typeof(System.Drawing.Image), Description = "Image Visualizer")]
  10:   
  11:  namespace GDIDebuggerVisualizers
  12:  {
  13:      public class ImageDebuggerVisualizer : DialogDebuggerVisualizer
  14:      {
  15:          protected override void Show(IDialogVisualizerService windowService, 
  16:                                       IVisualizerObjectProvider objectProvider)
  17:          {
  18:              Image debugImage = objectProvider.GetObject() as Image;
  19:              if (debugImage != null)
  20:              {
  21:                  using (ImageViewerForm displayForm = new ImageViewerForm())
  22:                  {
  23:                      displayForm.CurrentImage = debugImage;
  24:                      DialogResult result = windowService.ShowDialog(displayForm);
  25:                      if (result == DialogResult.OK)
  26:                      {
  27:                          objectProvider.ReplaceObject(displayForm.CurrentImage);
  28:                      }
  29:                  }
  30:              }
  31:          }
  32:   
  33:         public static void TestShowVisualizer(object objectToVisualize)
  34:          {
  35:              VisualizerDevelopmentHost visualizerHost = 
  36:                  new VisualizerDevelopmentHost(objectToVisualize, typeof(ImageDebuggerVisualizer));
  37:              visualizerHost.ShowVisualizer();
  38:          }
  39:      }
  40:  }

 

Step 5: Compile and Deploy

You can install the new visualizer assembly at a user level or at a machine level.  For the user-level approach, copy the compiled assembly to:  My Documents\Visual Studio 2005\Visualizers.  For a machine-wide approach, copy the assembly to:  \Program Files\Microsoft Visual Studio 8\Common7\Packages\Debugger\Visualizers.  Once this has been copied, you are ready to debug.  In Beta 2, no restart is required because VS 2005 will check for the available visualizers every time you start a debug session.  Of course, you cannot change the list of registered Debugger Visualizers during a debug session.

Test with the Debugger

Testing simply requires that you start a debugging session and inspect an Image object.  The easiest way is to build a simple WinForm application with a PictureBox control configured at design-time to load an external bitmap file.  The result will look like the picture below:

 

Insert a breakpoint in the code, and start debugging.  When you hit the breakpoint, inspect the picturebox Image property by hovering over it.  There should be a magnifying glass icon that appears, with a drop-down associated for the new Debugger Visualization.  The screenshots below show this in action:

 

When you clock on the Image Visualizer in the drop-down menu, your new Debugger Visualizer is launched.  The screenshot below shows this using my implementation (I support a context menu for loading and saving images as well). 

 

Testing without Debugging

There is a way of testing out the visualizer without actually debugging by using an instance of VisualizerDevelopmentHost.  This class invokes the visualizer as if it were in a debugging session, and is for testing purposes.  The template-generated code from Lines 50-52 of the code for Step 2 implements this approach via a static method.  You can create a simple project in the same solution, add a project reference to the visualizer, and call the static method to test this out.  Don't forget to add a reference to the Microsoft.VisualStudio.DebuggerVisualizers assembly in this test project-- you need this reference because the visualizer depends on it. 

Other Notes

There are some important things to know about DebuggerVisualizer implementations.  I received some updates from Scott Nonnenberg as well

  • You can have one or more System.Diagnostics.DebuggerVisualizer attributes per assembly.
  • You need an instance of the System.Diagnostics.DebuggerVisualizer for every type your visualizer supports (can be multiple here).
  • You can have multiple debugger visualizers implemented within an assembly. 
  • This form implementation can be smart enough to handle different types which are semantically similar but taxonomically distinct.
  • You can support changes to the object by calling the ReplaceObject() method of the IVisualizerObjectProvider (examine the DialogResult first).

Next Steps

In any case, this was an interim step, and I am thinking about building more interesting debugger visualizers now.  The most compelling implementations to me would probably be some sort of Web Services debugger visualizer.  I will look around for other more sophisticated debugger visualizers when I get a chance.

This posting is provided "AS IS" with no warranties, and confers no rights.

U.K. Trip

I am currently flying back home after 6 days in the U.K.  I'm on a plane for 10 hours, so this is an ideal time for a blog entry.  I was there to collaborate with some of our internal team members and partners on an interesting project involving advanced Web Services.  It was a great trip and London is a great city.  I have been there a few times before, but this trip was long enough to appreciate it more than past visits.  Spending seven straight days away from home is something that I prefer to avoid, but I will be seeing Angie and Chloe tonight for dinner at least.

We had some great meetings, and I think all involved would certainly agree we made excellent progress.  I was also able to spend time at both the Microsoft office in Reading and the MSN office in the Soho district in London.  Much of my time was focused on technical pursuits involving Web Services and implementing performance counters in WSE 2.0 (I'll share details on my implementation soon).  I also worked with my MCS team on MOM 2005 integration for our Web Services demo.

"Lamb Coma"

We had an excellent dinner with one of our partners in Newbury at The Bunk Inn.  It was lots of fun, and the conversation was interesting.  Chung recommended I try the famous half lamb shoulder, so I did.  It was much larger than I expected, but I ate every last bit of the thing!  And then it set in-- the Lamb Coma! It was if I had failed "a savings throw versus paralysis" or something. I became instantly drowsy for about 15 minutes. When I emerged out of the Lamb Coma, the dinner conversation had become creative and a little whimsical.  I joined in this goofiness with a discussion around "wetware" implants and the Mouth Area Network.

Mouth Area Network

Those who have heard my pitch for the Mouth Area Network know that it's mostly tongue in cheek.  It is a form of a personal area network which seeks to implement intra-, inter-, and extra- mouth-area communications using pluggable computing modules which replace your teeth.  These modules are functionally and aesthetically equivalent to teeth, but offer much more value to end users (here is a diagram of your teeth).  Different oral modules provide storage, processing, communications, and IO.  These modules need to be integrated in some sort of mouth-wide network with a service bus architecture ideally.

We expanded on this concept during our dinner discussion.  We talked about a data storage module that would replace a first or second molar and that could be both upgradeable and support plug-and-play.  Bruce and I discussed supporting the idea of a short-range wireless communications unit that would simply replace a third molar (a.k.a. wisdom tooth).  We decided that this particular tooth unit would be a blue color.  We also discussed a line-of-sight module to replace one of your central incisors using a gold tooth with a diamond in it (diagram here)-- this could be very classy while providing infrared transfer services when you smile. 

I started thinking about using WS-* protocols to achieve the integration of the oral modules.  Perhaps I could implement some of the key WS-* protocols within a micro-CLR implementation from someone like Hive-Minded.  One of the most important scenarios is establishing trust between different mouths, and the need for a challenge/response protocol for establishing secure conversations in mouth-to-mouth (extranet) service integration.  Given these requirements, a robust Web services artchitecture is required.  Of course, I’m guessing at least some of you would like me to consider REST for this topic.

London Recommendations

On a more serious note, I have some recommendations for those visiting London.  St. Martins Lane, a hotel near Covent Garden and the West End theatres, is an excellent place!  The Light Bar, which is in the hotel, is a great place for geeks to gather to discuss deep topics while enjoying fine beverages.  The Red Fort is an amazing and high quality Indian restaurant in Soho.  The food was incredible, the atmosphere was ideal, and the variety was really good.  I definitely recommend it.

Working with Beta 2 of Visual Studio 2005

I pulled down Beta 2, and I am busy working through the changes since the last CTP.  Overall, this release seems much more polished than I expected.  I will be implementing some DebuggerVisualizers for the rest of this flight.

Introduction

I'm finally starting my blog. I have deferred this activity for a number of reasons, some of which were valid, but all of which were well formed.

 

For those who don't know me, I am an Architectural Consultant working for Microsoft within the Communications Sector, Consulting Services team. My team works with the Telecommunications, Media and Entertainment, and the Mobile industries.  I have been with Microsoft for 7

 

In my role as a customer-facing consultant, there are some great projects that I am exposed to. Unfortunately, I often cannot mention them publicly. In my role as a Microsoft architect working with various product teams, I am also involved in some very early efforts that are internal only. So the potential blog content has been squeezed from both sides -- too many secrets.

 

My current work has enough touch points and original thinking that I feel like I can possibly provide the right content to stay both relevant and innovative. There are 3 topics I am primarily focused on within the Communications Sector:

 

  • Service Oriented Architecture
  • Mobile Web Services
  • Service Delivery Platforms

 

My Current Role

My specific initiative within Microsoft right now is to assist the virtual team in Microsoft driving the Mobile Web Services initiative. This team has some influential members from the Platforms Strategy Group, Microsoft Research, the Server and Tools product team, and the Communications Sector/MED group.

 

My role is to serve as the Lead Architect within Microsoft Consulting that will help deliver Mobile Web Services implementations within Mobile Network Operators. I work closely with the strategy and development teams on this effort.

 

Mobile Network Operators

The wireless market is undergoing tremendous change. Next generation networks like CDMA2000, 3G, WiFi, and the new WiMax are being deployed. There is a revolution happening in mobile devices, and Microsoft has been a tremendous catalyst in this area. Finally, there is an exciting focus on providing richer, more useful, value-added services to subscribers.

 

There are some key services that have become common to most operators. This includes SMS, MMS, and recently Location detection. There are also some profitable but newer services, like Ring Tone services and downloadable games, which many operators are building. Some companies are providing “buddy locators” to detect when one of your friends is nearby. Finally, people are devising ways to purchase things on their phone like a digital wallet.

 

These services are implemented in many different ways, depending on the operator’s environment and network. There are numerous companies which provide platforms and equipment to implement or provide these base services, and they have their own proprietary interfaces. The more complex services are custom applications that aggregate multiple other base services to provide value.

 

There is a combinatorial challenge here since there are many different mobile network operators, using many different vendors and products to support a varying set of wireless services. This complexity makes it impractical to develop software products to broadly support the operators and services in a ubiquitous, cost-effective, supportable way.

 

Some operators are pursuing their own developer programs to expose their services, but the potential base of developers is somewhat limited by alignment with that specific operator. In a majority of cases, this does not provide enough scale to justify the development of applications specifically for that mobile network operators services.

 

Standards Everywhere

It's widely acknowledged that in the wired network world, there has been a convergence of technology and standards based on XML and Web Services. Microsoft and a few key players such as IBM and BEA have been in the center of that effort, driving integration and standardization in conjunction with leading standards bodies.

 

A similar opportunity exists in the wireless space as well. Vendors and standards groups are focused on new XML-based standards for OSS/BSS, device configuration and provisioning, subscriber services, etc. The subscriber services include a range of abilities like sending messages, locating a device, retrieving voice mail, and purchasing concert tickets on your phone bill.

 

With all of the different standardization efforts, this leads to the challenge describe by the cliché: “Standards are great! There are so many of them to choose from!”

 

Mobile Network Services

Microsoft and Vodafone recently announced the Mobile Web Services initiative to help address this challenge. In essence, they announced a plan to help create new Web services standards that integrate the services provided by Mobile Network Operators with the fixed (wired) network world. Here is a high-level architectural overview.

 

Mobile Web services utilizes the rapidly maturing XML-based Web services architecture to extend the service reach of mobile network services. One opportunity is to make is easy and ubiquitous for developers to integrate mobile network services such as messaging, location, authentication and billing into their applications.

 

Another essential opportunity is to empower end-users with new modalities of computing by harnessing mobile Web services from multiple devices on both wired and wireless networks. This “federated roaming” experience enables a more seamless computing experience. Microsoft has an opportunity in their software applications to unleash this potential.

 

Microsoft and Vodafone said they were interested in working with other key Mobile Network Operators and partners who can bring solid experience, ideas, and innovation to this effort. The goal is to define the foundation of the technical standards and to validate them with real-world implementations. After this work has matured, the expectation is that one or more formal standards bodies would take on the effort.

 

Different Roles for Devices

This effort is not solely about invoking web services from mobile devices, although this is a well supported scenario. It is about integrating the fixed and wireless networks for a richer experience on any device. Some devices are consumers of the services, some devices are participants in the services, and some are both.

 

Devices that consume Mobile Web Services can be any rich device, such as servers, PCs, laptops, PDAs, and SmartPhones. For example, a Mobile Workforce Management application running on a Windows Server might send messages to people via their phone. Another example might be a “Where Am I” mapping application written in.NET CF running on a high-end phone (perhaps a Motorola MPx if you know someone). Michael Yuan has an interesting post on developing .NET CF applications with Web services.

 

Devices which participate in Mobile Web Services can be any supported mobile device by that Operator. One example would be sending a SMS message to a basic cell phone from a web application. The consuming device is a server. The participating device might a basic cell phone, unable to handle XML or Web Services locally. The Mobile Network Operator processes the requests and handles them directly—in this case by sending the SMS message to the phone.

 

This posting is provided "AS IS" with no warranties, and confers no rights.

 

 
Page view tracker