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

Traffic Simulation

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)

 

The Move Constructor: A Linking Pitfall of Qt Library with Different Compilers

Move constructor is a C++11 feature from ISO/IEC14882:2011.  It enhanced the old-school C++ copy constructor by moving the resource of an object, instead of member-wise copying.  It is faster than a copy constructor.  Thus a C++11 compiler will generate six special member functions for a C++ object, including  move constructor and move assignment operator:

  • Default Constructor
  • Copy Constructor
  • Copy Assignment Operator
  • Destructor
  • Move Constructor
  • Move Assignment Operator

We are not going to discuss C++11 Move Constructor in details here –  better details and better explanations are there, and there.

The motivation of  this article,  is not to discuss the semantics or usage of Move Constructor,  but an interesting debugging experience, and the lessons learned which involves C++11 move constructor.

Long story short – I have been working on developing an advanced Qt-based C++ plugin DLL for a host software developed in Qt 4.8.7.   I was using Visual C++ 2010 compiler, and the Qt for VS2010 official release for commercial applications.

The plugin DLL is supposed to be dynamically loaded by the host via Qt’s QLibrary API (see my previous article on this subject), which internally will call Microsoft’s Win32 API LoadLibrary.  Somehow, I got the following error, when trying to load the DLL into the host software:

34f8:3518 @ 01570140 – LdrpGetProcedureAddress – INFO: Locating procedure “AcdssPluginFactory” by name
34f8:3518 @ 01570140 – LdrpNameToOrdinal – WARNING: Procedure “AcdssPluginFactory” could not be located in DLL at base 0x0B630000
34f8:3518 @ 01570140 – LdrpReportError – WARNING: Locating export “AcdssPluginFactory” for DLL “Unknown” failed with status: 0xc0000139
34f8:1168 @ 01570265 – LdrpReportError – ERROR: Locating export “??4QString@@QAEAAV0@$$QAV0@@Z” for DLL “C:\Program Files (x86)\…\plugins\acdssplugin.DLL” failed with status: 0xc0000139

The above debug messages were generated by GFlags Utility, which comes with Debugging Tools for Windows. You can find the most advanced debugging techniques including how to use GFlags utility from the excellent book Inside Windows Debugging.  In our case, we just need to set “Show Loader Snaps” flag, as shown in the figure.  This is a typical way of debugging LoadLibrary failures.

2016-10-12_21-41-26

Looking at the debug messages, it is simply pointing out that LoadLibrary fails because an exported function is missing from the image space – its C++ mangled name as  “??4QString@@QAEAAV0@$$QAV0@@Z”,  which can be interpreted as:


    ? = C++ mangled symbol
    ?4 = "operator="
    QString@ = the enclosing class, hence method name: QString::operator=
    @ = end of the scope
    Q = public
    A = no const and volatile qualifier
    E = __thiscall
    AAV0 = const ref to the first named class (QString) - the return value (const QString &)
    @ = end return type
    $$ = move constructor &&
    QAV0 = const pointer to first named class - QString * const
    @ = end parameter type
    @ = end parameters
    Z = function

So clearly, the host software was complaining that the Move Constructor of QString can not be located in any of the image space.  Upon further inspection of the host software, it is discovered it was compiled using VS2005.  QtCore4.dll does not have the Move Constructor generated with VC++ 2005 compiler.  

The solution is simple – just rebuilt the Qt 4.8.7 using VC++ 2005, and rebuilt the plugin DLL.  Above all, the lessons learned are:

Do NOT mix Qt library compiled with different compilers, EVEN with the same Qt Version.  Period.

VISSIM in VMWare: USB Passthrough Timeout with WiBu CodeMeter

Starting with VISSIM v8,  the CodeMeter dongle stores more licensing items than earlier versions. This may result in USB pass through timeout when running VISSIM from within a VMWare virtual machine.  We discuss this potential issue here and a fix is documented.

In a previous post, we have discussed running VISSIM in a VMWare Workstation  virtual environment:

2016-02-15_18-28-32

http://blog.wupingxin.net/2015/05/21/vmware-usb-passthrough-running-vissim-in-a-virtual-machine/

This should be working fine until PTV released VISSIM 8.0,  which is a great upgrade to v7 with a lot of nice additions and enhancements, especially the mesoscopic traffic simulation, to name just the most note-worthy.

For users of VISSIM v7,  the upgrade to V8 requires one unusual step to update the contents of the CodeMeter key.  And PTV apparently has more to feed into the dongle than old versions, thus after upgrading to VISSIM v8 with the “stuffed” CodeMeter dongle,  you might have problem launching VISSIM in a VMWare virtual machine,  something like this:  the code meter icon shows up in a yellowish-green color different than the normal color, while VISSIM complains “CmContainer entry not find Error 200”:2016-02-15_12-44-04

 

 

 

 

 

 

 

 

 

It is even more perplexing that there will be no problem running VISSIM with the same CodeMeter dongle, but on a direct physical computer. The virtual machine that you might encounter this issue includesWindows Server 2012 R2, Windows 10 x64 Pro. However, Windows 7 x64 virtual machine has no problem.

And you might see CodeMeter log output as follows:

2016-02-15 15:16:57: CodeMeter for Windows (B6.10.2018.501.32.180)
2016-02-15 15:16:57: Running on Microsoft Windows 10 Pro, 64-Bit
2016-02-15 15:16:57: Execution path: C:\Program Files (x86)\CodeMeter\Runtime\bin
2016-02-15 15:16:57: Found IPv4 address: 127.0.0.1 | 192.168.11.130
2016-02-15 15:16:57: Found IPv6 address: ::1 | fe80::a45b:71d5:41d1:150%3
2016-02-15 15:16:57: Used Communication Mode: IPv6 IPv4 SharedMemory
2016-02-15 15:16:57: Used IP address: default address
2016-02-15 15:16:57: Used IP port: 22350
2016-02-15 15:16:57: Used CmWAN port: 22351
2016-02-15 15:16:57: Multicast server search: not available
2016-02-15 15:16:57: Run as network server: no
2016-02-15 15:16:57: Run as CmWAN server: no
2016-02-15 15:16:57: Run as system service: yes
2016-02-15 15:16:57: Service startup delay:  0:08 minutes
2016-02-15 15:16:57: Box Access: use direct access mode
2016-02-15 15:16:59: Detecting CmContainer with Serial Number 2-2573687
2016-02-15 15:17:16: Runtime Event RT410-535 (2573687) occurred.
2016-02-15 15:17:46: Runtime Event RT410-535 (2573687) occurred.
2016-02-15 15:17:46: EBL-Trace: I1P1CX1CX1
2016-02-15 15:17:48: Event WB0407 (REPLUG) occurred: RePlug(2)
2016-02-15 15:17:48: Access from local(IPV6) to SubSystem (Handle 16)
2016-02-15 15:17:48: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:48: Handle 16 released
2016-02-15 15:17:48: Access from local(IPV6) to SubSystem (Handle 17)
2016-02-15 15:17:48: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:48: Handle 17 released
2016-02-15 15:17:48: Access from local(IPV6) to SubSystem (Handle 18)
2016-02-15 15:17:48: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:48: Handle 18 released
2016-02-15 15:17:48: Box Event HW04-529 (2573687) occurred.
2016-02-15 15:17:49: API Error 105 (INVALID PARAMETER) occurred!
2016-02-15 15:17:49: Access from local(IPV6) to SubSystem (Handle 22)
2016-02-15 15:17:49: API Error 105 (INVALID PARAMETER) occurred!
2016-02-15 15:17:49: Access from local(IPV6) to SubSystem (Handle 26)
2016-02-15 15:17:49: Access from local(IPV6) to SubSystem (Handle 27)
2016-02-15 15:17:49: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:49: Handle 27 released
2016-02-15 15:17:49: API Error 115 (WRONG HANDLE TYPE) occurred!
2016-02-15 15:17:49: Access from local(IPV6) to SubSystem (Handle 31)
2016-02-15 15:17:49: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:49: Handle 31 released
2016-02-15 15:17:55: API Error 105 (INVALID PARAMETER) occurred!
2016-02-15 15:17:55: Access from local(IPV6) to SubSystem (Handle 35)
2016-02-15 15:17:55: Access from local(IPV6) to SubSystem (Handle 36)
2016-02-15 15:17:55: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:55: Handle 36 released
2016-02-15 15:17:55: API Error 115 (WRONG HANDLE TYPE) occurred!
2016-02-15 15:17:55: API Error 105 (INVALID PARAMETER) occurred!
2016-02-15 15:17:55: Access from local(IPV6) to SubSystem (Handle 40)
2016-02-15 15:17:55: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:55: Handle 40 released

The problem  is really caused by USB timeouts when reading a large quantity of licenses.  This happens when CmStick uses the VMWare USB pass-through communication mode between CodeMeter Run-time Server (that is running inside the virtual machine) and CM-Stick (that is plugged via the host physical computer’s USB port).   That is why I believe that PTV has added a lot more license items into the CmStick than earlier versions, since this didn’t happen before.  The solution (thanks to the heads up from Mr. John Battista from WiBu USA) is to use the “File I/O” communication mode (UseUmsDA = 0) :

CodeMeter communication mode (on the virtual machine) can be changed  as follows:

1. In the virtual machine Guest OS, open the windows registry using regedit.exe

2. Go To: HKEY_LOCAL_MACHINE\SOFTWARE\WIBU-SYSTEMS\CodeMeter\Server\CurrentVersion

3. Set the “UseUmsDA” variable to 0

4. Restart CodeMeter Service, or restart the virtual machine directly

Then everything is working again.  Have fun!

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)

VMWare USB Passthrough: Running Vissim in a Virtual Machine

I bet it is not uncommon for someone to have a faint of heart at the idea of using VISSIM in a virtualized environment:

Using a virtual machine, it becomes easier and more orderly to debug and test various COM client applications, customized API DLLs and such, without messing around ordinary simulation projects . On the other hand, using a second virtual machine dedicated to traffic simulation models,  the project portfolio is organized and streamlined, while the IT administration load is simplified since a uniform work space is maintained between different modelers.

The following shows two snapshots of Vissim running inside a VMware 11.1.0 virtual machine.  In them, the Vissim instance was running smooth like a charm, without tangible performance hit, even running a 3D animation.

2015-05-22_15-33-35

VISSSIM 3D Animation in Virtual Machine

2015-05-22_15-28-37

VISSIM 2D Animation in Virtual Machine

In the above example, the hardware specification of the running computer is:

Host

  • WIN7x64
  • Intel i7-3920XM Quad Core@2.90GHz/3.1GHz
  • 32GB RAM(large host RAM will prevent frequent memory swapping)
  • Samsung 850 Pro SSD 1TB (SSD makes a big difference)

Guest

  • OS:Windows Server 2012 R2;
  • RAM: 8GB;
  • CPU: Enable the option “Virtualize Intel -VTx/EPT or AMD-V/RVI;
    • If the physical processor is enabled with EPT, this would give near native performance;
  • Graphic 3D and Graphic Memory setting as follows:

Virtual Machine Graphics Setting

The following is useful tips for improving Guest performance.

Add the following 3 lines in C:\ProgramData\VMware\VMware Workstation\settings.ini;

  • mainMem.useNamedFile = “FALSE”

This would disable the on-disk memory-swap file *.vmem, while forcing the virtual memory to be backed up by the host swap space. This means, if the host has enough physical RAM (e.g., 32GB),  all nominal guest-RAM will be allocated in host-memory hence improves performance.

  • MemTrimRate = “0”

This would disable memory page trimming. Memory trimming will return unused virtual machine memory to the host machine. By disabling such, the I/O is saved and will improve performance especially if the host is short of RAM.

  • scsi0:0.virtualSSD =  1

This is to explicitly let Guest OS know the virtual disk is SSD.

In order for the guest OS to see the hardware dongle,  the so-called USB Passthrough feature of VMWare is needed.  Of course, if the license is a network one, then this is a non issue – as long as the CodeMeter license server is configured , and the guest OS’ firewall set up properly.

To use USB Passthrough feature of VMWare, make sure the following services are enabled, or alternatively, make sure they are not disabled (See following figure) 💡 :

  • VMware Authorization Service
  • VMware USB Arbitration Service

 

2015-05-22_15-36-07

VMware Servivces Required for USB Passthrough

With the USB dongle plugged in the host’s USB port,  let go the “passthrough” by checking the “WIBU-Systems CodeMeter-Stick”, under VM->Removable Device.

2015-05-22_15-34-57

Connect the “Passthrough” CodeMeter Key in Virtual Machine

A cute example of Aimsun scripting

Aimsun is traffic simulation software developed by Transport Simulation System (TSS). It has a very powerful python-based scripting engine.  Though other traffic simulation software, e.g., PTV Vissim or Caliper TransModeler provides scripting functionality as well – yet Aimsun’s scripting engine has some unique features that make the scripting work not only productive, but also quite fun 😆 .

One such feature is the so-called live-binding of  a script to any selected object type.  

In Aimsun framework,  all elements of the simulation task – from network geometry,  control devices, script,  to menus, dialogs, projects, scenarios, algorithms …. everything … anything – is an “object”,  derived from a base class GKBaseObject which is rooted from Qt’s QObject.  The entire Aimsun software is built upon a Model-View-Controller (MVC) framework taking advantage of Qt framework.  This framework is well exposed to end users via its SDKs, APIs, and the Scripting Engine.  Apart from being a  comprehensive traffic simulation tool,  Aimsun presents itself as an excellent example of  modern design patterns and software engineering. It has very small memory footprint as well.

The following example comes with default Aimsun installation, i.e.,  the sample script No. 30 “Copy Control Plan”.

Please note, the latest Aimsun 8.0.x versions have some internal changes breaking the scripts that once had worked with Aimsun version 7.x. TSS releases  these scripts with the official Version 8.0.x without upgrading those scripts,  and you’ll have to fix them yourself.   (UPDATE: Aimsun 8.0.8 released on March 19, 2015 has fixed this.)

The following is the original script Copy Control Plan that comes with Aimsun official 8.0.x installation:

2015-03-06_22-26-59

In the above,  Line 3 – Line 7 should be replaced as follows:

2015-03-06_22-31-46

So, the script after the fix should look like the following:

2015-03-06_22-34-31

Some notes:

  • The object that the script binds to is represented by the name “target”. Therefore,  if the script is bound to node-type objects (e.g., the script is added to the context menu of node objects),  “target” would refer to the subject node object.  To bind a script to another  object,  you simply right click the script, select “Properties”. Then from “Settings” tab –> “Add Script to a Menu”, select an object type in the drop-down list “To Context Menu for Object Type” .  See the figure below.

2015-03-06_22-41-19

  • getControlPlan is called twice, at Line 11, and at Line 14. At Line 11,  it is called to get the source control plan object. At Line 14, it is called to get the destination control plan object.
  • GAnyObjectChooserEditor and GAnyObjectChooser are two interesting classes.  GAnyObjectChooserEditor is a later-addition.  Originally there was only GAnyObjectChooser class.  The helper class GAnyObjectChooserEditor is added to separate the chooser class and the editor class – a better design/refactoring but breaking some of the existing scripts .  Basically,  as its name indicates, it provides a user interface to choose an object of the specified type in Aimsun framework.  You can see it in action in the following figure:

2015-03-06_22-53-48

  •   chooser.setType is the one responsible for specifying what type of objects that the Editor dialog should present.

In summary – Aimsun python scripting engine are able to:

  1. Dynamically bind a script  to any objects during run-time;
  2. Inside the script engine, Aimsun provides ready-made UI elements to facilitate the interactions between the end user and the Aimsun host.  This allows productive and efficient workflow of simulation projects with the creative minds of a traffic modeler.
  3. Agree?  Any thoughts, or Aimsun scripting experience to share?

Brain-Wave Controlled Traffic Simulation: Control a Vissim Simulated Car (2)–Open Box

Emotiv  EPOC Neuroheadset  (Special LImited Edition) is priced a little over $400, and shipped in a nice box.  The package includes the headset, a sensor box with 16 sensors, a USB wireless receiver, and a charger. If you are willing to pay a little more, you can get an enhanced edition with firmware providing the raw EEG data. But I chose not to.

 

The following picture shows the package box.  The design is nice and the model in the picture looks cool.

10604536_10205375448368578_4169426888157101417_o

 

As you can see, the headset is sleek and looks with some Sci-Fi taste.  Can you see the he sensor sockets?

1529814_10205375449008594_7259397696980105817_o

This picture shows how it looks after all the sensor pads are put into the sockets.  They have to be soaked with the supplied saline liquid.

10714089_10205375450928642_1712280249339140873_o

 

This picture shows the SDK control panel. The diagram shows the sensor signals.

2014-11-06_22-10-19

The picture below shows the real-time charts of my brain activities, the Y axis represents the intensity of the signal. Different color of charts represents different emotions such as frustration, excitement, meditation etc.

Untitled

 

Clearly, the EEG data of my brain activities suggest I am amidst  potpourri emotions including frustration, excitement, boredom and others. Gee, I think I love this little Gadget.

 

(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)