It is All about Traffic, and Programming
Search
Archives
0 visitors online now
0 guests, 0 members

COM

Lane Closure Utility Updated for VISSIM 9

Lane Closure Utility was initially developed in 2006 as an amateur/hobby work by a then graduate student.  Surprisingly,  it had been found useful,  and has been used by quite a few industry engineers, graduate students,  and academic researchers in their work.  I would like to thank them again for giving me feedback and inputs.

I just updated this free little utility to work with VISSIM latest 9.x version.

PTV made a LOT, really a LOT of changes to VISSIM COM interfaces – which is annoying but understandable given their grand plan of overhauling and refactoring the system’s application framework inside out –  that however made this upgrade quite eventful trying back and forth to figure out a lot of undocumented changes. Anyway,  I managed to just upgrade the code to match the latest VISSIM version COM interfaces.

It can be downloaded here: vissim9-dist-x86-x64  Feel free to download and distribute.

For those interested – my previous post about this little utility is here, so you can learn how to use it (easy and simple!)  Another big surprise to me as I found today is that – the original post has been read for almost 5000 times!  Wow.  I would be even happier  if you’d left me some comments,  good or bad.

Lane Closure Utility for VISSIM 5.40 (32bit and 64bit)

 

Dissecting Vissim COM Internal from Inside Out (3)

In order to study the life cycle of CCOMVissim,  we have to track the calling stack of comsvr.dll.  This DLL is the host of CCOMVissim and other helper classes of Vissim COM functionalities. Please note it is not possible and not an option to perform static code analysis using a typical debugger. This is because CodeMeter hardware chip employs sophisticated anti-debugging mechanism, black-listing all known static/dynamic analysis debuggers such as OllyDBG or IDAPro .  We’d have to return to comsrv.DLL  – and recall in this post – the 58 exported functions, something like below:

vissim-com-export-index-1-30

As an effective approach (for interoperability among Vissim’s own various licensed modules),  let’s start creating a DLL project, using the same name “comsrv.DLL”,  as the one in the Exe folder of Vissim installation.

As a good background reading on exporting  C++ classes in a DLL,  here is an detailed post CodeProject: Export C++ classes from a DLL

Following this new Visual Studio C++ DLL project,  create a new class called CCOMVissim  – pay attention to the class definition, and the empty methods, and the declaration “__declspec(dllexport)“.  By default, the calling convention is “thiscall“.  Because we know Vissim is compiled in Visual C++ compiler apriori, thus name mangling wouldn’t be an issue (because of the same C++ compiler).

2015-06-05_14-59-13

Now, compile this project, and a dll called comsrv.dll is generated.  After this new DLL is generated,  de-compile it to verify the exported functions (see the figure below):

2015-06-05_15-02-18

We just created a “proxy” DLL with the same name as Vissim’s original comsrv.dll.  We emulated some of the original exported functions and classes.  The point is,  as long as the same list of  functions  are exported by this new dll, it is “loadable” by Vissim.  Therefore, we are  enableed to append additional code to track, manage, and manipulate the calling stack of those class methods or functions relevant to the life-cycle of IVissimPtr. This will help accomplish the objective of enabling interoperability of Vissim COM functionalities within Vissim’s various DLL-based modules,  including Signal Control API DLL, External Driver DLL and such.

If you could understand up to this point,  there should be no problem for you to move on to a final working solution to the question asked in the beginning.  The efforts are yours, and the omissions are mine.  One last hint:

Rename the original “comsrv.dll” to a different name, e.g., “comsrv_org.dll”.  Redirect calls from inside the proxy comsrv.dll to the original dll.

Dissecting Vissim COM Internal from Inside Out (2)

Let’s look at a typical Vissim COM programming code snippet in C++. It is taken from the Vissim manual, with some reformatting.

For Vissim end users, C++ is not an ideal choice of language for COM applications.  You’d have to handle all the complexities involved with COM  interface management. C++/COM programming has never been something as easy as a breeze with a steep learning curve.  On the other hand,  C++/COM is excellent that it does not hide COM implementation details,  while providing the best performance than any other languages. It is simply native to the COM world.

vissim-com-vc-snippet-1vissim-com-vc-snippet-2

In this beautiful C++ code snippet, Smart Pointer is used.  QueryAttach is a helper function shipped with this sample; it encapsulates the tedious QueryInterface process, and wraps up the returned Vissim interface as a smart pointer.

Clearly, the code illustrates the work-flow invoking Vissim as an automation server (see my another post on Vissim COM Instance Model).  When you call CreateInstance,  a Vissim process is started, where the default interface IVissim is instantiated and returned as the smart pointer IVissimPtr.

To say the least,  IVissimPtr is the “Open Sesame” to the wonderland of Vissim COM programming.

The  flow of all Vissim COM programming starts from getting an instance of IVissim interface.

It is fairly easy to get an IVissim interface by invoking Vissim as an automation server – just having an external COM client to call   CreateInstance.

VISSIMLIB::IVissimPtr pVissim declares the smart pointer to the default  IVissim interface.  COM smart pointer encapsulates COM operations including AddRef, Release etc. Don’t confuse yourself VISSIMLIB::IVissimPtr with IVissimIVissimPtr is generated by macro _COM_SMARTPTR_TYPEDEF(IVissim, __uuidof(IVissim)), while IVissim is declared as the following:

struct __declspec(uuid("a023e2ec-8002-4bb1-a584-b85ce59681ee"))
IVissim : IObjectBase
{
    //
    // Property data
    //

    __declspec(property(get=GetNet))
    INetPtr Net;
    __declspec(property(get=GetSimulation))
    ISimulationPtr Simulation;
    __declspec(property(get=GetEvaluation))
    IEvaluationPtr Evaluation;
    __declspec(property(get=GetGraphics))
    IGraphicsPtr Graphics;
    __declspec(property(get=GetPresentation))
    IPresentationPtr Presentation;

    //
    // Wrapper methods for error-handling
    //

    HRESULT New ( );
    HRESULT LoadNet (
        _bstr_t NetPath,
        VARIANT_BOOL Additive );
    HRESULT SaveNet ( );
    HRESULT SaveNetAs (
        _bstr_t NetPath );
    HRESULT LoadLayout (
        _bstr_t LayoutPath );
    HRESULT SaveLayout (
        _bstr_t LayoutPath );
    HRESULT ImportANM (
        _bstr_t NetPath,
        _bstr_t RoutesPath,
        _bstr_t InputPath,
        ImportType ImportType,
        int importOptions,
        int evaluationInterval );
    HRESULT BringToFront ( );
    HRESULT Exit ( );
    INetPtr GetNet ( );
    ISimulationPtr GetSimulation ( );
    IEvaluationPtr GetEvaluation ( );
    IGraphicsPtr GetGraphics ( );
    HRESULT ImportSynchro (
        _bstr_t synchroFile,
        _bstr_t workingDirectory,
        VARIANT_BOOL adaptiveImport );
    IPresentationPtr GetPresentation ( );
    HRESULT ExportVisum (
        _bstr_t NetPath,
        VisumExportType ExportType );
    HRESULT ImportResults (
        _bstr_t Path );
    HRESULT VissimTest (
        int TestNo,
        _bstr_t Param1,
        _bstr_t Param2,
        _bstr_t Param3 );
    HRESULT SuspendUpdateGUI ( );
    HRESULT ResumeUpdateGUI (
        VARIANT_BOOL enforceRedraw );

    //
    // Raw methods provided by interface
    //

      virtual HRESULT __stdcall raw_New ( ) = 0;
      virtual HRESULT __stdcall raw_LoadNet (
        /*[in]*/ BSTR NetPath,
        /*[in]*/ VARIANT_BOOL Additive ) = 0;
      virtual HRESULT __stdcall raw_SaveNet ( ) = 0;
      virtual HRESULT __stdcall raw_SaveNetAs (
        /*[in]*/ BSTR NetPath ) = 0;
      virtual HRESULT __stdcall raw_LoadLayout (
        /*[in]*/ BSTR LayoutPath ) = 0;
      virtual HRESULT __stdcall raw_SaveLayout (
        /*[in]*/ BSTR LayoutPath ) = 0;
      virtual HRESULT __stdcall raw_ImportANM (
        /*[in]*/ BSTR NetPath,
        /*[in]*/ BSTR RoutesPath,
        /*[in]*/ BSTR InputPath,
        /*[in]*/ ImportType ImportType,
        /*[in]*/ int importOptions,
        /*[in]*/ int evaluationInterval ) = 0;
      virtual HRESULT __stdcall raw_BringToFront ( ) = 0;
      virtual HRESULT __stdcall raw_Exit ( ) = 0;
      virtual HRESULT __stdcall get_Net (
        /*[out,retval]*/ struct INet * * Net ) = 0;
      virtual HRESULT __stdcall get_Simulation (
        /*[out,retval]*/ struct ISimulation * * Simulation ) = 0;
      virtual HRESULT __stdcall get_Evaluation (
        /*[out,retval]*/ struct IEvaluation * * Evaluation ) = 0;
      virtual HRESULT __stdcall get_Graphics (
        /*[out,retval]*/ struct IGraphics * * Graphics ) = 0;
      virtual HRESULT __stdcall raw_ImportSynchro (
        /*[in]*/ BSTR synchroFile,
        /*[in]*/ BSTR workingDirectory,
        /*[in]*/ VARIANT_BOOL adaptiveImport ) = 0;
      virtual HRESULT __stdcall get_Presentation (
        /*[out,retval]*/ struct IPresentation * * Presentation ) = 0;
      virtual HRESULT __stdcall raw_ExportVisum (
        /*[in]*/ BSTR NetPath,
        /*[in]*/ VisumExportType ExportType ) = 0;
      virtual HRESULT __stdcall raw_ImportResults (
        /*[in]*/ BSTR Path ) = 0;
      virtual HRESULT __stdcall raw_VissimTest (
        /*[in]*/ int TestNo,
        /*[in]*/ BSTR Param1,
        /*[in]*/ BSTR Param2,
        /*[in]*/ BSTR Param3 ) = 0;
      virtual HRESULT __stdcall raw_SuspendUpdateGUI ( ) = 0;
      virtual HRESULT __stdcall raw_ResumeUpdateGUI (
        /*[in]*/ VARIANT_BOOL enforceRedraw ) = 0;
};

In addition to invoking Vissim as an automation server,  In-Menu/Event-based COM scripting has a different mechanism.

In the In-Menu/Event-based COM script,  there is no explicit instantiation of IVissim. As a matter of fact,  there is a “Vissim” object already created, ready to be referenced in the script.

That is a mystery, isn’t?

To trace how and when “Vissim” object is created in the scripting context, we need to trace the life cycle of  the class CCOMVissim. That is the key to the original question – i.e.,  how to call all those COM functions inside an external DLL.

We’ll continue with our journey looking into the life cycle of the class CCOMVissim.  Right now, please just look at IVissim declaration again, and remember the following:

IVissim declaration stipulates nothing but just a memory blueprint. The sequence of all its virtual members are the slots of the v-table of IVissim’s implementation class.  This, is the “Open Sesame”.

Dissecting Vissim COM Internal from Inside Out (1)

There was an interesting discussion at PTV Vissim LinkedIn group – how to access Vissim COM interface inside a DLL, e.g., a Signal Control DLL,  an External Driver DLL etc.  To properly answer this question, some in-depth understanding of the COM technology,  C++ compiler internals, and Vissim binary level details are in order.

To begin with, Component Object Model (COM) is just a binary-level coding standard for out-of-process and in-process communication. It’s been out there for many years but somehow never become popular due to its daunting learning-curve for ordinary programmers,  and then Microsoft began promoting .NET, which is essentially similar idea revamped at the level of Common Language Run-time (CLR) and Intermediate Language (IL).

In the nostalgia good-old days,  COM/C++ programming required too steep learning curve to weed out sub-par programmers.  Nowadays programming is so much easier with various .NET languages or scripting languages that do not require low-level knowledge of hardware or compiler internals. The barrier to programing is quite low nowadays; anyone with common  sense can pick up programming,  develop some apps, and sell such on streets.

In the context of Vissim,  PTV wraps up the simulation elements and workflow into various interfaces. These interfaces are implemented (in C++) at binary level thus any language that supports COM (by their respective compilers) will be able to use Vissim’s COM interface to interact with Vissim functionality.

In the  earlier days of Vissim, its COM interfaces allow a client application to invoke Vissim as an automation server (as an out-of-process use case). Then PTV added In-Menu scripting, that supports invoking COM inside the active Vissim instance, using Python, VBS, or JS.

Starting Vissim 6, PTV completely refactored and redesigned Vissim, almost rebuild the software from scratch, inside out.  As part of this process, more gems are added,  one of such, is the so-called “event-based” COM scripting. “Event-based” COM scripting is a use case of in-process COM; it was added since Vissim v7.

Once again, with the In-Menu COM/Event-based Scripting,  and many other new designs/architectures, Vissim has set up a solid foundation significantly better than its v5 and any earlier generations, making itself readily primed for the future. A big congratulation is due to the PTV development team for this achievement, seriously.

Some of my earlier post discussed Vissim COM Internal as well.

As of today, Vissim 7-09 appears as the most impressive redemption of a legacy software (I mean, particularly, Vissim v4 and earlier versions) – and presents itself, with so many improvements and beef-ups, and as a powerful, sleek and increasingly popular tool for its users that have been yelling and crying for  years while its competitors eating up its market share.

Aside from COM interface, Vissim also provides various APIs e.g., Signal Control API, Emission API, External Driver API etc. These APIs have to be compiled in DLL to be loaded by Vissim host, which calls back the exported functions when certain events fire.

It is interesting that “event-based” COM scripting is capable of providing a unified interface for all the above APIs.  In future, it is possible that PTV might gradually phase out all these DLL-based APIs so everything is done through a unified event-based COM scripting. Granted, that is just my personal perspective.

Now, coming back to the million dollar question –  can we access COM interface from inside an API DLL? For example,  from inside External Driver DLL,  how can we access some, if not all of the COM functions?

The answer is: yes,  that is doable, but with some twist.

Now you start to have a faint of heart,  aren’t you?  Before we roll up our sleeves and jump to the 1-2-3 steps, I want you to take a look at the following snapshots – they are the key to the solution.

The following are the 58 exported functions from comsrv.dll, which is located in Vissim installation Exe folder. Most of these exported functions, are class methods of several classes, primarily:

  • CComVissim
  • CComNetObjHelper
  • CComVehicleContainer
  • CComSignalController
  • CComPedestrianContainer
  • CComException

💡 comsrv.dll is the “hub” of all Vissim COM functionality.

With the above in mind,   let me lead you to the interesting journey to figure out comsvr.dll  and Vissim COM invocation flow, till we reach the final solution to the original question.

vissim-com-export-index-1-30

vissim-com-export-index-31-58

 

(to be continued)

Brain-Wave Controlled Traffic Simulation: Control a Vissim Simulated Car (1)

Ever watched the movie “Carrie”, a classic produced in 1976 from Stephen King’s 1974’s horror novel?  An abused 17-year-old girl with telekinesis, gets pushed to the limit by a humiliating prank,  and finally took her revenge with her power – turning her school’s prom into a bloody night of killing.

You might want to develop telekinesis on your own,  so as to get back on whoever you get pissed of with – Good Luck on That!  Here is a nice tip on How to Develop Telekinesisjust let me know how it works!!

What we are going to talk about today is the so-called Brain-Computer-Interface (BCI), which is about using your brain wave patterns to train a computer program, while the latter directs some device doing some nice, dirty, and/or even horny (you wish!)  jobs for you   😆  

Here is an excerpt from Wikipedia:

A brain–computer interface (BCI), sometimes called a mind-machine interface (MMI), or sometimes called a direct neural interface (DNI), synthetic telepathy interface (STI) or a brain–machine interface (BMI), is a direct communication pathway between the brain and an external device. BCIs are often directed at assisting, augmenting, or repairing human cognitive or sensory-motor functions.

BCI uses Electroencephalography(EEG), which detects voltage fluctuations resulting from ionic current flows within neurons of brain. Whenever your neurons fire,  weak electrical signals in millisecond-range resolution propagates all the way to the scalp.This signal is at higher resolution than CT or MRI.

Therefore, BCI is pretty much about signal processing, machine learning and pattern recolonization recognition.

EEG was invented in early 1900’s, hence it is not something new.  However, when the time comes to 2010’s,  the industry has come out with cost-effective and portable EEG devices (unlike those used in medical applications).  Novel applications are thus enabled.  The following pictures (source:http://emotiv.com/) illustrate a conventional EEG and a portable EEG device.

compare1 compare2

The following picture shows Emotiv EPOC EEG device, manufactured by Emotiv, featuring

16 wet electrodes, 14 EEG electrodes read brain waves, two-axis gyroscope to read head movements, 4 mental states, 13 conscious thoughts or facial expressions, 4 processing suites

The wonderful thing is, this little device sells for only $399 desktop or $499 for Bluetooth Smart, with full programming SDKs. You can even integrate it with wearable devices (such as Google Glass).

epoc

And, that is what I am gonna do.  I am going to use this little gadget, and its SDKs to interface with VISSIM microscopic traffic simulator via its COM interface and Driver API – so I can:

  • Command a simulated car to brake, accelerate and stop,  using my brain wave – termed otherwise,  by simply staring at my computer screen like a dork 😯 .

That is right.  I am going to present an interesting demo here that Brain-Computer-Interface for the first time,  being used in traffic simulation to control a simulated car…… (I really wish one day I could use the same to command my boss to pay me more  😈 )

Stay tuned. It is going to be realllllly FUN.

(to be continued)

Initial Setting up of Vissim COM in .NET environment

VISSIM’s kernel is pretty much written using  C++ (a lot of template programming),  including its COM part.  Its UI is written in .NET for a better user experience, though. The VISSIM COM API manual is mostly about using it with Visual Basic or VBA,  which has long been depreciated by Microsoft since Visual Studio 6.0.

For .NET environment,  no detailed description is provided as to how to import the COM lib.   Anyway, here are the list of the snapshots to show how to import Vissim type lib in .NET (VS 2012), to start VISSIM COM client programming.  It applies to all .NET languages, such as C# or VB.NET.

1. Create a new C# (or VB.NET project).

2014-03-18_17-58-38

2. You will see something like below.

2014-03-18_18-00-01

3. Right click “References”,  choose “Add Reference”..

2014-03-18_18-00-19

 

4.  Choose “Browse”.

2014-03-18_18-01-02

5. Browse to where Vissim is installed,  select “Vissim.exe” . Click “Add” , and click “OK”.

2014-03-18_18-01-30

6. You will now see “VISSIMLIB” is added to the references list.  From this point on,  you can start referencing VISSIMLIB interfaces as in the C# example of the VISSIM manual.  Have fun.

2014-03-18_18-01-57

Running VISSIM from within MATLAB

Vissim has a very nice COM-based programming interface – that a user can use any COM-compliant languages (as COM client)  to programmingly invoke Vissim (as out-of-proc COM server),  and performs some customized task.  Typically,  a user can use Excel/VBA, C#, Java,  Fortran, Delphi, C++ etc as his preferred language.

Matlab is a comprehensive computation platform with a lot of readily available numerical algorithms (e.g., Genetic Algorithms,  Support Vector Machine, Wavelet, Kalman Filtering etc.)  that can be very useful in simulation studies, research and development on customized and sophisticated simulation experiments.

Matlab provides very good support for COM – hence it is, in my opinion, probably the best Vissim COM programming environment if you have an academic minds and wish to do some cool prototypes and interesting simulation experiments.

  • For industry applications,  it is probably an overkill,  and the performance hit is a problem – Matlab essentially works the same way as Excel/VBA – this means all method invocations are “interpreted” – the stack frame is created by first querying a dictionary of method names to get the right function pointer,  amongst the mess of the inter-process marshaling.   C++, C# or any compiled language would be much faster as the stack frame is created directly from function pointer without the  querying step.  Wait – strictly speaking, C# is a bit different from other native language like C++, Delphi, or Fortran, as .NET/COM inter-op is via Common Language Runtime (CLR)’s P/Invoke which is another layer, rather than the pure native way.

Vissim User Manual doesn’t mention how to use Vissim COM wih Matlab.  It is not complicated but there is some catch to make it work, so I just put the procedures here – and,  if you find it helpful,  a loud “Thank You” would make me HAPPY!

First thing first,  in order to run Vissim COM,  you would need to know Vissim’s ProgID, which is a string-based name saved in Windows system registry, together with some other information (such as the path to Vissim.exe).  Here is an excerpt you need to read carefully from Vissim COM manual:

When working with Vissim  manually it is possible to start several instances of Vissim. You
can  also  start  several  different  versions  (e.g.  Vissim  5.40  and  Vissim  6.0).  The  same
applies  when  working  with  COM:  If  the  version  number  is  not  specified  (i.e.
CreateObject (“Vissim.Vissim”)),  the  Vissim  version  which  has  been  registered  as  COM
server most recently is started.  Specifying the version number during the call allows you to
start  a  specific  version  of  Vissim:  CreateObject (“Vissim.Vissim.540”)  for  Vissim  5.40  or
CreateObject (“Vissim.Vissim.600”)  for Vissim 6. If you have installed a 32-bit and  a  64-bit
edition,  you  can  use  “Vissim.Vissim-32.600”  or  “Vissim.Vissim-64.600”  to  start  a  specific
edition. A Vissim instance started via COM is automatically closed as soon all COM objects
are set to nothing.

This is kind of twisty, so let me rephrase it, with some simplifications:

  • If you only have one Vissim version installed, ProgID = “Vissim.Vissim”
  • If you have multiple Vissim version installed, ProgID = “Vissim.Vissim.XXX”, where XXX is the version number, e.g., 540 for version 5.40, or 600 for version 6.00. Please note,  service packs doesn’t count for version number, so service pack 1, 2, … n for the same version have the same ProgID
  • If you have multiple Vissim versions,  for 32bit and 64bit, then the ProgID = “Vissim.Vissim-YY.XXX”, where YY is 32, or 64, corresponding to 32bit or 64bit edition, XXX is the version number such as 540, or 600.

With ProgID in mind, and a Vissim COM interface online manual in front of you,  now you need to

  • Launch Matlab (in my example I am using Matlab 2013b), but I believe any Matlab version after 7.0 will do;
  • In the Matlab Command Window, type
    vissim = actxserver('Vissim.Vissim.600')

    Note here a ProgID string ‘Vissim.Vissim.600’,  with an explicit version number 600 is used. This is because on my computer I have two Vissim versions (540 and 600) installed. actxserver is a Matlab command that returns the default interface of the COM server, which in our case,  is IVissim interface.

  • Immediately you will see a Vissim 600 instance being launched automatically, and the main GUI shows up;
  • The Matlab variable, “vissim” is a handle to IVissim interface. From this point on,  you can use “vissim” to call various other interfaces, for example,
    vissim.LoadNet(‘whatever.inpx’), vissim.Simulation.RunContinuous, simulation = vissim.Simulation
  • You can do whatever you like now with Matlab,  including invoke  Genetic Algorithm routines or something else;
  • Finally, when you are done,  to destroy “vissim” (which is a reference-counted handle of IVissim interface),  simply put this line
    vissim = 0,  or alternatively,  vissim.Release

    then the vissim instance will be destroyed (to be more accurate  – released to decrement ref_count,  and destroyed if ref_count drops to zero) and the main GUI disappears from the screen.

Last, there are two little tricks working Vissim in Matlab environment , you can use .get to list all properties of an interface, and .methods to list all methods of an interface, for example:

You can immediately recognize that these are all listed in Vissim COM Manual – but it is good to verify by using .get  and .methods.

********************

UPDATE –

I found another good source of information on this subject is a white paper of Dr. Tamas Tettamanti, which provides a more detailed step-by-step document for Vissim-Matlab integration –

http://www.researchgate.net/publication/258513223_The_beginning_steps_of_VISSIM_COM_programming_with_MATLAB_script

 

Lane Closure Utility for VISSIM 5.40 (32bit and 64bit)

The “Lane Closure Utility” is a hobby tool I developed when I was a graduate student 5 years ago.  It utilizes VISSIM COM interface to dynamically close or open any lane of any link at any time,  during the simulation.

The tool can be pretty handy for modelling lane closure (You Bet!),  incidents,  evacuation contraflow, work zones etc.

Interestingly,  over the years PTV didn’t bother to implement this “dynamic lane closure” as its default feature.  Once you specify a lane closure at the beginning,  it will be literally a lane closure throughout the entire simulation period.  This “limitation” might be awkward sometimes,  if you do not mean to close the lane for the entire simulation period,  but just want to close the lane at certain point,  and re-open it at a later time during the simulation.

Since VISSIM does not provide a convenient off-the-shelf solution for this type of situation,  there have been surprisingly quite some VISSIM users,  including university faculties, graduate students,  traffic engineers contacted me for accessing this utility,  to use in their engineering projects,  research dissertations and others.

As of today,  the latest VISSIM version available to North American users is 5.40 (SP3).   I just updated this small utility to be compatible with this latest VISSIM 5.4 version.  Because PTV won’t change VISSIM COM Lib’s GUID with its service packs,    the utility should work with all service packs of the same major version.

The updated lane closure utility can be downloaded from the following link:

vissim54-lcu-x86-x64

A small tutorial:

LCU Tutorial

The utility is built both as 32 bit and 64 bit programs, to work with respective VISSIM 32 bit or 64bit.  The download package includes a little demo and a quick video tutorial (you might need to install tscc CODEC to play the video, though).

The following is the snapshot of the user interface.

To set the schedule of a lane closure event,  click “New” under “LCU File Items”.  You will see the following

A lane closure event is defined as an ensemble of the following elements:

Scheduled Time, in seconds counted from the simulation start time;
Event Type: Lane Closure, or Lane Open;
Link ID;
Lane ID;
Affected Vehicle Class List.

This boils down to the following lane closure configuration file:

20-LaneClose-1-1-2-10-20-
40-LaneClose-1-2-2-20-10-
60-LaneOpen-1-2-2-10-20-
1000-LaneOpen-1-1-2-10-20-

Essentially, the above configuration says:

at time 20 seconds,   close Lane 1 of Link 1 to Vehicle Class 10 and Vehicle Class 20
at time 40 seconds,   close Lane 2 of Link 1 to Vehicle Class 10 and Vehicle Class 20
at time 60 seconds,   open  Lane 2 of Link 1 to Vehicle Class 10 and Vehicle Class 20
at time 1000 seconds, open  Lane 1 of Link 1 to Vehicle Class 10 and Vehicle Class 20

After specifying the schedule,  load the VISSIM network file and click “Run VISSIM”, then VISSIM will be launched.  You can control the simulation speed by sliding the “Simulation Speed” track bar. That is all.  After all,  it is a very simple tool anyway.  If you find it useful or interesting,  or just sucks,  please don’t hesitate to drop me a “thank you” message or tell me “it stinks” or whatever.

VISSM COM Instance Model

VISSIM has a licensed feature “VISSIM COM” that a user can use to do automation-style programming. It provides convenient, easy-to-use  interfaces to access VISSIM functionality programmingly (e.g., though an Excel client).

VISSIM COM Server by design can only be invoked in “single instance” mode. That is, if you have a COM client that tries to establish a connection with a VISSIM COM server, the connection will be established only to the first VISSIM instance that has already been created.  In other words, a new VISSIM instance is created if and only if there is currently no active VISSIM instance running.  On the other hand, if there are multiple VISSIM instances, your COM client would only connect to the first instance.

Yesterday at  the 90th TRB annual meeting, a Minnesota friend asked me if it is possible to create multiple VISSIM COM server connections.   That was a pretty interesting question, and the answer lies in a clear understanding of what is under the hood of Microsoft’s COM technology.  Probably  let me do a little lecture first for those non-programmers or who not familiar with the inner workings of COM.  Since in 99.9% of its applications,  VISSIM is only used as a local out-of-process COM server,  let me just focus on explaining out-of-process COM only.  In-process COM has somewhat different mechanism – in order not to confuse I’ll rather leave it to some discussion later.

For out-of-process COM exe server like VISSIM,  a client program (a client program can be written in any COM compliant languages such as VB, VC++, .NET, or Delphi) starts a connection by calling Windows Operating System’s COM API in the following sequence:

1. CoCreateInstance

Nothing need to mention about this COM API.

 2. CoGetClassObject

For In-Process COM object, CoGetClassObject will get the pointer to the class factory; but for out-of-process COM exe like VISSIM, CoGetClassObject will get the VISSIM path from the ProgID in the system registry. Note, different versions of VISSIM has different ProgID. Also remember VISSIM is registered a LocalServer, so no DCOM is involved.

 3. CoRegisterClassObject

Once the system locates VISSIM.exe, CoRegisterClassObject (this is the ultimate ole32 API to be invoked, even VISSIM uses some .NET wrappers) – will be invoked in the start-up code before calling the WinMain entry function of VISSIM.exe.

 Here is the signature CoRegisterClassObject(CLSID, pUnk, dwClsContext, flags, &dwRegister). The key point is the fourth parameter “flags”. It determines during run-time whether VISSIM COM exe can be started as single instance or multiple instances. Check MSDN for more information about this COM API:

http://msdn.microsoft.com/en-us/library/ms693407%28VS.85%29.aspx

The fourth parameter is a REGCLS enumeration variable defined as:

typedef enum tagREGCLS { 
  REGCLS_SINGLEUSE       = 0,
  REGCLS_MULTIPLEUSE     = 1,
  REGCLS_MULTI_SEPARATE  = 2,
  REGCLS_SUSPENDED       = 4,
  REGCLS_SURROGATE       = 8
} REGCLS;

All we need to do is to  specify REGCLS_SINGLEUSE,  then VISSIM COM exe will be invoked in a “multi-instance” manner.  Why? Here is the description of the REGCLS flag:

  • REGCLS_SINGLEUSE

After an application is connected to a class object with CoGetClassObject, the class object is removed from public view so that no other applications can connect to it. This value is commonly used for single document interface (SDI) applications. Specifying this value does not affect the responsibility of the object application to call CoRevokeClassObject; it must always call CoRevokeClassObject when it is finished with an object class.

  • REGCLS_MULTIPLEUSE

Multiple applications can connect to the class object through calls to CoGetClassObject. If both the REGCLS_MULTIPLEUSE and CLSCTX_LOCAL_SERVER are set in a call to CoRegisterClassObject, the class object is also automatically registered as an in-process server, whether or not CLSCTX_INPROC_SERVER is explicitly set.

The above text is a little twisty – essentially it says, if REGCLS_SINGLEUSE is set, then any client connection request would result in creation of a new class object – in our case, the class object is VISSIM object represented by IVissim interface. Creating a new class object means starting a new VISSIM.exe process, because VISSIM.exe is the host of the class object. Period.

A little interesting additional information on what happens after CoRegisterClassObject – Internally, a I/O completion port (a.k.a IOCP) is created.  I/O completion port is a fairly low level Inter Process Communication (IPC) mechanism. By low level, I mean, File handle, Winsock2, name pipes etc all these higher level IPC mechanism would be built on top of I/O Completion port. So IOCP is pretty “ugly” if you ever bother to delve into that level to satisfy your peeking eyes and curiosity.

The created I/O completion port receives I/O completion packets then dispatches the package via Windows messaging then to the WndProc registered by ole32.dll. That WndProc then unmarshall the out-of-process COM method invocation and restores the original function’s stack frame, hence finishes the entire invocation COM function.

This creation of stack frame on the fly is similar to how web services are implemented. All are based on stack frames created during run time. Stack frame is just a memory footprint to prepare a function invocation, say, you need to allocate sufficient memories from the stack, then save all the current states registers and push the parameters. Of course, in COM, the convention is always stdcall.

Depending on the threading model the subject COM objects implements (single apartment, multiple apartment or whatever), there are some nuisances that I am not going to touch here.

Aimsun COM Interface (3) – Matlab example

Matlab is a very powerful computational platform that runs on multi-platforms, including Windows, Mac-OS, Linux… you name it.

On Microsoft Windows, Matlab provides pretty good support for COM automation. So today, let me illustrates a little Aimsun COM sample using Matlab.

When using Aimsun COM under Matlab environment, all the automation objects are accessed by the relevant IDispatch interface.

Here is the first line that creates a reference to the Aimsun Application object. ‘angcomsvr.AimsunServer’ is the progID, also in Matlab the string is single quoted, just like Pascal.

aimsunApp = actxserver(‘angcomsvr.AimsunServer’);

After creating the reference, we need to initialize the object by:.

aimsunApp.InitAimsunApp(0);

The integer parameter 0 will be marshalled as a boolean false, indicating that Aimsun is going to be started as “non-console”, i.e., GUI model.

Now that we have successfully initialized Aimsun App, we can now to whateve we like, e.g., open an network, generate new demand or run the simulation. All of these through line by line Matlab code, just like what you can usually do with Aimsun’s default Python scripting.

aimsunApp.OpenNetwork(‘D:\Network\whatever.ang’);

Or you can have a little fun by maximizing, minimizing, reposition the main Aimsun window:

aimsunApp.ShowMaximized;
aimsunApp.ShowMinimized;
aimsunApp.SetWindowPosition(0, 0, 150, 150);
aimsunApp.Run;

In order to close the Aimsun Application, use

aimsunApp.release

This will decrement the reference count and since the Aimsun COM is implemented as multi-instance COM server, decrementing the reference count by 1 will immediately drop it to 0, hence deleting the object from memory.

That is it. Next I will illustrate an Excel sample. Then I’ll show more complicated simulation scenario using Pascal.