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

Script Programming

Hushing the nagging screen from Syncrho Education Version

Synchro Education Edition – has a nagging screen EACH time the software is launched – Until you click “Accept”,  you will be going nowhere.

After “Accept” is clicked,  you will see the main UI water-marked with the line saying “Educational Use Only”.  Also you will experience a noticeable freezing period up to 1 or 2 seconds – the software is surreptitiously checking with a Trafficware server in Texas for any new version available, and verifying the license information.

This Fall semester I am teaching a Traffic Control & Simulation course at NYU-Poly, and get to use the Synchro academic version with some sort of frequency.  This nagging screen is becoming quite annoying to me – not to mention personally I tend to attribute this nagging trick as being somewhat paranoid and pointless, especially when the actual protection with Syncrho is shockingly weak.

I simply don’t like that each time I have to manually click the “Accept” button, in order to proceed. Don’t get me wrong,  this is not that I disagree with the terms,  just I don’t like manually doing it.  I would like to make a tool, and authorize the tool,  representing myself, to Agree and Accept to the license terms by clicking the “Accept”  button for me.

Therefore – with my tool of choice – AutoIt,  I prepared a little nifty script so that each time the software is launched, the computer itself will automatically click the button for me to Accept the terms – I don’t need to bother to move any of my fingers.

Wowooo – La!

The following is download link to the compiled version of the script, just put it anywhere on your computer’s desktop to replace the default Synchro shortcut lnkYou are still going to see the nagging screen appear, so you know what you are going to Accept,  but immediately it will be closed since the script, as authorized by you, and truly you,  automatically click the “Accept” button for you.  Besides,  the version checking window will be immediately closed as well,  and you won’t see the initial 1 or 2 seconds freezing period.  You can always to go to “Help” -> “Check for Updates” to do the explicit version check, yourself.

http://www.wupingxin.net/wx-files/synchro-8.7z

Use AutoIt Scripting to automatically Connect and Disconnect VPN

Assume a business model uses two database servers,  one is master, behind a corporate firewall; the other is a replication behind another firewall.  At midnight,  a one-way replication will be performed to sync the master database server with the replication one.  Before the synchronization is performed, a VPN connection needs to be established, and the VPN connection will be released after the synchronization is done.

Autoit at  http://www.autoitscript.com/site/autoit/ provides a very neat solution to automate this.  To to  that,  first create an Autoit script, then compile the script as an executable,  and schedule the executable  as a Windows task.

In order to make this work,  the scheduled task MUST be set as “Run only when user is logged on”.  This is because if not,  Windows OS will run the program in the background and Autoit cannot grab the window’s handle therefore any key strokes emulation will not work.

In summary,

  • Download AutoIt
  • Create a script like this:

[sourcecode]
Run("..\Cisco Systems\VPN Client\vpnclient.exe connect user aa pwd bb ")
Sleep(5000)
ControlSend("[CLASS:WinConsoleClass", "","","y")
Sleep(1000)
RunWait("dbsync.exe")
Run("C:\Program Files (x86)\Cisco Systems\VPN Client\vpnclient.exe disconnect")
[/sourcecode]

  • Use AutoIt compile the above script.
  • Set a scheduled task with Windows task scheduler, with “Run only when user is logged on” option selected.
  • Locked the user account for which the above task is scheduled.  This is important.  You must NOT log off because then the task will not be run (even you set it as “Run whether user is logged on or not“).  The reason is that,  when the CISCO VPN client connection is running in the background (i.e., “Run whether user is logged on or not” is selected),  it would NOT receive emulated key strokes to accept the connection.  As a result, the scheduled task will be launched but it will not continue and be hanging there forever.

In the above script,   RunWait command is used to launch the database synchronization program dbsync.exe.  Then the script execution waits till dbsync.exe finishes, before disconnecting the VPN connection.

Also noted that “ControlSend” is used instead of “Send” to send the emulated “y” key stroke,  as in the following script line:

[sourcecode]
ControlSend("[CLASS:WinConsoleClass", "","","y")
[/sourcecode]

Without the emulated “y”,  the CISCO VPN client will simply hang there forever,  waiting for the user’s confirmation.

The difference between “ControlSend” and “Send” is Send is going to send an emulated key stroke to the active window,  while ControlSend  to any window specified with its class title.  Send will not work with the logged user locked, since in that case there is no “active” window as seen by Autoit.

Before closing, there is one more point to note – remember not to open more than 1 cmd window.  This will confuse ControlSend, and the keystroke might be sent to the other cmd window than intended.

 

VISSIM Signal Control API: Let’s Talk about it

– This is a re-posted article from my previous one published at Blogline, with minor modifications.

Besides VAP, PTV provides Signal Control APIs for customized external signal control. To be sure, the Signal Control APIs provided by PTV include several header files and C++ source files. These files contains a plethora of information for any interested user to get some hint about the coding style and design patterns implemented in VISSIM simulator.

After studying the source codes for a few days, I am having great fun to read through the APIs and really get a grasp of the intended ideas of PTV developer(s). And, I am willing to share some hints here.


1. THE ORGNIZATION OF THE SIGNAL CONTROL API

The Signal Control APIs includes the following C++ source file

a. lsa_fehl.h/lsa_fehl.cpp: Utility functions showing various error messages are defined in these files; The messages information can be found from the string resource lsa_ra_e.rc
b. lsa_puff.h/lsa_puff.cp : Core data structures, such as T_DET, T_LSA_PUFFERare defined here.
c. lsa_rahm.h/lsa_rahm.cpp: These two files define some wrapper functions for sc_dll_functions. Mostly in German!  Oh, man! I wish I knew German – but at least, it is still C++ syntax, so couldn’t be worse than reading the bluntly sexy assembly code.
d. lsapuffr.h : Defines various Macros to facilitate the interfacing of VISSIM and the external controller. e. sc_dll_functions.h/sc_dll_functions.cpp : Various functions are defined here to provide read-write access to detector, signal controller, routing information.
f. sc_dll_main.h/sc_dll_main.cpp : the user mostly modifies the call back functions defined here to implement his control logic. This might involve calling the access functions defined in sc_dll_functions.h g. SC_Interface.h/SC_Interface.cpp : the interface functions that connect VISSIM and the controller are defined here.

2. MAJOR DATA STRUCTURES

The most important data structure is the sturct T_LSA_Puffer. This encapsulate Signal Controller Number, and pointers to detectors list. This struct is the building block of a LINKED LIST that contains a list of T_LSA_Puffer.

3. CONTROL FLOW

At the start of simulation, a LINKED LIST of T_LSA_Puffer will be constructed. The element of the linked list is individual T_LSA_Puffer, which corresponds to each individual signal controller, get initialized.

During the simulation, at each controller updating step, through ControllerSetValue function, VISSIM transfers a LARGE NUMBER of data, identified by the MACROS, to the signal control dll. These data is stored two places, one place the those global variables defined in lsa_puff.cpp, the other place is the LINKED LIST of T_LSA_Puffer.

It is important to NOTE, all the utility functions, and the functions defined in sc_dll_functions.h, are actually WRAPPER functions simply to facilitate the read-write of the LINKED LIST! THIS IS THE BEAUTY of the entire API package. I hope somebody can appreciate this like me.

Following this, VISSIM sequentially executes a few more call-back commands to get back the signal timing, specifically, with ControllerGetValue.

4. BIG PICTURE

The kernel of the Signal Control APIs is actually only two files , i.e., SC_interface.cpp/SC_interface.h. All the other files are wrappers that aim to organize and facilitate the signal timing calculation, read and write of various global variables.

From these Signal Control APIs and the wrapper files, we can get a grasp of the coding style of VISSIM in general and also some hints of the underlying design patters.

Overall, from the External Driver Module APIs as well as from this Signal Control APIs, it can be seen that, the philosophy of VISSM APIs is to use call back functions to expose data while the user have NO access to the internal of the program. This means, VISSIM doesn’t EXPORT any functions that the user can call. All the user can to is to process the data and send back the data to VISSIM via callback again. This allows flexibility on the user side, as he can freely develop wrapper class on top of the data. But the entire process is totally transparent to VISSIM.

Aimsun scripting: A different perspective

Aimsun is an Object-Oriented Framework and Unified Platform for Traffic Modeling.  It  provides quite a few programming interfaces for advanced applications and customization. To name a few,  those  include Aimsun Simulator API,  Aimsun SDK,  Aimsun Python-based Scripting,  MicroSDK,  Logistics SDK, Parking APIs.  These SDKs and APIs  together with Aimsun main software  provide powerful tools for its users.

Interestingly, by design all these APIs, albeit having different focuses, have ONE in common, i.e., they MUST either be invoked within Aimsun host ( e.g., Aimsun SDK and Aimsun Pyhton-based Scripting), or called-back during run time (i.e., simulator API and MicroSDK). This means Aimsun cannot be used as a COM automation sever, and therefore it may not be invoked by external applications.

Actually, it is only partially true.  First of all, this is not something to complain about.  Aimsun is a cross-platform software package;  it runs on Linux, MacOS, and Windows. COM is a very much Windows specific technology, so in spite of that it is doable it simply doesn’t seem to make much sense to dedicate Aimsun to a platform specific feature.  Second some the COM-like functionality can be achieved by using ANGApp class, which is fully accessible by Python scripting.

In this post,  I would like to discuss a way of porting ANGApp class by Python C API,  so that some of  its advanced functionality becomes available to a common compiler-based language.  To start with,  the following shows a Python wrapper class that encapsulate some COM-like interfaces, on top of the ANGApp class:

from PyANGBasic   import *
from PyANGApp     import *
from PyANGAimsun  import *
from PyANGKernel  import *
from PyANGConsole import *

__author__    = "Wuping Xin"
__company__   = "No Inc."
__copyright__ = "Copyright (c) No Rights Reserved"
__license__   = "python"
__version__   = "$1.0.0 $"
__date__      = "$Date: 2009/07/15 11:57 $"

class AimsunApp:
"Wrapper class of Aimsun ANGApp class for C++ application with Python C API"
def __init__(self, isCon = False):
  self.angInstance = None
  self.simulator   = None
  self.model       = None
  self.angGui      = None
  self.isConsole   = isCon
  def initInstance(self):
  pass

def freeInstance(self):
pass

def openNetwork(self,filename):
pass

def runInteractive(self):
  self.angInstance.run()

def __setModel(self):
  self.model = self.angInstance.getModel()

def initSimulator(self,repID,simMode = 0):

.......
def runSingleStep(self):
  self. angInstance.processEvents()
  self.simulator.simulationStep()

With this wrapper class ready, we can use the following C code to invoke:

Py_Initialize();
..........

pName    = PyString_FromString("aimsunpy_interface");
pModule  = PyImport_Import(pName);
pDict    = PyModule_GetDict(pModule);

// Build the name of a callable class
pClass = PyDict_GetItemString(pDict, "AimsunApp");

// Create an instance of the wrapper cls.
if (PyCallable_Check(pClass))
{
    pInstance = PyObject_CallObject(pClass, NULL);
}

PyObject_CallMethod(pInstance, "initInstance", NULL);
PyObject_CallMethod(pInstance, "openNetwork","s","C:\\Test\\test.ang");
PyObject_CallMethod(pInstance, "initSimulator","i",346);

This is a nuance to note – when trying to load a C-Extension module ( i.e., *.pyd file),  if the host program that embeds Python interpreter links with pythonxx_d.dll, then PyImport_Import will import the xxxx_d.pyd, even if the module’s name is specified without “_d”!  Also this approach is dependent on Aimsun’s embedded Python  interpreter hence there is some run-time performance hit. But if that is not an issue, this approach would make it possible to integrate Aimsun with external applications, for example, MATLAB platform.