essay on programming languages, computer science, information techonlogies and all.

Monday, January 20, 2014

Automatic optical inspection equipment running in SketchUp by dynamic component

It will be great if you can see that the equipment you designed running even in a computer. You can find out lots of thing that can go wrong before hand. Actually, I guess that is the motto of the SketchUp. Design and see whether it works. To that extent, using component and ensuring edges of different component meet exactly is a big step forward. Next step can be seeing those components running around in times and see how each components interact with each other.

But adding another dimension - in here, it is time - is always a great challenge. Sketchup answers it with dynamic component. Here is an example that use dynamic component to run automatic optical inspection system. You can see that a glass coming and sitting on the stage and gripped by tractor and being scanned by cameras that are also moving to cover whole glass area.



To make this kind of simulation, you need to slice the whole time and put which component should move in what direction in each time slice. Refer below screen shot for this.

When user click the bed component, the "ANIMATECUSTOM( "t", 10, 0, 0, 0, 10 )" is executed which increments variable 't' from 0 to 10 in 10 seconds. Refer SketchUp OnClick Functions for detail. Of course, 't' is the time in unit of seconds.

Now we can move parts in various ways in this 10 seconds. In above screen, you can see that the red marks that 't' updates variable 'servox1' to 'servox5' and when time is 2 seconds to 4 seconds, the servox2 is incremented from 0 to 120 cm with 60cm/seconds. Then it is added up to servox and servox is fed into X position of 'tractor' which makes SketchUp draws the tractor component moves along the x-axis at that time slice.

Well, it works but you can see that it is awkward. How ugly it looks to see those variables. It will makes you crazy if you are asked to change any movement in this code. Just think about how much changes should be there if you decided to put 1 second slice after second 2. Maybe there is a better way to organize code. But still you have to write everything in a line. And also look at all those methods - even there is 'AND' method. Of course, there is OR method. Certainly this will make dynamic component in less favorable option.

Reference : Google SektchUp Workshop. Edited by Laurent Brixius, Appendix : Dynamic Components by Matt Chambers

Monday, January 13, 2014

Employ matrix operation in C++ using MTL4

Developing algorithm using matrix asks for number of tools. First a straight forward and proven tool is needed like Matlab. It is better to minimize unknowns when a new algorithm is tried. You have to be sure that the result is solely come from one source - mostly from maturing algorithm. And that is the reason why you sticks to a tool that you are familiar with.

After making up an algorithm with matrix, it is time to make it a working code. It is not desirable to stick to the algorithm development tool as it comes together with a big library and license. It is MTL4 's turn to play.

MTL stands for Matrix Template Library. It is C++ template based and make no dependencies on a library file nor dll. Hence it goes in a small foot print and can be deployed in any platform.

But as template library goes, the most of the work comes down to a successful compilation of the source code. There are number of things to note. First, download appropriate zip files and copies files to an appropriate folders. In Windows, you can download from here and copies whole usr folder and name it MTL4. Second there is conflict in variable names between MTL4 and WinDefs. Refer below code snippet to fix the compilation error in Windows.
There are number of warning that can be ignored - I know I am lazy on it and will pay the debt at someday but until then. The code to include the MTL4 will be like below.
Now time to port the algorithm code to C++ code using MTL4. Refer below code snippet. As above code shows, the C++ code can be very similar to a code in the Matlab thanks to operator overloading in MTL4. In here, very limited features of MTL4 is shown and you can find more in the MTL4.

Friday, January 3, 2014

Installer with Wix

WiX is XML based installer builder.

As WiX is based on the XML, it can be version controlled and you can track the changes made. This is important as tool like InstallShield isn't saved to a text file. If you don't see a difference, you won't be able to debug some bug that comes up some day. If you know there is no difference in source code, you can be sure that there will be no difference in behaviour. If there is , then you can be sure that it isn't come from the installer. That will save a good time of debugging in installer.

Another advantage of WiX is that it is based on the Window Installer. If you write installer for Windows, you can be sure that this tool can fully utilize all the feature the OS provides - like rollback. How can you make rollback without OS supports ? I have no doubt that you can invent a wheel but who will credit you on a new wheel ?

Though unlike other script based installer e.g. NSIS and InnoSetup, WiX is declarative language as it comes from XML. You may find it hard to understand how one element behave. You won't be able to step through the XML. You will spend quite some time scanning through document to figure out which element should be used in what parent and still you need to figure out appropriate attributes. There is no assignment operator. There is no type. No control statement. All these makes quite unpleasant to read XML code. Probably you won't be able to remember why you use one XML element in a place after a month later.

So you have pros and cons. Simply speaking, it is a great tool to fine control the installer. But will take some dedicated mind to develop and maintain.

I am going to show you a simple WiX installer which install number of file and shortcuts. Also prerequisites will be installed also in here. Below is a xml file defines Product. $(var.Product) and others are preprocessor variables which can be defined in the command line argument of WiX compiler or it can be defined by another xml file. Below is a xml file that defines these variables. You might want to update this file automatically to have a increased build number on every build. Product has GUID at Id and UpgradeCode. You want to change Id when you make a major version change but will keep the UpgradeCode throughout the product.

When a product is installed, it is customary to put a registry value of 'Installed' at the HKCU/Software/Company/Product. This can be used by other installer or program to check existence of a product.

Files feature is defined at a separate file. It contains all the files that will be copied to the target PC. But as there can be quite number of files to copy and manually define all these files can be error prone and tedious, 'Heat.exe' is provided by Wix as harvest tool. To use the heat, we can put relevant files in a directory to simplify the process. Here is a sample batch file that copies product files to a directory and run heat.
Sole reason of copying files from one place to another is the heat.exe. It doesn't allow to run multiple times to merge harvest files. You run heat once and then you can't update the result xml file to feed on the next heat run. Maybe this is just one way to collect all the files to install. Anyway, you can find people using different technique like using XSLT or others to achieve their own goal.

The above batch can be executed by pre-build event of the project with below command line.
$(ProjectDir)PrepareInstallImages.bat $(SolutionDir)\InstallerPickupFilesInHere $(SolutionDir)\YourProductFilesAreHere

First argument is the target path at where the generated installer pick up files. This argument is evaluated at $(var.DIR.Main) at HarvestFiles.wx like below snippet.

But this file will be updated with new id and GUID whenever you run the build. It may not desirable. If you want to keep the change minimized between each version of installer, you'd better copy the content to a new file say Files.wxs and use it to build installer. And later when you need to add a new file or directory, you will pick up those changes from the generated HarvestFiles.wxs and put it to the Files.wxs.

With these files in place in the VS project - Product.wxs, VersionInfo.wxs and Files.wxs - you can build the msi file that can install your product.

Though it is not the end yet. You have your files installed with the msi file but it may not run properly as it may need dependencies installed. You may need to install prerequisites like VC2010 x86 redistribution or .NET Framework 4.0 or others. Time to delve into Bundle. There is "xmlns:util" which is same as in Product project. But in here, as it is a Bundle, you need to put "-ext WixUtilExtension.dll" at Tool Settings / Additional parameters / Compiler. This is to let the Wix compiler to figure out external dll. I found it weird though.

Note that the RegistrySearch is from util which is WixUtilExtension. The basic Wix RegistrySearch isn't working at the Bundle - how come ! - and you should use util:RegistrySearch instead.

For the VC2010 x86 and x64 redist, you can check registry whether those are installed before or not. Refer How to detect the presence of the Visual C++ 2010 redistributable package

The result of this bundle project is an exe file with those prerequisite files contained in addition to the msi file of your product.

Reference : WiX : A Developer's Guide to Windows Installer XML, Nick Ramirez.

Sunday, December 22, 2013

Using Boost io_service to synchronize with user theread

When writing GUI application using MFC, you can encounter a situation that ask you to call some GUI method in a non-GUI thread. This can happens when there are more than 1 threads running - quite common case in nowaday. When application call methods like GetAfxMainWnd() in non-GUI thread, the application crashes. AfxGetMainWnd() stores information at thread local storage which can't be access in the non-GUI thread. Refer below code. Foo runs a non-GUI thread which call a GUI-thread only method that can crash an application.

To get over this problem, you have to make a GUI thread to call a method for the non-GUI thread. If we just put the method on the GUI class holding GUI thread - CMainFrame in above, it makes the GUI class to be dependant on a completely separate class. It is a bad design. And also it is not possible to know all the different methods that will comes up to be called in GUI thread. If we add methods on the GUI-thread whenever a new stuff comes up, the code is constantly changing. Refer below code snippet that demonstart this scenario. In here, the exact implementation detail of synchronization is not shown .e.g SignalGUI(), WaitForGUIToFinish(), IsGUISignaled(). It can be implemented with semaphore and list structure.

With boost IOService, this situation can be elegantly solved with good separation between GUI and non-GUI class. Controller class has io_service and it acts like a bridge between GUI and non-GUI class. The non-GUI class can Post() it's own method that has to run in a GUI thread. The GUI class can just call Controller's Poll() method and that will call non-GUI's posted method subsequently Above Controller() provides a good isolation between two different entity and also reusable as it doesn't depend how the GUI and non-GUI class are made.

Thursday, December 19, 2013

Using MSBUILD

Using MSBUILD and making a build process has advantage on other building tools - e.g. nants ... - and that is IDE. When project file is loaded in Visudal Studio IDE and when project is compiled in build process, there is no difference. So just write code and test it in the IDE is enough to run build process.

But to be consistent on the build result across number of project, it should have a common configuration setting that applies to all the project. This can be easily done by just taking out common part of project and import it in the project configuration. Refer below code snippet. There is Import which asks for BuildUnitTest.Default.props. This file can contains all the common setting across all the unit test that is based on the boot unit test framework.

Now the BuildUnitTest.Default.props can be looked like below. Note setting like OutDir and IntDir. By using this common project file, all the project can emit the generated output file to the OutDir which is consitently named location and all the intermediate file can go to the consitently named IntDir. And note the Debug and Release usage to make consistent setting applying to all the project that import this file.

After having number of this kind os project, it is time to weave those together and make a one project file that can build all the projects. Refer below BuildAll.proj. All solution files are listed at the SolutionToBuild. And all unit test that can be run can be liseted at AfterBuild.

And time to write a simple batch file that can kick off the build process. Refer below BuildAll.bat.

Note that this BuildAll.bat can be used in the command line with vcavr32.bat set. Command window can have below setting. This way of making build process doesn't ask for any other tools. Just Visual Studio - demonstrated in here with 2010 - is enough and can be extended to various ways without much effort and learning.

Saturday, December 14, 2013

Using Git - setup SSH server

People starts to have more than 1 computer to play with. At my case, I have two PCs and 1 laptop and 1 tablet. I use one PC for work and the other PC for private matter and 1 laptop for work and private in mobile. I like to go to a cafe and work at there with my laptop. I see lots of people come to cafe with their laptop. Nowaday, most of popular cafe has power socket at their table or nearby wall. And of course WIFI.

This convenience isn't that convenient when it comes to move around files between PC and laptop. As a software developer, I need to be able to share source code between these computers. Sometimes those files are for work or private or public source code.

I can put all the files in some server and try to download and modify and upload. Or the server can be a source server. At this case, you need to have a server with a fixed IP for this purpose. This asks for money most of the case.

There are another way. You can use a Git. Git is a distributed version control. With Git, you can write code with any of your computer and share it between computer easily.

Roughly speaking, each computer has it's own source repository. After you write code, you will 'commit' it to the local repository which is keeps the changes in it's own computer. Then you will 'push' the committed change to a global repository which can reside in any of your computer. This global repository is where all the changes resides made by all the computer. This repository doesn't have to be on the web. It can be one of your computer. Then you can use another PC or laptop to 'pull' the changes from the global repository. Then makes changes and 'commit' and then 'push'

The distributed part of Git comes handy when you want to see the changed history. The local repository also has all the changed history what global repository has. When you 'push' the changes, all the committed part comes up to the global repository. And then when you 'pull', the local repository gets history of all the changes made by different computer through global repository.

The global repository should be accessible in every computer you have. One way to achieve this is to run a SSH server. This SSH is a gateway that allows other computer to access the computer. Other computer can read/write files in the global repository through SSH server.

SSH server asks a public key for each user. It can be generated using puttygen like below screen shot. You will send the saved public key to the SSH server administrator but keeps the private key in private. Server administrator knows your name and it's public key. And later, when you try to access the server with your name, the SSH server will ask for matched private key to let you in.

Then as SSH Server administrator, you should register you as an user. In here, refer below screen shot with Bitvise SSH Server. You will add an user in the account and then add pulic key you generated using puttygen.

Now when you use Git, you need to use the matched private key to log in the SSH server. Refer below screen shot using TortoiseGit. You can select your private key to log on specific SSH server. In here, I used my computer as SSH server so 'localhost'

After successful log-in, the tortoise git will execute commands of Git which resides at git installer folder e.g. "C:\Program Files (x86)\Git\libexec\git-core". You need to put this path at the environmental variable PATH. Otherwise, the SSH server will just terminate just after executing any git command. e.g. cmd.exe /c git-upload-pack "F:\depo\my_repo.git" - in this case if git-upload-pack is not in path, the cmd.exe just returns without any error.

Thursday, August 1, 2013

Lightweight Component Object Model

COM (Component Object Model)is an ambitious and grand paradigm that aimed to cover almost everything. First of all, it is compiler neutral and further more it is programming language neutral. And it can create object within a process or it allow to communicate with a service ( an component in a separate process ) via marshaling. And it allows multiple inheritance.

This grandness is what makes the COM to be dominant in various software project. Though it is heavy weight and has a steep learning curve. Compiler and language neutral brings in IDL ( Interface Definition Language ), VARIANT, BSTR and HRESULT. There can be no exception crossing object boundary. Object creation model brings in various registry scheme. Apartment model comes with lots of concepts e.g. MTA, STA, marshaling, server lifetime and so on. Installation needs registering the DLLs in a specific way.

There are lots of situation that we don't need too much freedom. For example, in a equipment control software, it is tightly controlled software project and won't need that much neutral stuff. Any changes in software should be heavily tested and usually deployed as a whole. And only one programming language is used to develop the whole control code. Engineer spends more time to make machine running rather than mixing two different programming language for the sake of grandness of software.

Now imagine what happen if a project doesn't need language neutral or compiler neutral. What happen if we don't need marshaling ? What happens if we want to throw exception from a sub module and catch it in a host module ? What if we can just use string or wstring ? What if we just want to drop a DLL into a specific folder ?

Here I will try to code a C++ component object model - named PlugIn - that will be written with C++ and complied with VisualStudio and nothing else. It can be created only within the host process and it only allows single inheritance.

// IPlugIn.h 
class IPlugIn
{
public:
  virtual ~IPlugIn() {};
  virtual const char * GetID() const = 0;
};

typedef std::vector PlugInNameArray;

class IPlugInFactory : public IPlugIn
{
public:
  virtual PlugInNameArray GetPlugInIDs() const = 0;
  virtual IPlugIn* Create( const char *ID ) = 0;
};
First IPlugIn is equivalent of IUnknown in COM. It is the base interface of all object exposed. Unlike IUnknown, it doesn't need QueryInterface because polymorphic cast i.e. dynamic_cast retrieves the interface desired - in type safe way. And as we don't support multiple inheritance, complex QueryInterface() doesn't necessary. AddRef() and Release() won't be necessary as boost smart pointer .i.e shared_ptr will be used to manage the allocated memory. Then it has to be noted that the class in DLL should be allocated by new as shared_ptr will clear it with delete. This leads to define virtual destructor.

IPlugInFactory is a factory pattern that delegate the creation of IPlugIn based one string id. This string id is what ProgID - Programmatic ID does. Again we don't use GUID for interface as we are gonna rely on the dynamic_cast.

GetPlugInIDs() is to retrieve all the supported class. This is to allow discovery of class dynamically. User is supposed to enumerate all the IDs and create and check whether it can be cast to the desired interface.

This IPlugIn.h declare what the basic interface looks like. This interface is exported using C functions as below.
#ifdef PLUGIN_EXPORTS
#define LIBSPECS extern "C" __declspec(dllexport)
#else
#define LIBSPECS extern "C" __declspec(dllimport)
#endif

LIBSPECS HRESULT DllGetVersion( DLLVERSIONINFO *pvdi );
LIBSPECS IPlugInFactory* CPI_CreateFactory();
DllGetVersion is to let user knows the version of loaded DLL. According to Johnson M.Hart ( Windows System Programming 4th : 175-177 ), it is quite common practice in Microsoft. As it is not a good idea to invent a wheel, I use the same method.

CPI_CreateFactory() is the only entrance of the DLL. All the plugin in the DLL should be created using this interface.

Now the implementation of the plugin.

// IFoo.h
class IFoo : public IPlugIn
{
public:
 virtual int Foo( int i ) = 0;
};

typedef boost::shared_ptr< IFoo > IFooPtr;


// PlugInFoo.cpp
class PlugInFoo : public IFoo
{
public:
  const char * GetID() const { return s_PlugInClassName; }
  int Foo( int i ) { return i * i; }

  static const char *GetClassName() { return s_PlugInClassName; }

private:
  static const char *s_PlugInClassName;
};

const char * PlugInFoo::s_PlugInClassName = "CPI.PlugInFoo.1";


class FooPlugInFactory : public IPlugInFactory
{
public:
  const char * GetID() const { return "CPI.PlugInFooFactory.1"; }

  PlugInNameArray GetPlugInIDs() const 
  {
    PlugInNameArray names;
    names.push_back( PlugInFoo::GetClassName() );
    return names;
  }

  IPlugIn* Create( const char *plugInName ) 
  {
    std::string strPlugInName( plugInName );
    if( strPlugInName == PlugInFoo::GetClassName() )
    {
      return new PlugInFoo();
    }
    else
      return NULL;
  }
};

IPlugInFactory* CPI_CreateFactory()
{
  return new FooPlugInFactory();
}

IFoo.h is what is going to be shared with host process. This is what the host process going to cast on the created object.

Implementation of IFoo.h and IPlugInFactory is almost trivial. PlugInFoo can return it's class name as ID and FooPlugInFactory is returning this class name as it's sole PlugIn. Of course, it can return more than a IDs. Create() is just allocating memory and returning it to the user.

Now it is turn to Host process. It should be able to retrieve a known interface in a DLL based on the known id. Here I put these function in a hpp file so that it can be used by just adding this header.
// PlugInModule.hpp

class PlugInModule
{
public:
  PlugInModule() : m_hDLL( NULL ) {}

  ~PlugInModule()
  {
    m_PlugInFactory.reset();

    if( m_hDLL ) {
      FreeLibrary( m_hDLL );
    }
  }

  void Load( const _TCHAR * filename )
  {
    m_hDLL = LoadLibrary( filename );
    if( m_hDLL == NULL ) {
      throw Exception( StringFormat::As( _T("%s is not a valid DLL"), filename ) );
    }

    FN_DllGetVersion DllGetVersion = 
      (FN_DllGetVersion) GetProcAddress( m_hDLL, "DllGetVersion" );
    if( DllGetVersion == NULL ) {
      throw Exception( StringFormat::As( _T("%s is not a supported PlugIn DLL"), filename ) );
    }

    if( S_OK != DllGetVersion( &m_VerInfo ) ) {
      throw Exception( StringFormat::As( _T("Failed to get version info of the PlugIn DLL %s"), filename ) );
    }


    FN_CPI_CreateFactory CPI_CreateFactory = 
      (FN_CPI_CreateFactory) GetProcAddress( m_hDLL, "CPI_CreateFactory" );

    if( CPI_CreateFactory == NULL ) {
      throw Exception( StringFormat::As( _T("%s is not a supported PlugIn DLL"), filename ) );
    }

    m_PlugInFactory = IPlugInFactoryPtr( CPI_CreateFactory() );
  }

  template< typename TPlugIn >
  boost::shared_ptr< TPlugIn > CreatePlugIn( const char *name )
  {
    if( m_PlugInFactory == NULL ) { throw Exception( StringFormat::As( _T("No plugin in loaded") ) ); }

    IPlugIn* plugIn = m_PlugInFactory->Create( name );
    if( plugIn == NULL ) {
      throw Exception( StringFormat::As( _T("No plugin found with give name %s"), name ) );
    }

    TPlugIn* targetPlugIn = dynamic_cast< TPlugIn* > ( plugIn );
    if( targetPlugIn == NULL ) {
      delete plugIn;
      throw Exception( StringFormat::As( _T("Can't convert to taregt plugin interface with %s"), name ) );
    }

    return boost::shared_ptr< TPlugIn >( targetPlugIn );
  }

  const DLLVERSIONINFO& GetVersionInfo() const 
  { 
    if( m_hDLL == NULL ) { throw Exception( StringFormat::As( _T("No DLL has been loaded yet" ) ) ); }

    return m_VerInfo; 
  }

  PlugInNameArray GetPlugInIDs() const
  {
    if( m_hDLL == NULL ) { throw Exception( StringFormat::As( _T("No DLL has been loaded yet" ) ) ); }
    return m_PlugInFactory->GetPlugInIDs();
  }
  
private:
  typedef boost::shared_ptr IPlugInFactoryPtr;
  typedef IPlugInFactory* (* FN_CPI_CreateFactory)();
  typedef HRESULT (* FN_DllGetVersion)(DLLVERSIONINFO *);

  HMODULE m_hDLL;
  IPlugInFactoryPtr m_PlugInFactory;
  DLLVERSIONINFO m_VerInfo;
};

typedef boost::shared_ptr< PlugInModule > PlugInModulePtr;

Above hpp can be used as below code. User just load a dll and can create interface with known ID.
#include "PlugInModule.hpp"

  PlugInModulePtr plugInFoo( new PlugInModule() );

  plugInFoo->Load( _T("PlugInFoo.DLL") );
  IFooPtr foo( plugInFoo->CreatePlugIn( "CPI.PlugInFoo.1" ) );
  foo->Foo( 10 )  
This light weight component object model is very restricted but it can be an easy alternative to the heavy weight COM.