diff --git a/src/tools/visualStates_py/.idea/inspectionProfiles/profiles_settings.xml b/src/tools/visualStates_py/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 000000000..c23ecacb3
--- /dev/null
+++ b/src/tools/visualStates_py/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/tools/visualStates_py/.idea/misc.xml b/src/tools/visualStates_py/.idea/misc.xml
new file mode 100644
index 000000000..5bbe586f1
--- /dev/null
+++ b/src/tools/visualStates_py/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/tools/visualStates_py/.idea/modules.xml b/src/tools/visualStates_py/.idea/modules.xml
new file mode 100644
index 000000000..f34e1f1dc
--- /dev/null
+++ b/src/tools/visualStates_py/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/tools/visualStates_py/.idea/visualStates_py.iml b/src/tools/visualStates_py/.idea/visualStates_py.iml
new file mode 100644
index 000000000..3f8acbf35
--- /dev/null
+++ b/src/tools/visualStates_py/.idea/visualStates_py.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/tools/visualStates_py/.idea/workspace.xml b/src/tools/visualStates_py/.idea/workspace.xml
new file mode 100644
index 000000000..578bbc8d4
--- /dev/null
+++ b/src/tools/visualStates_py/.idea/workspace.xml
@@ -0,0 +1,1124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ copyRuntime
+ self.configs
+ State
+ Transition
+ State.__i
+ generateInterfaces
+ comm.ini
+ #include
+ destroy
+ cmake
+ std::cout
+ cout
+ print
+ print(
+ print('
+ print('t
+ print('type
+ interface
+ interfaceHeaders
+ package
+ getFunction
+ functions
+ signal
+ varName[0]
+ parseFunctions
+ getVar
+ runCode
+ doc.create
+ getVariables
+ replace
+
+
+
+ Okan Asik
+
+
+ $PROJECT_DIR$
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ DEFINITION_ORDER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ project
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1499771568074
+
+
+ 1499771568074
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/tools/visualStates_py/codegen/cpp/runtimegui.cpp b/src/tools/visualStates_py/codegen/cpp/runtimegui.cpp
index eeae45a97..e6942d4fa 100644
--- a/src/tools/visualStates_py/codegen/cpp/runtimegui.cpp
+++ b/src/tools/visualStates_py/codegen/cpp/runtimegui.cpp
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -28,14 +29,14 @@
RunTimeGui::RunTimeGui() {
// create shared memory
- createSharedMem();
+ createSharedMemAndSemaphore();
pthread_create(&threadIPC, NULL, &RunTimeGui::loopStaticIPC, this);
- ipcData[0] == '0';
+
}
void RunTimeGui::emitRunningStateById(int id) {
std::stringstream strstream;
- strstream << "emitRunningStateById " << id;
+ strstream << "emitRunningStateById " << id << " ";
msgQueue.push(strstream.str());
// std::cout << "running state:" << id << std::endl;
}
@@ -43,13 +44,13 @@ void RunTimeGui::emitRunningStateById(int id) {
void RunTimeGui::emitLoadFromRoot() {
std::stringstream strstream;
// strstream << "emitLoadFromRoot";
- msgQueue.push(strstream.str());
+// msgQueue.push(strstream.str());
}
void RunTimeGui::emitActiveStateById(int id) {
std::stringstream strstream;
// strstream << "emitActiveStateById " << id;
- msgQueue.push(strstream.str());
+// msgQueue.push(strstream.str());
}
void* RunTimeGui::loopStaticIPC(void* owner) {
@@ -57,24 +58,34 @@ void* RunTimeGui::loopStaticIPC(void* owner) {
}
void RunTimeGui::loopIPC() {
+ struct sembuf sb = {0, 0, 0}; /* set to allocate resource */
+ int semop_result;
while(true) {
+// std::cout <<"data:"<< std::endl;
+// for (int i = 0; i < 1024; i++) {
+// std::cout << ipcData[i];
+// }
+// std::cout << ":data" << std::endl;
+// std::cout << "msg.size=" << msgQueue.size() << std::endl;
if (msgQueue.size() > 0) {
- if (ipcData[0] == '0') {
- std::string msg = msgQueue.front();
- msgQueue.pop();
- strncpy(ipcData, msg.c_str(), 1024);
- }
+ sb.sem_op = 0;
+ semop_result = semop(sem_id, &sb, 1);
+ std::string msg = msgQueue.front();
+ std::cout << "sending msg:" << msg << std::endl;
+ msgQueue.pop();
+ strncpy(ipcData, msg.c_str(), 1024);
+ sb.sem_op = 1;
+ semop_result = semop(sem_id, &sb, 1);
}
-
- usleep(1000);
+// usleep(1000);
}
}
-void RunTimeGui::createSharedMem() {
+void RunTimeGui::createSharedMemAndSemaphore() {
key_t fkey;
int shmid;
int mode;
- int numTrial = 15;
+ int numTrial = 10;
int trial = 0;
while (trial < numTrial) {
@@ -83,6 +94,7 @@ void RunTimeGui::createSharedMem() {
} else {
break;
}
+
trial++;
usleep(100000); // sleep for 100 milliseconds
}
@@ -94,9 +106,23 @@ void RunTimeGui::createSharedMem() {
return;
}
+ trial = 0;
+ while (trial < numTrial) {
+ if ((sem_id = semget(9, 1, 0)) == -1) {
+ std::cerr << "semget error with id 9 try for " << trial << std::endl;
+ } else {
+ break;
+ }
+
+ trial++;
+ usleep(100000); // sleep for 100 milliseconds
+ }
+
ipcData = (char*) shmat(shmid, (void *)0, 0);
if (ipcData == (char *)(-1)) {
std::cerr << "error shmat" << std::endl;
return;
}
+
+
}
diff --git a/src/tools/visualStates_py/codegen/cpp/runtimegui.h b/src/tools/visualStates_py/codegen/cpp/runtimegui.h
index c17fe9519..752cdb9de 100644
--- a/src/tools/visualStates_py/codegen/cpp/runtimegui.h
+++ b/src/tools/visualStates_py/codegen/cpp/runtimegui.h
@@ -27,10 +27,11 @@
class RunTimeGui {
protected:
pthread_t threadIPC;
+ int sem_id;
std::queue msgQueue;
char* ipcData;
- void createSharedMem();
+ void createSharedMemAndSemaphore();
public:
RunTimeGui();
diff --git a/src/tools/visualStates_py/codegen/cpp/temporaltransition.cpp b/src/tools/visualStates_py/codegen/cpp/temporaltransition.cpp
index 29963a58e..3adad6f3a 100644
--- a/src/tools/visualStates_py/codegen/cpp/temporaltransition.cpp
+++ b/src/tools/visualStates_py/codegen/cpp/temporaltransition.cpp
@@ -20,7 +20,8 @@
#include "temporaltransition.h"
#include
-TemporalTransition::TemporalTransition(int id, int destinationId, int elapsedTime):Transition(id, destinationId) {
+TemporalTransition::TemporalTransition(int id, int destinationId, int elapsedTime):
+ Transition(id, destinationId) {
this->elapsedTime = elapsedTime;
}
diff --git a/src/tools/visualStates_py/codegen/cpp/transition.h b/src/tools/visualStates_py/codegen/cpp/transition.h
index 94263b92a..6dac678ce 100644
--- a/src/tools/visualStates_py/codegen/cpp/transition.h
+++ b/src/tools/visualStates_py/codegen/cpp/transition.h
@@ -20,6 +20,8 @@
#ifndef TRANSITION_H
#define TRANSITION_H
+class State;
+
class Transition {
protected:
int id;
diff --git a/src/tools/visualStates_py/codegen/python/runtimegui.py b/src/tools/visualStates_py/codegen/python/runtimegui.py
index 5cb494727..481a33719 100644
--- a/src/tools/visualStates_py/codegen/python/runtimegui.py
+++ b/src/tools/visualStates_py/codegen/python/runtimegui.py
@@ -64,6 +64,7 @@ def __init__(self, parent=None):
self.memory = None
self.ipcThread = None
+ self.semaphore = None
def createTreeView(self):
dockWidget = QDockWidget()
@@ -209,37 +210,40 @@ def getStateList(self, state, stateList):
def loopIPC(self):
while True:
msg = self.getIPCMessage()
- if msg is not None and len(msg) > 0:
- methodName = msg.split(' ')[0]
- id = int(msg.split(' ')[1])
- if methodName == 'emitRunningStateById':
- self.emitRunningStateById(id)
- else:
- print('unknown method name')
-
- time.sleep(1.0/1000)
+ if msg is not None:
+ if len(msg) > 0:
+ msg = msg.strip()
+ methodName = msg.split(' ')[0]
+ id = int(msg.split(' ')[1])
+ if methodName == 'emitRunningStateById':
+ self.emitRunningStateById(id)
+ else:
+ print('unknown method name')
+
+ # time.sleep(1.0/1000)
def activateIPC(self):
try:
- self.memory = sysv_ipc.SharedMemory(123456, sysv_ipc.IPC_CREX)
+ self.memory = sysv_ipc.SharedMemory(123456, flags=sysv_ipc.IPC_CREAT, size = 1024)
+ except:
+ print('cannot create or open share mem with id 123456')
+ return
+
+ # create sempahore
+ try:
+ self.semaphore = sysv_ipc.Semaphore(9, flags=sysv_ipc.IPC_CREAT, initial_value=0)
except:
- # if memory exists just open shared memory
- self.memory = sysv_ipc.SharedMemory(123456)
+ print('cannot create or open semaphore with id 9')
+ self.memory.remove()
+ return
self.ipcThread = Thread(target=self.loopIPC)
self.ipcThread.start()
def getIPCMessage(self):
- if self.memory is not None:
- data = self.memory.read().decode()
- if data[0] != '0':
- self.memory.write('0'.encode())
- i = data.find('\0')
- if i != -1:
- data = data[:i]
- return data
-
- return None
+ self.semaphore.acquire()
+ data = self.memory.read().decode()
+ return data
diff --git a/src/tools/visualStates_py/codegen/python/temporaltransition.py b/src/tools/visualStates_py/codegen/python/temporaltransition.py
index 0f3ad0b93..6aed45360 100644
--- a/src/tools/visualStates_py/codegen/python/temporaltransition.py
+++ b/src/tools/visualStates_py/codegen/python/temporaltransition.py
@@ -20,8 +20,8 @@
from codegen.python.transition import Transition
from time import time
-class TemporalTransition(Transition, object):
- def __init__(self, id, destinationId, elapsedTime):
+class TemporalTransition(Transition):
+ def __init__(self, id, destinationId, elapsedTime):
super(TemporalTransition, self).__init__(id, destinationId)
# elapsed time in milliseconds
self.elapsedTime = elapsedTime
diff --git a/src/tools/visualStates_py/cpptest b/src/tools/visualStates_py/cpptest
new file mode 100755
index 000000000..f8412c220
Binary files /dev/null and b/src/tools/visualStates_py/cpptest differ
diff --git a/src/tools/visualStates_py/gui/cppgenerator.py b/src/tools/visualStates_py/gui/cppgenerator.py
index 87adaf7cd..5e46655ff 100644
--- a/src/tools/visualStates_py/gui/cppgenerator.py
+++ b/src/tools/visualStates_py/gui/cppgenerator.py
@@ -66,7 +66,7 @@ def getAllTransitions(self):
def generate(self, projectPath, projectName):
stringList = []
self.generateHeaders(stringList, projectName)
- self.generateInterfaceClasses(stringList)
+ self.generateInterfaceClass(stringList)
self.generateStateClasses(stringList)
self.generateTransitionClasses(stringList)
stringList.append('#endif')
@@ -79,7 +79,7 @@ def generate(self, projectPath, projectName):
self.generateHeadersForCpp(stringList, projectName)
self.generateStateMethods(stringList)
self.generateTranMethods(stringList)
- self.generateProxies(stringList, projectName)
+ self.generateInterfaceMethods(stringList, projectName)
self.generateReadArgs(stringList, projectName)
self.generateMain(stringList, projectName)
sourceCode = ''.join(stringList)
@@ -143,17 +143,12 @@ def generateStateClasses(self, classStr):
classStr.append('class State' + str(state.id) + ' : public State {\n')
classStr.append('public:\n')
classStr.append('\tInterfaces* interfaces;\n')
- classStr.append(state.getVariables())
classStr.append('\tState' + str(state.id) + '(int id, bool initial, Interfaces* interfaces, int cycleDuration, State* parent, RunTimeGui* gui):\n')
classStr.append('\t\tState(id, initial, cycleDuration, parent, gui) {this->interfaces = interfaces;}\n')
classStr.append('\tvirtual void runCode();\n')
-
- returnTypes, funcNames, codes = CPPParser.parseFunctions(state.getFunctions())
- for i in range(len(returnTypes)):
- classStr.append('\t' + returnTypes[i] + ' ' + funcNames[i] + ';\n')
-
classStr.append('};\n\n')
+
def generateTransitionClasses(self, classStr):
for tran in self.getAllTransitions():
if tran.getType() == TransitionType.CONDITIONAL:
@@ -169,11 +164,13 @@ def generateTransitionClasses(self, classStr):
elif tran.getType() == TransitionType.TEMPORAL:
classStr.append('class Tran' + str(tran.id) + ' : public TemporalTransition {\n')
classStr.append('\tpublic:\n')
- classStr.append('\tTran' + str(tran.id) + '(int id, int destId, int elapsedTime):TemporalTransition(id, destId, elapsedTime) {}\n')
+ classStr.append('\tTran' + str(tran.id) + '(int id, int destId, int elapsedTime):\n')
+ classStr.append('TemporalTransition(id, destId, elapsedTime) {}\n')
classStr.append('\tvirtual void runCode();\n')
classStr.append('};\n\n')
- def generateInterfaceClasses(self, classStr):
+
+ def generateInterfaceClass(self, classStr):
classStr.append('class Interfaces {\n')
classStr.append('public:\n')
classStr.append('\tComm::Communicator* jdrc;\n')
@@ -182,8 +179,18 @@ def generateInterfaceClasses(self, classStr):
classStr.append('\n')
classStr.append('\tvirtual void connectProxies(int argc, char* argv[]);\n')
classStr.append('\tvirtual void destroyProxies();\n')
+ for state in self.getAllStates():
+ # define variables
+ types, varNames, initialValues = CPPParser.parseVariables(state.getVariables())
+ for i in range(len(types)):
+ classStr.append('\t' + types[i] + ' ' + varNames[i] + ';\n')
+ classStr.append('\n')
+ returnTypes, funcNames, codes = CPPParser.parseFunctions(state.getFunctions())
+ for i in range(len(returnTypes)):
+ classStr.append('\t' + returnTypes[i] + ' ' + funcNames[i] + ';\n')
classStr.append('};\n\n')
+
def generateHeadersForCpp(self, headerStr, projectName):
headerStr.append('#include "' + projectName + '.h"\n')
headerStr.append('#include \n')
@@ -197,11 +204,6 @@ def generateStateMethods(self, stateStr):
stateStr.append('\t' + codeLine + '\n')
stateStr.append('}\n\n')
- returnTypes, funcNames, codes = CPPParser.parseFunctions(state.getFunctions())
- for i in range(len(returnTypes)):
- stateStr.append(returnTypes[i] + ' State' + str(state.id) + '::' + funcNames[i] + '\n')
- stateStr.append(codes[i])
- stateStr.append('\n\n')
def generateTranMethods(self, tranStr):
for tran in self.getAllTransitions():
@@ -209,7 +211,7 @@ def generateTranMethods(self, tranStr):
#todo: currently user does not provide init method
tranStr.append('void Tran' + str(tran.id) + '::init() {\n')
tranStr.append('}\n\n')
- tranStr.append('void Tran' + str(tran.id) + '::checkCondition() {\n')
+ tranStr.append('bool Tran' + str(tran.id) + '::checkCondition() {\n')
for codeLine in tran.getCondition().split('\n'):
tranStr.append('\t' + codeLine + '\n')
tranStr.append('}\n')
@@ -220,7 +222,7 @@ def generateTranMethods(self, tranStr):
tranStr.append('}\n\n')
- def generateProxies(self, proxyStr, projectName):
+ def generateInterfaceMethods(self, proxyStr, projectName):
proxyStr.append('void Interfaces::connectProxies(int argc, char* argv[]) {\n')
proxyStr.append('\tConfig::Properties props = Config::load(argc, argv);\n')
proxyStr.append('\tjdrc = new Comm::Communicator(props);\n\n')
@@ -229,13 +231,29 @@ def generateProxies(self, proxyStr, projectName):
proxyStr.append('\tif (' + cfg['name'] + ' == NULL) {\n')
proxyStr.append('\t\tthrow "invalid proxy ' + cfg['name'] + '";\n')
proxyStr.append('\t}\n')
- proxyStr.append('\tstd::cout << "' + cfg['name'] + ' is connected" << std::endl;\n')
+ proxyStr.append('\tstd::cout << "' + cfg['name'] + ' is connected" << std::endl;\n\n')
+
+ # set inital values of variables
+ for state in self.getAllStates():
+ types, varNames, initialValues = CPPParser.parseVariables(state.getVariables())
+ for i in range(len(types)):
+ if initialValues[i] is not None:
+ proxyStr.append('\t' + varNames[i] + ' = ' + initialValues[i] + ';\n')
+
proxyStr.append('}\n\n')
proxyStr.append('void Interfaces::destroyProxies() {\n')
proxyStr.append('\tif (jdrc != 0) {\n')
proxyStr.append('\t}\n}\n\n')
+ for state in self.getAllStates():
+ returnTypes, funcNames, codes = CPPParser.parseFunctions(state.getFunctions())
+ for i in range(len(returnTypes)):
+ proxyStr.append(returnTypes[i] + ' Interfaces::' + funcNames[i] + '\n')
+ proxyStr.append(codes[i])
+ proxyStr.append('\n\n')
+
+
def generateReadArgs(self, argStr, projectName):
mystr = '''
pthread_t guiThread;
@@ -308,11 +326,11 @@ def generateMain(self, mainStr, projectName):
# create transition instances
for tran in self.getAllTransitions():
if tran.getType() == TransitionType.CONDITIONAL:
- mainStr.append('\tTransition* tran' + str(tran.id) + ' = new Tran' + str(tran.id) + '(' + str(tran.id) +
- ', ' + str(tran.destination.id) + ', &interfaces);\n')
+ mainStr.append('\tTransition* tran' + str(tran.id) + ' = new Tran' + str(tran.id) +
+ '(' + str(tran.id) + ', ' + str(tran.destination.id) + ', &interfaces);\n')
elif tran.getType() == TransitionType.TEMPORAL:
- mainStr.append('\tTransition* tran' + str(tran.id) + ' = new Tran' + str(tran.id) + '(' + str(tran.id) +
- ', ' + str(tran.destination.id) + ', ' + str(tran.getTemporalTime()) + ');\n')
+ mainStr.append('\tTransition* tran' + str(tran.id) + ' = new Tran' + str(tran.id) +
+ '(' + str(tran.id) + ', ' + str(tran.destination.id) + ', ' + str(tran.getTemporalTime()) + ');\n')
mainStr.append('\tstate' + str(tran.origin.id) + '->addTransition(tran' + str(tran.id) + ');\n')
mainStr.append('\n')
diff --git a/src/tools/visualStates_py/gui/cppparser.py b/src/tools/visualStates_py/gui/cppparser.py
index 90fd395f4..f3c20f302 100644
--- a/src/tools/visualStates_py/gui/cppparser.py
+++ b/src/tools/visualStates_py/gui/cppparser.py
@@ -42,11 +42,11 @@ def parseFunctions(funcStr):
firstCurlyIndex = None
lastCurlyIndex = None
for i, ch in enumerate(funcStr):
-
if ch == '{':
curlyCounter += 1
- firstCurlyFound = True
- firstCurlyIndex = i
+ if not firstCurlyFound:
+ firstCurlyFound = True
+ firstCurlyIndex = i
elif ch == '}':
curlyCounter -= 1
@@ -70,6 +70,34 @@ def parseFunctions(funcStr):
return returnTypes, funcNames, codes
+ @staticmethod
+ def parseVariables(variableStr):
+ types = []
+ varNames = []
+ initialValues = []
+ variableStr = variableStr.strip()
+ variableLines = variableStr.split(';')
+ for varLine in variableLines:
+ varLine = varLine.strip()
+ if len(varLine) == 0:
+ continue
+
+ varType = varLine[0:varLine.find(' ')]
+ varName = None
+ initalValue = None
+ if varLine.find('=') >= 0:
+ # if there is initial value
+ varName = varLine[varLine.find(' ')+1:varLine.find('=')].strip()
+ initialValue = varLine[varLine.find('=')+1:].strip()
+ else:
+ varName = varLine[varLine.find(' ')+1:].strip()
+
+ types.append(varType)
+ varNames.append(varName)
+ initialValues.append(initialValue)
+
+ return types, varNames, initialValues
+
if __name__ == '__main__':
sampleCode = '''
@@ -83,6 +111,9 @@ def parseFunctions(funcStr):
c = 10;
d = 12;
a = c*d*b;
+ if ( a == 2) {
+ b = 3;
+ }
return a;
}
@@ -93,12 +124,27 @@ def parseFunctions(funcStr):
int b = 324;
int c = 0;
c = a + b;
+ for (int i = 0; i < 10; i++) {
+ c = a + b;
+ }
}
'''
- returnTypes, funcNames, codes = CPPParser.parseFunctions(sampleCode)
- for i in range(len(returnTypes)):
- print(returnTypes[i])
- print(funcNames[i])
- print(codes[i])
- # print(returnType, funcName)
\ No newline at end of file
+ # returnTypes, funcNames, codes = CPPParser.parseFunctions(sampleCode)
+ # for i in range(len(returnTypes)):
+ # print(returnTypes[i])
+ # print(funcNames[i])
+ # print(codes[i])
+ # print(returnType, funcName)
+
+ sampleVariables = '''
+ int a = 12; int b = 23;
+ float myVar; float myVar2 = 12.2;
+ '''
+
+ types, varNames, initialValues = CPPParser.parseVariables(sampleVariables)
+ for i in range(len(types)):
+ print(types[i])
+ print(varNames[i])
+ print(initialValues[i])
+
diff --git a/src/tools/visualStates_py/gui/cpprosgenerator.py b/src/tools/visualStates_py/gui/cpprosgenerator.py
index 6979d38a0..7ae7f3b3c 100644
--- a/src/tools/visualStates_py/gui/cpprosgenerator.py
+++ b/src/tools/visualStates_py/gui/cpprosgenerator.py
@@ -22,18 +22,16 @@
from gui.cmakevars import CMAKE_INSTALL_PREFIX
from gui.cppparser import CPPParser
from xml.dom import minidom
-import os, stat, shutil
+import os, stat
class CppRosGenerator(CppGenerator):
def __init__(self, libraries, config, interfaceHeaders, states):
CppGenerator.__init__(self, libraries, config, interfaceHeaders, states)
def generate(self, projectPath, projectName):
- # create src folder in the projects
- if os.path.exists(projectPath + '/src'):
- shutil.rmtree(projectPath + '/src')
-
- os.mkdir(projectPath + '/src')
+ # create source dir if not exists
+ if not os.path.exists(projectPath + os.sep + 'src'):
+ os.makedirs(projectPath + os.sep + 'src')
stringList = []
self.generateHeaders(stringList, projectName)
@@ -55,10 +53,6 @@ def generate(self, projectPath, projectName):
self.generateMain(stringList, projectName)
sourceCode = ''.join(stringList)
- # create source dir if not exists
- if not os.path.exists(projectPath + os.sep + 'src'):
- os.makedirs(projectPath + os.sep + 'src')
-
fp = open(projectPath + os.sep + 'src' + os.sep + projectName + '.cpp', 'w')
fp.write(sourceCode)
fp.close()
@@ -84,8 +78,6 @@ def generate(self, projectPath, projectName):
with open(projectPath + os.sep + 'package.xml', 'w') as f:
f.write(xmlStr)
- self.copyRunTime(projectPath)
-
def generateHeaders(self, headers, projectName):
headers.append('#ifndef ' + projectName + '_H\n')
@@ -120,7 +112,9 @@ def generateRosNodeClass(self, classStr, config):
classStr.append('\tpthread_t thread;\n\n')
for topic in config.getTopics():
- varName = topic['name'].replace('/', '-')
+ varName = topic['name'].replace('/', '_')
+ if varName[0] == '_':
+ varName = varName[1:]
if topic['opType'] == 'Publish':
classStr.append('\tros::Publisher ' + varName + 'Pub;\n')
@@ -144,7 +138,9 @@ def generateRosNodeClass(self, classStr, config):
classStr.append('\tvoid join();\n\n')
for topic in config.getTopics():
- varName = topic['name'].replace('/', '-')
+ varName = topic['name'].replace('/', '_')
+ if varName[0] == '_':
+ varName = varName[1:]
if topic['opType'] == 'Subscribe':
type = topic['type']
@@ -161,6 +157,17 @@ def generateRosNodeClass(self, classStr, config):
else:
classStr.append('\tvoid publish' + varName + '(' + type + '& ' + varName + ');\n')
classStr.append('\n')
+
+ for state in self.getAllStates():
+ # define variables
+ types, varNames, initialValues = CPPParser.parseVariables(state.getVariables())
+ for i in range(len(types)):
+ classStr.append('\t' + types[i] + ' ' + varNames[i] + ';\n')
+ classStr.append('\n')
+ returnTypes, funcNames, codes = CPPParser.parseFunctions(state.getFunctions())
+ for i in range(len(returnTypes)):
+ classStr.append('\t' + returnTypes[i] + ' ' + funcNames[i] + ';\n')
+
classStr.append('};\n\n')
def generateStateClasses(self, classStr):
@@ -168,15 +175,10 @@ def generateStateClasses(self, classStr):
classStr.append('class State' + str(state.id) + ' : public State {\n')
classStr.append('public:\n')
classStr.append('\tRosNode* node;\n')
- classStr.append(state.getVariables())
classStr.append('\tState' + str(state.id) + '(int id, bool initial, RosNode* node, int cycleDuration, State* parent, RunTimeGui* gui):\n')
classStr.append('\t\tState(id, initial, cycleDuration, parent, gui) {this->node = node;}\n')
classStr.append('\tvirtual void runCode();\n')
- returnTypes, funcNames, codes = CPPParser.parseFunctions(state.getFunctions())
- for i in range(len(returnTypes)):
- classStr.append('\t' + returnTypes[i] + ' ' + funcNames[i] + ';\n')
-
classStr.append('};\n\n')
def generateTransitionClasses(self, classStr):
@@ -203,14 +205,16 @@ def generateHeadersForCpp(self, headerStr, projectName):
headerStr.append('#include \n')
headerStr.append('#include \n')
headerStr.append('#include \n')
- headerStr.append('#include \n')
- headerStr.append('#include \n\n');
+ headerStr.append('#include \n\n')
def generateRosMethods(self, rosStr, config):
rosStr.append('RosNode::RosNode(int nodeRate):rate(nodeRate) {\n')
for topic in config.getTopics():
- varName = topic['name'].replace('/', '-')
+ varName = topic['name'].replace('/', '_')
+ if varName[0] == '_':
+ varName = varName[1:]
+
type = topic['type']
types = type.split('/')
if topic['opType'] == 'Publish':
@@ -221,6 +225,14 @@ def generateRosMethods(self, rosStr, config):
'name'] + '", 10);\n')
elif topic['opType'] == 'Subscribe':
rosStr.append('\t' + varName + 'Sub = nh.subscribe("' + topic['name'] + '", 10, &RosNode::'+varName+'Callback, this);\n')
+
+ # set inital values of variables
+ for state in self.getAllStates():
+ types, varNames, initialValues = CPPParser.parseVariables(state.getVariables())
+ for i in range(len(types)):
+ if initialValues[i] is not None:
+ rosStr.append('\t' + varNames[i] + ' = ' + initialValues[i] + ';\n')
+
rosStr.append('}\n\n')
rosStr.append('void* RosNode::threadRunner(void* owner) {\n')
@@ -243,7 +255,10 @@ def generateRosMethods(self, rosStr, config):
rosStr.append('}\n\n')
for topic in config.getTopics():
- varName = topic['name'].replace('/', '-')
+ varName = topic['name'].replace('/', '_')
+ if varName[0] == '_':
+ varName = varName[1:]
+
if topic['opType'] == 'Subscribe':
type = topic['type']
types = type.split('/')
@@ -272,6 +287,12 @@ def generateRosMethods(self, rosStr, config):
rosStr.append('\t' + varName + 'Pub.publish(' + varName + ');\n')
rosStr.append('}\n\n')
+ for state in self.getAllStates():
+ returnTypes, funcNames, codes = CPPParser.parseFunctions(state.getFunctions())
+ for i in range(len(returnTypes)):
+ rosStr.append(returnTypes[i] + ' RosNode::' + funcNames[i] + '\n')
+ rosStr.append(codes[i])
+ rosStr.append('\n\n')
def generateReadArgs(self, argStr, projectName):
@@ -305,9 +326,7 @@ def generateReadArgs(self, argStr, projectName):
'''
argStr.append(mystr)
argStr.append('void* runGui(void*) {\n')
- argStr.append('\tstd::string path = ros::package::getPath("' + projectName + '");\n')
- argStr.append('\tpath.append("/'+projectName+'_runtime.py");\n')
- argStr.append('\tsystem(path.c_str());\n')
+ argStr.append('\tsystem("./' + projectName + '_runtime.py");\n')
argStr.append('}\n\n')
def parentString(self, state):
@@ -361,7 +380,7 @@ def generateMain(self, mainStr, projectName):
mainStr.append('\tstate' + str(state.id) + '->startThread();\n')
mainStr.append('\n')
- mainStr.append('signal(SIGINT, signalCallback);\n')
+ mainStr.append('\tsignal(SIGINT, signalCallback);\n')
for state in self.states:
mainStr.append('\tstate' + str(state.id) + '->join();\n')
@@ -371,6 +390,7 @@ def generateRunTimeGui(self, guiStr):
guiStr.append('#!/usr/bin/python\n')
guiStr.append('# -*- coding: utf-8 -*-\n')
guiStr.append('import sys\n')
+ guiStr.append('sys.path.append("' + CMAKE_INSTALL_PREFIX + '/lib/python2.7/visualStates_py")\n\n')
guiStr.append('from PyQt5.QtWidgets import QApplication\n')
guiStr.append('from codegen.python.runtimegui import RunTimeGui\n\n')
@@ -416,22 +436,30 @@ def generateCmake(self, cmakeStr, projectName, config):
cmakeStr.append('find_package(catkin REQUIRED COMPONENTS\n')
for dep in config.getBuildDependencies():
cmakeStr.append(' ' + dep + '\n')
- cmakeStr.append(' roslib\n')
cmakeStr.append(')\n\n')
cmakeStr.append('SET(JDEROBOT_INSTALL_PATH ' + CMAKE_INSTALL_PREFIX + ')\n')
myStr = '''
+SET(JDEROBOT_INCLUDE_DIR ${JDEROBOT_INSTALL_PATH}/include)
+SET(VISUALSTATE_RUNTIME_INCLUDE_DIR ${JDEROBOT_INSTALL_PATH}/include/visualstates_py)
+SET(JDEROBOT_LIBS_DIR ${JDEROBOT_INSTALL_PATH}/lib)
+SET(VISUALSTATE_RUNTIME_LIBS_DIR ${JDEROBOT_INSTALL_PATH}/lib/visualstates_py)
+
include_directories(
${catkin_INCLUDE_DIRS}
- src
+ ${JDEROBOT_INCLUDE_DIR}
+ ${VISUALSTATE_RUNTIME_INCLUDE_DIR}
)
+link_directories(
+ ${JDEROBOT_LIBS_DIR}
+ ${VISUALSTATE_RUNTIME_LIBS_DIR}
+)
'''
cmakeStr.append(myStr)
cmakeStr.append('catkin_package()\n')
- cmakeStr.append('add_executable(' + projectName + '\n src/' + projectName + '.cpp\n src/runtimegui.cpp\n \
- src/state.cpp\n src/temporaltransition.cpp\n src/transition.cpp\n )\n')
- cmakeStr.append('target_link_libraries(' + projectName + ' ${catkin_LIBRARIES})\n')
+ cmakeStr.append('add_executable(' + projectName + ' src/' + projectName + '.cpp)\n')
+ cmakeStr.append('target_link_libraries(' + projectName + ' ${catkin_LIBRARIES} visualStatesRunTime)\n')
cmakeStr.append('install(TARGETS ' + projectName + ' RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})\n\n')
return cmakeStr
@@ -462,19 +490,11 @@ def generatePackageXml(self, config, projectName):
bdepElement.appendChild(doc.createTextNode(bdep))
root.appendChild(bdepElement)
- bdepElement = doc.createElement('build_depend')
- bdepElement.appendChild(doc.createTextNode('roslib'))
- root.appendChild(bdepElement)
-
for rdep in config.getRunDependencies():
rdepElement = doc.createElement('run_depend')
rdepElement.appendChild(doc.createTextNode(rdep))
root.appendChild(rdepElement)
- rdepElement = doc.createElement('run_depend')
- rdepElement.appendChild(doc.createTextNode('roslib'))
- root.appendChild(rdepElement)
-
exportElement = doc.createElement('export')
root.appendChild(exportElement)
doc.appendChild(root)
@@ -482,37 +502,6 @@ def generatePackageXml(self, config, projectName):
return doc
- def copyRunTime(self, projectPath):
- if os.path.exists(projectPath + '/codegen'):
- shutil.rmtree(projectPath + '/codegen')
- if os.path.exists(projectPath + '/gui'):
- shutil.rmtree(projectPath + '/gui')
-
- shutil.copytree(CMAKE_INSTALL_PREFIX + '/lib/python2.7/visualStates_py/codegen', projectPath + '/codegen')
- shutil.copytree(CMAKE_INSTALL_PREFIX + '/lib/python2.7/visualStates_py/gui', projectPath + '/gui')
-
- shutil.copy(CMAKE_INSTALL_PREFIX + '/share/visualstates_py/conditionaltransition.h',
- projectPath + '/src/conditionaltransition.h')
- shutil.copy(CMAKE_INSTALL_PREFIX + '/share/visualstates_py/runtimegui.h',
- projectPath + '/src/runtimegui.h')
- shutil.copy(CMAKE_INSTALL_PREFIX + '/share/visualstates_py/runtimegui.cpp',
- projectPath + '/src/runtimegui.cpp')
- shutil.copy(CMAKE_INSTALL_PREFIX + '/share/visualstates_py/state.h',
- projectPath + '/src/state.h')
- shutil.copy(CMAKE_INSTALL_PREFIX + '/share/visualstates_py/state.cpp',
- projectPath + '/src/state.cpp')
- shutil.copy(CMAKE_INSTALL_PREFIX + '/share/visualstates_py/temporaltransition.h',
- projectPath + '/src/temporaltransition.h')
- shutil.copy(CMAKE_INSTALL_PREFIX + '/share/visualstates_py/temporaltransition.cpp',
- projectPath + '/src/temporaltransition.cpp')
- shutil.copy(CMAKE_INSTALL_PREFIX + '/share/visualstates_py/transition.h',
- projectPath + '/src/transition.h')
- shutil.copy(CMAKE_INSTALL_PREFIX + '/share/visualstates_py/transition.cpp',
- projectPath + '/src/transition.cpp')
-
-
-
-
diff --git a/src/tools/visualStates_py/gui/pythongenerator.py b/src/tools/visualStates_py/gui/pythongenerator.py
index 763a10b14..f0025de4c 100644
--- a/src/tools/visualStates_py/gui/pythongenerator.py
+++ b/src/tools/visualStates_py/gui/pythongenerator.py
@@ -74,9 +74,6 @@ def generate(self, projectPath, projectName):
fp.close()
self.generateAndSaveCfgYaml(projectPath, projectName)
- #fp = open(projectPath + os.sep + projectName + '.cfg', 'w')
- #fp.write(''.join(stringList))
- #fp.close()
os.system('chmod +x ' + projectPath + os.sep + projectName + '.py')
@@ -108,8 +105,6 @@ def generateImports(self, headerStr):
# headerStr.append(cfg['interface'])
# headerStr.append('Prx\n')
- headerStr.append('import comm\n')
-
headerStr.append('\n')
return headerStr
@@ -125,13 +120,7 @@ def generateStateClass(self, state, stateStr):
stateStr.append('\tdef __init__(self, id, initial, interfaces, cycleDuration, parent=None, gui=None):\n')
stateStr.append('\t\tState.__init__(self, id, initial, cycleDuration, parent, gui)\n')
- stateStr.append('\t\tself.interfaces = interfaces\n')
-
- if len(state.getVariables()) > 0:
- for varLine in state.getVariables().split('\n'):
- stateStr.append('\t\t' + varLine + '\n')
- stateStr.append('\n')
- stateStr.append('\n')
+ stateStr.append('\t\tself.interfaces = interfaces\n\n')
stateStr.append('\tdef runCode(self):\n')
if len(state.getCode()) > 0:
@@ -141,10 +130,6 @@ def generateStateClass(self, state, stateStr):
stateStr.append('\t\tpass\n')
stateStr.append('\n')
- if len(state.getFunctions()) > 0:
- for funcLine in state.getFunctions().split('\n'):
- stateStr.append('\t' + funcLine + '\n')
- stateStr.append('\n')
def generateInterfaces(self, interfaceStr, projectName):
mystr = '''class Interfaces():
@@ -155,6 +140,15 @@ def generateInterfaces(self, interfaceStr, projectName):
for cfg in self.config.getInterfaces():
interfaceStr.append('\t\tself.' + cfg['name'] + ' = None\n')
+ for state in self.getAllStates():
+ if len(state.getVariables()) > 0:
+ for varLine in state.getVariables().split('\n'):
+ varLine = varLine.strip()
+ if len(varLine) > 0:
+ interfaceStr.append('\t\t' + varLine + '\n')
+
+ interfaceStr.append('\n')
+
interfaceStr.append('\t\tself.connectProxies()\n\n')
interfaceStr.append('\tdef connectProxies(self):\n')
@@ -173,20 +167,25 @@ def generateInterfaces(self, interfaceStr, projectName):
interfaceStr.append('\t\tif self.jdrc is not None:\n')
interfaceStr.append('\t\t\tself.jdrc.destroy()\n\n')
+ for state in self.getAllStates():
+ if len(state.getFunctions()) > 0:
+ for funcLine in state.getFunctions().split('\n'):
+ interfaceStr.append('\t' + funcLine + '\n')
+ interfaceStr.append('\n')
+
def generateTransitionClasses(self, tranStr):
for tran in self.getAllTransitions():
if tran.getType() == TransitionType.CONDITIONAL:
tranStr.append('class Tran' + str(tran.id) + '(ConditionalTransition):\n')
- tranStr.append('\tdef __init__(self, id, destinationId, interfaces)\n')
+ tranStr.append('\tdef __init__(self, id, destinationId, interfaces):\n')
tranStr.append('\t\tConditionalTransition.__init__(self, id, destinationId)\n')
tranStr.append('\t\tself.interfaces = interfaces\n\n')
tranStr.append('\tdef checkCondition(self):\n')
for checkLine in tran.getCondition().split('\n'):
- tranStr.append('\t\treturn ' + checkLine + '\n')
+ tranStr.append('\t\t' + checkLine + '\n')
tranStr.append('\n')
elif tran.getType() == TransitionType.TEMPORAL:
tranStr.append('class Tran' + str(tran.id) + '(TemporalTransition):\n\n')
-
tranStr.append('\tdef runCode(self):\n')
if len(tran.getCode()) > 0:
for codeLine in tran.getCode().split('\n'):
diff --git a/src/tools/visualStates_py/gui/pythonrosgenerator.py b/src/tools/visualStates_py/gui/pythonrosgenerator.py
index 84d88ce1d..d417a124d 100644
--- a/src/tools/visualStates_py/gui/pythonrosgenerator.py
+++ b/src/tools/visualStates_py/gui/pythonrosgenerator.py
@@ -134,13 +134,7 @@ def generateStateClass(self, state, stateStr):
stateStr.append('\tdef __init__(self, id, initial, rosNode, cycleDuration, parent=None, gui=None):\n')
stateStr.append('\t\tState.__init__(self, id, initial, cycleDuration, parent, gui)\n')
- stateStr.append('\t\tself.rosNode = rosNode\n')
-
- if len(state.getVariables()) > 0:
- for varLine in state.getVariables().split('\n'):
- stateStr.append('\t\t' + varLine + '\n')
- stateStr.append('\n')
- stateStr.append('\n')
+ stateStr.append('\t\tself.rosNode = rosNode\n\n')
stateStr.append('\tdef runCode(self):\n')
if len(state.getCode()) > 0:
@@ -148,12 +142,7 @@ def generateStateClass(self, state, stateStr):
stateStr.append('\t\t' + codeLine + '\n')
else:
stateStr.append('\t\tpass\n')
- stateStr.append('\n')
-
- if len(state.getFunctions()) > 0:
- for funcLine in state.getFunctions().split('\n'):
- stateStr.append('\t' + funcLine + '\n')
- stateStr.append('\n')
+ stateStr.append('\n\n')
def generateRosInterface(self, rosNodeStr, projectName):
rosNodeStr.append('class RosNode():\n')
@@ -163,14 +152,22 @@ def generateRosInterface(self, rosNodeStr, projectName):
if topic['opType'] == 'Publish':
typesStr = topic['type']
types = typesStr.split('/')
- rosNodeStr.append('\t\tself.' + topic['name'] + 'Pub = rospy.Publisher("' +
+ rosNodeStr.append('\t\tself.' + self.getVarName(topic['name']) + 'Pub = rospy.Publisher("' +
topic['name'] + '", ' + types[1] + ', queue_size=10)\n')
elif topic['opType'] == 'Subscribe':
typesStr = topic['type']
types = typesStr.split('/')
- rosNodeStr.append('\t\tself.' + topic['name'] + 'Sub = rospy.Subscriber("' +
- topic['name'] + '", ' + types[1] + ', self.'+topic['name']+'Callback)\n')
- rosNodeStr.append('\t\tself.' + topic['name'] + ' = ' + types[1] + '()\n')
+ rosNodeStr.append('\t\tself.' + self.getVarName(topic['name']) + 'Sub = rospy.Subscriber("' +
+ topic['name'] + '", ' + types[1] + ', self.'+self.getVarName(topic['name'])+'Callback)\n')
+ rosNodeStr.append('\t\tself.' + self.getVarName(topic['name']) + ' = ' + types[1] + '()\n')
+
+ # add state variables as part of ros node
+ for state in self.getAllStates():
+ if len(state.getVariables()) > 0:
+ for varLine in state.getVariables().split('\n'):
+ rosNodeStr.append('\t\t' + varLine + '\n')
+ rosNodeStr.append('\n')
+
rosNodeStr.append('\t\ttime.sleep(1) # wait for initialization of the node, subscriber, and publisher\n\n')
rosNodeStr.append('\tdef stop(self):\n')
@@ -179,13 +176,21 @@ def generateRosInterface(self, rosNodeStr, projectName):
# define publisher methods and subscriber callbacks
for topic in self.config.getTopics():
if topic['opType'] == 'Publish':
- rosNodeStr.append('\tdef publish' + topic['name'] + '(self, ' + topic['name'] + '):\n')
- rosNodeStr.append('\t\tself.' + topic['name'] + 'Pub.publish(' + topic['name'] + ')\n\n')
+ rosNodeStr.append('\tdef publish' + self.getVarName(topic['name']) + '(self, ' + self.getVarName(topic['name']) + '):\n')
+ rosNodeStr.append('\t\tself.' + self.getVarName(topic['name']) + 'Pub.publish(' + self.getVarName(topic['name']) + ')\n\n')
elif topic['opType'] == 'Subscribe':
- rosNodeStr.append('\tdef ' + topic['name'] + 'Callback(self, ' + topic['name'] + '):\n')
- rosNodeStr.append('\t\tself.' + topic['name'] + ' = ' + topic['name'] + '\n')
+ rosNodeStr.append('\tdef ' + self.getVarName(topic['name']) + 'Callback(self, ' + self.getVarName(topic['name']) + '):\n')
+ rosNodeStr.append('\t\tself.' + self.getVarName(topic['name']) + ' = ' + self.getVarName(topic['name']) + '\n')
rosNodeStr.append('\n\n')
+ # define user functions as part of rosnode
+ for state in self.getAllStates():
+ if len(state.getFunctions()) > 0:
+ for funcLine in state.getFunctions().split('\n'):
+ rosNodeStr.append('\t' + funcLine + '\n')
+ rosNodeStr.append('\n\n')
+
+
def generateTransitionClasses(self, tranStr):
for tran in self.getAllTransitions():
if tran.getType() == TransitionType.CONDITIONAL:
@@ -195,7 +200,7 @@ def generateTransitionClasses(self, tranStr):
tranStr.append('\t\tself.rosNode = rosNode\n\n')
tranStr.append('\tdef checkCondition(self):\n')
for checkLine in tran.getCondition().split('\n'):
- tranStr.append('\t\treturn ' + checkLine + '\n')
+ tranStr.append('\t\t' + checkLine + '\n')
tranStr.append('\n')
elif tran.getType() == TransitionType.TEMPORAL:
tranStr.append('class Tran' + str(tran.id) + '(TemporalTransition):\n\n')
@@ -366,8 +371,15 @@ def generatePackageXml(self, config, projectName):
def copyRuntime(self, projectPath):
if os.path.exists(projectPath + '/codegen'):
shutil.rmtree(projectPath + '/codegen')
- if os.path.exists(projectPath + 'gui'):
+ if os.path.exists(projectPath + '/gui'):
shutil.rmtree(projectPath + '/gui')
shutil.copytree(CMAKE_INSTALL_PREFIX + '/lib/python2.7/visualStates_py/codegen', projectPath + '/codegen')
- shutil.copytree(CMAKE_INSTALL_PREFIX + '/lib/python2.7/visualStates_py/gui', projectPath + '/gui')
\ No newline at end of file
+ shutil.copytree(CMAKE_INSTALL_PREFIX + '/lib/python2.7/visualStates_py/gui', projectPath + '/gui')
+
+
+ def getVarName(self, varName):
+ varName = varName.replace('/', '_')
+ if varName[0] == '_':
+ varName = varName[1:]
+ return varName
\ No newline at end of file
diff --git a/src/tools/visualStates_py/gui/state.py b/src/tools/visualStates_py/gui/state.py
index 1045b3eee..54382b1f4 100644
--- a/src/tools/visualStates_py/gui/state.py
+++ b/src/tools/visualStates_py/gui/state.py
@@ -100,8 +100,15 @@ def getNewCopy(self):
copy.y = self.y
return copy
- def parse(self, stateElement):
+ def parseElement(self, elementName, parentElement):
+ elements = parentElement.getElementsByTagName(elementName)
+ if len(elements) > 0:
+ if len(elements[0].childNodes) > 0:
+ return elements[0].childNodes[0].nodeValue
+ return ''
+
+ def parse(self, stateElement):
# parse attributes of the state
for (name, value) in stateElement.attributes.items():
if name == 'id':
@@ -114,15 +121,10 @@ def parse(self, stateElement):
self.x = float(stateElement.getElementsByTagName('posx')[0].childNodes[0].nodeValue)
self.y = float(stateElement.getElementsByTagName('posy')[0].childNodes[0].nodeValue)
- # optinal state tags
- if len(stateElement.getElementsByTagName('code')[0].childNodes) > 0:
- self.code = stateElement.getElementsByTagName('code')[0].childNodes[0].nodeValue
-
- if len(stateElement.getElementsByTagName('functions')[0].childNodes) > 0:
- self.functions = stateElement.getElementsByTagName('functions')[0].childNodes[0].nodeValue
-
- if len(stateElement.getElementsByTagName('timestep')[0].childNodes) > 0:
- self.timeStepDuration = int(stateElement.getElementsByTagName('timestep')[0].childNodes[0].nodeValue)
+ self.code = self.parseElement('code', stateElement)
+ self.functions = self.parseElement('functions', stateElement)
+ self.variables = self.parseElement('variables', stateElement)
+ self.timeStepDuration = int((self.parseElement('timestep', stateElement)))
# recursive child state parsing
allChildTransitions = []
@@ -148,6 +150,7 @@ def parse(self, stateElement):
# return transitions of the state to be able to wire after all states are created
return stateTransitions
+
def createElement(self, doc, parentElement=None):
stateElement = doc.createElement('state')
stateElement.setAttribute('initial', str(self.initial))
@@ -167,6 +170,9 @@ def createElement(self, doc, parentElement=None):
functionsElement = doc.createElement('functions')
functionsElement.appendChild(doc.createTextNode(self.functions))
stateElement.appendChild(functionsElement)
+ varElement = doc.createElement('variables')
+ varElement.appendChild(doc.createTextNode(self.variables))
+ stateElement.appendChild(varElement)
timeElement = doc.createElement('timestep')
timeElement.appendChild(doc.createTextNode(str(self.timeStepDuration)))
stateElement.appendChild(timeElement)
diff --git a/src/tools/visualStates_py/install_manifest.txt b/src/tools/visualStates_py/install_manifest.txt
new file mode 100644
index 000000000..344a62917
--- /dev/null
+++ b/src/tools/visualStates_py/install_manifest.txt
@@ -0,0 +1,30 @@
+/opt/jderobot/lib/visualstates_py/libvisualStatesRunTime.so
+/opt/jderobot/include/visualstates_py//runtimegui.h
+/opt/jderobot/include/visualstates_py//test.h
+/opt/jderobot/include/visualstates_py//transition.h
+/opt/jderobot/include/visualstates_py//conditionaltransition.h
+/opt/jderobot/include/visualstates_py//temporaltransition.h
+/opt/jderobot/include/visualstates_py//state.h
+/opt/jderobot/lib/python2.7/visualStates_py/codegen/python//conditionaltransition.py
+/opt/jderobot/lib/python2.7/visualStates_py/codegen/python//transition.py
+/opt/jderobot/lib/python2.7/visualStates_py/codegen/python//state.py
+/opt/jderobot/lib/python2.7/visualStates_py/codegen/python//test.py
+/opt/jderobot/lib/python2.7/visualStates_py/codegen/python//temporaltransition.py
+/opt/jderobot/lib/python2.7/visualStates_py/codegen/python//__init__.py
+/opt/jderobot/lib/python2.7/visualStates_py/codegen/python//testipc.py
+/opt/jderobot/lib/python2.7/visualStates_py/codegen/python//runtimegui.py
+/opt/jderobot/lib/python2.7/visualStates_py/gui/state.py
+/opt/jderobot/lib/python2.7/visualStates_py/gui/transition.py
+/opt/jderobot/lib/python2.7/visualStates_py/gui/guitransition.py
+/opt/jderobot/lib/python2.7/visualStates_py/gui/guistate.py
+/opt/jderobot/lib/python2.7/visualStates_py/gui/idtextboxgraphicsitem.py
+/opt/jderobot/lib/python2.7/visualStates_py/gui/recthandlegraphicsitem.py
+/opt/jderobot/lib/python2.7/visualStates_py/gui/transitiontype.py
+/opt/jderobot/lib/python2.7/visualStates_py/gui/treemodel.py
+/opt/jderobot/lib/python2.7/visualStates_py/gui/treenode.py
+/opt/jderobot/lib/python2.7/visualStates_py/gui/cmakevars.py
+/opt/jderobot/lib/python2.7/visualStates_py/__init__.py
+/opt/jderobot/lib/python2.7/visualStates_py/codegen/__init__.py
+/opt/jderobot/lib/python2.7/visualStates_py/codegen/python/__init__.py
+/opt/jderobot/lib/python2.7/visualStates_py/gui/__init__.py
+/opt/jderobot/bin/getinterfaces.sh
\ No newline at end of file
diff --git a/src/tools/visualStates_py/samples/sample1/CMakeLists.txt b/src/tools/visualStates_py/samples/sample1/CMakeLists.txt
new file mode 100644
index 000000000..6a36833d7
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample1/CMakeLists.txt
@@ -0,0 +1,46 @@
+project(sample1)
+
+cmake_minimum_required(VERSION 2.8)
+
+SET(SOURCE_FILES
+ sample1.cpp)
+
+SET(JDEROBOT_INSTALL_PATH /opt/jderobot)
+
+
+SET(JDEROBOT_INCLUDE_DIR ${JDEROBOT_INSTALL_PATH}/include)
+SET(VISUALSTATE_RUNTIME_INCLUDE_DIR ${JDEROBOT_INSTALL_PATH}/include/visualstates_py)
+
+SET(JDEROBOT_LIBS_DIR ${JDEROBOT_INSTALL_PATH}/lib)
+SET(VISUALSTATE_RUNTIME_LIBS_DIR ${JDEROBOT_INSTALL_PATH}/lib/visualstates_py)
+
+SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=gnu++0x")
+
+include_directories(
+ ${JDEROBOT_INCLUDE_DIR}
+ ${VISUALSTATE_RUNTIME_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+link_directories(
+ ${JDEROBOT_LIBS_DIR}
+ ${VISUALSTATE_RUNTIME_LIBS_DIR}
+)
+
+add_executable(sample1 ${SOURCE_FILES})
+
+target_link_libraries( sample1
+ visualStatesRunTime
+ comm
+ config
+ JderobotInterfaces
+ jderobotutil
+ colorspacesmm
+ pthread
+ Ice
+ IceUtil
+ IceStorm
+ glog
+)
diff --git a/src/tools/visualStates_py/samples/sample1/sample1 b/src/tools/visualStates_py/samples/sample1/sample1
new file mode 100755
index 000000000..d7f716835
Binary files /dev/null and b/src/tools/visualStates_py/samples/sample1/sample1 differ
diff --git a/src/tools/visualStates_py/samples/sample1/sample1.cpp b/src/tools/visualStates_py/samples/sample1/sample1.cpp
new file mode 100644
index 000000000..a3859f62b
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample1/sample1.cpp
@@ -0,0 +1,106 @@
+#include "sample1.h"
+#include
+#include
+#include
+
+void State0::runCode() {
+
+}
+
+void State1::runCode() {
+ interfaces->myMotors->sendV(0.1);
+}
+
+void State2::runCode() {
+ interfaces->myMotors->sendV(0);
+}
+
+void Tran1::runCode() {
+
+}
+
+void Tran2::runCode() {
+
+}
+
+void Interfaces::connectProxies(int argc, char* argv[]) {
+ Config::Properties props = Config::load(argc, argv);
+ jdrc = new Comm::Communicator(props);
+
+ myMotors = Comm::getMotorsClient(jdrc, "sample1.myMotors");
+ if (myMotors == NULL) {
+ throw "invalid proxy myMotors";
+ }
+ std::cout << "myMotors is connected" << std::endl;
+}
+
+void Interfaces::destroyProxies() {
+ if (jdrc != 0) {
+ }
+}
+
+
+pthread_t guiThread;
+RunTimeGui* runTimeGui = NULL;
+bool displayGui = false;
+
+void readArgs(int *argc, char* argv[]) {
+ int i;
+ std::string splitedArg;
+
+ for(i = 0; i < *argc; i++) {
+ splitedArg = strtok(argv[i], "=");
+ if (splitedArg.compare("--displaygui") == 0){
+ splitedArg = strtok(NULL, "=");
+ if (splitedArg.compare("true") == 0 || splitedArg.compare("True") == 0){
+ displayGui = true;
+ std::cout << "displayGui ENABLED" << std::endl;
+ }else{
+ displayGui = false;
+ std::cout << "displayGui DISABLED" << std::endl;
+ }
+ }
+ if(i == *argc -1){
+ (*argc)--;
+ }
+ }
+}
+
+void* runGui(void*) {
+ system("./sample1_runtime.py");
+}
+
+int main(int argc, char* argv[]) {
+ Interfaces interfaces;
+ try {
+ interfaces.connectProxies(argc, argv);
+ } catch (const Ice::Exception& ex) {
+ std::cerr << ex << std::endl;
+ interfaces.destroyProxies();
+ return 1;
+ } catch (const char* msg) {
+ std::cerr << msg << std::endl;
+ interfaces.destroyProxies();
+ return 1;
+ }
+
+ readArgs(&argc, argv);
+
+ if (displayGui) {
+ pthread_create(&guiThread, NULL, &runGui, NULL);
+ runTimeGui = new RunTimeGui();
+
+ }
+ State* state0 = new State0(0, true, &interfaces, 100, NULL, runTimeGui);
+ State* state1 = new State1(1, true, &interfaces, 100, state0, runTimeGui);
+ State* state2 = new State2(2, false, &interfaces, 100, state0, runTimeGui);
+
+ Transition* tran1 = new Tran1(1, 2, 1000);
+ state1->addTransition(tran1);
+ Transition* tran2 = new Tran2(2, 1, 1000);
+ state2->addTransition(tran2);
+
+ state0->startThread();
+
+ state0->join();
+}
diff --git a/src/tools/visualStates_py/samples/sample1/sample1.h b/src/tools/visualStates_py/samples/sample1/sample1.h
new file mode 100644
index 000000000..ea0ebebce
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample1/sample1.h
@@ -0,0 +1,58 @@
+#ifndef sample1_H
+#define sample1_H
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+class Interfaces {
+public:
+ Comm::Communicator* jdrc;
+ Comm::MotorsClient* myMotors;
+
+ virtual void connectProxies(int argc, char* argv[]);
+ virtual void destroyProxies();
+};
+
+class State0 : public State {
+public:
+ Interfaces* interfaces;
+ State0(int id, bool initial, Interfaces* interfaces, int cycleDuration, State* parent, RunTimeGui* gui):
+ State(id, initial, cycleDuration, parent, gui) {this->interfaces = interfaces;}
+ virtual void runCode();
+};
+
+class State1 : public State {
+public:
+ Interfaces* interfaces;
+ State1(int id, bool initial, Interfaces* interfaces, int cycleDuration, State* parent, RunTimeGui* gui):
+ State(id, initial, cycleDuration, parent, gui) {this->interfaces = interfaces;}
+ virtual void runCode();
+};
+
+class State2 : public State {
+public:
+ Interfaces* interfaces;
+ State2(int id, bool initial, Interfaces* interfaces, int cycleDuration, State* parent, RunTimeGui* gui):
+ State(id, initial, cycleDuration, parent, gui) {this->interfaces = interfaces;}
+ virtual void runCode();
+};
+
+class Tran1 : public TemporalTransition {
+ public:
+ Tran1(int id, int destId, int elapsedTime):TemporalTransition(id, destId, elapsedTime) {}
+ virtual void runCode();
+};
+
+class Tran2 : public TemporalTransition {
+ public:
+ Tran2(int id, int destId, int elapsedTime):TemporalTransition(id, destId, elapsedTime) {}
+ virtual void runCode();
+};
+
+#endif
\ No newline at end of file
diff --git a/src/tools/visualStates_py/samples/sample1/sample1.py b/src/tools/visualStates_py/samples/sample1/sample1.py
new file mode 100755
index 000000000..02fd6b4d1
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample1/sample1.py
@@ -0,0 +1,153 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+import sys, threading, time, signal
+sys.path.append("/opt/jderobot/lib/python2.7")
+sys.path.append("/opt/jderobot/lib/python2.7/visualStates_py")
+from codegen.python.state import State
+from codegen.python.temporaltransition import TemporalTransition
+from codegen.python.conditionaltransition import ConditionalTransition
+from codegen.python.runtimegui import RunTimeGui
+from PyQt5.QtWidgets import QApplication
+import config, comm
+
+import comm
+
+class State0(State):
+ def __init__(self, id, initial, interfaces, cycleDuration, parent=None, gui=None):
+ State.__init__(self, id, initial, cycleDuration, parent, gui)
+ self.interfaces = interfaces
+
+ def runCode(self):
+ pass
+
+
+class State1(State):
+ def __init__(self, id, initial, interfaces, cycleDuration, parent=None, gui=None):
+ State.__init__(self, id, initial, cycleDuration, parent, gui)
+ self.interfaces = interfaces
+
+ def runCode(self):
+ self.interfaces.myMotors.sendV(0.1)
+
+
+class State2(State):
+ def __init__(self, id, initial, interfaces, cycleDuration, parent=None, gui=None):
+ State.__init__(self, id, initial, cycleDuration, parent, gui)
+ self.interfaces = interfaces
+
+ def runCode(self):
+ pass
+
+
+class Tran1(TemporalTransition):
+
+ def runCode(self):
+ pass
+
+class Tran2(TemporalTransition):
+
+ def runCode(self):
+ pass
+
+class Interfaces():
+ def __init__(self):
+ self.jdrc = None
+ self.myMotors = None
+ self.connectProxies()
+
+ def connectProxies(self):
+ cfg = config.load(sys.argv[1])
+ self.jdrc = comm.init(cfg, "sample1")
+ self.myMotors = self.jdrc.getMotorsClient("sample1.myMotors")
+ if not self.myMotors:
+ raise Exception("could not create client with name:myMotors")
+ print("myMotors is connected")
+
+ def destroyProxies(self):
+ if self.jdrc is not None:
+ self.jdrc.destroy()
+
+displayGui = False
+guiThread = None
+gui = None
+state0 = None
+
+def signal_handler(signal, frame):
+ global gui
+ print("SIGINT is captured. The program exits")
+ if gui is not None:
+ gui.close()
+ global state0
+ state0.stop()
+
+def readArgs():
+ global displayGui
+ for arg in sys.argv:
+ splitedArg = arg.split('=')
+ if splitedArg[0] == '--displaygui':
+ if splitedArg[1] == 'True' or splitedArg[1] == 'true':
+ displayGui = True
+ print('runtime gui enabled')
+ else:
+ displayGui = False
+ print('runtime gui disabled')
+
+def runGui():
+ global gui
+ app = QApplication(sys.argv)
+ gui = RunTimeGui()
+ gui.show()
+ app.exec_()
+
+if __name__ == "__main__":
+ interfaces = Interfaces()
+
+ readArgs()
+ if displayGui:
+ guiThread = threading.Thread(target=runGui)
+ guiThread.start()
+
+
+ if displayGui:
+ while(gui is None):
+ time.sleep(0.1)
+
+ gui.addState(0, "root", True, 0.0, 0.0, None)
+ gui.addState(1, "state 1", True, 848.0, 820.0, 0)
+ gui.addState(2, "state 2", False, 1050.0, 1061.0, 0)
+
+ gui.addTransition(1, "transition 1", 1, 2, 1029.0, 867.5)
+ gui.addTransition(2, "transition 2", 2, 1, 853.0, 968.5)
+
+ if displayGui:
+ gui.emitLoadFromRoot()
+ gui.emitActiveStateById(0)
+
+ state0 = State0(0, True, interfaces, 100, None, gui)
+ state1 = State1(1, True, interfaces, 100, state0, gui)
+ state2 = State2(2, False, interfaces, 100, state0, gui)
+
+ tran1 = Tran1(1, 2, 1000)
+ state1.addTransition(tran1)
+
+ tran2 = Tran2(2, 1, 1000)
+ state2.addTransition(tran2)
+
+ try:
+ state0.startThread()
+ signal.signal(signal.SIGINT, signal_handler)
+ signal.pause()
+ state0.join()
+ if displayGui:
+ guiThread.join()
+
+ interfaces.destroyProxies()
+ except:
+ state0.stop()
+ if displayGui:
+ gui.close()
+ guiThread.join()
+
+ state0.join()
+ interfaces.destroyProxies()
+ sys.exit(1)
diff --git a/src/tools/visualStates_py/samples/sample1/sample1.xml b/src/tools/visualStates_py/samples/sample1/sample1.xml
new file mode 100644
index 000000000..5c7d64072
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample1/sample1.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+ ice
+ myMotors
+
+ Motors
+ localhost
+ 9001
+ Motors
+
+
+
+
+
+ 0.0
+ 0.0
+ root
+
+
+ 100
+
+ 848.0
+ 820.0
+ state 1
+ self.interfaces.myMotors.sendV(0.1)
+
+ 100
+
+ 0
+
+ 1029.0
+ 867.5
+ transition 1
+ 1
+ 2
+
+
+
+
+ 1050.0
+ 1061.0
+ state 2
+
+
+ 100
+
+ 0
+
+ 853.0
+ 968.5
+ transition 2
+ 2
+ 1
+
+
+
+
+
diff --git a/src/tools/visualStates_py/samples/sample1/sample1.yml b/src/tools/visualStates_py/samples/sample1/sample1.yml
new file mode 100644
index 000000000..4d9f36071
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample1/sample1.yml
@@ -0,0 +1,7 @@
+sample1:
+ NodeName: sample1
+ myMotors:
+ Name: myMotors
+ Proxy: Motors:default -h localhost -p 9001
+ Server: 1
+ Topic: ''
diff --git a/src/tools/visualStates_py/samples/sample1/sample1_runtime.py b/src/tools/visualStates_py/samples/sample1/sample1_runtime.py
new file mode 100755
index 000000000..3f207a9da
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample1/sample1_runtime.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+import sys
+sys.path.append("/opt/jderobot/lib/python2.7/visualStates_py")
+
+from PyQt5.QtWidgets import QApplication
+from codegen.python.runtimegui import RunTimeGui
+
+gui = None
+
+def runGui():
+ global gui
+ app = QApplication(sys.argv)
+ gui = RunTimeGui()
+ gui.activateIPC()
+
+ gui.addState(0, "root", True, 0.0, 0.0, None)
+ gui.addState(1, "state 1", True, 848.0, 820.0, 0)
+ gui.addState(2, "state 2", False, 1050.0, 1061.0, 0)
+
+ gui.addTransition(1, "transition 1", 1, 2, 1029.0, 867.5)
+ gui.addTransition(2, "transition 2", 2, 1, 853.0, 968.5)
+
+ gui.emitLoadFromRoot()
+ gui.emitActiveStateById(0)
+ gui.show()
+ app.exec_()
+
+if __name__ == "__main__":
+ runGui()
+
diff --git a/src/tools/visualStates_py/samples/sample2/CMakeLists.txt b/src/tools/visualStates_py/samples/sample2/CMakeLists.txt
new file mode 100644
index 000000000..96faeefe5
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample2/CMakeLists.txt
@@ -0,0 +1,44 @@
+project(sample2)
+
+cmake_minimum_required(VERSION 2.8)
+
+SET(SOURCE_FILES
+ sample2.cpp)
+
+SET(JDEROBOT_INSTALL_PATH /opt/jderobot)
+
+
+SET(JDEROBOT_INCLUDE_DIR ${JDEROBOT_INSTALL_PATH}/include)
+SET(VISUALSTATE_RUNTIME_INCLUDE_DIR ${JDEROBOT_INSTALL_PATH}/include/visualstates_py)
+
+SET(JDEROBOT_LIBS_DIR ${JDEROBOT_INSTALL_PATH}/lib)
+SET(VISUALSTATE_RUNTIME_LIBS_DIR ${JDEROBOT_INSTALL_PATH}/lib/visualstates_py)
+
+SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+include_directories(
+ ${JDEROBOT_INCLUDE_DIR}
+ ${VISUALSTATE_RUNTIME_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+link_directories(
+ ${JDEROBOT_LIBS_DIR}
+ ${VISUALSTATE_RUNTIME_LIBS_DIR}
+)
+
+add_executable(sample2 ${SOURCE_FILES})
+
+target_link_libraries( sample2
+visualStatesRunTime
+ config
+ comm
+ JderobotInterfaces
+ jderobotutil
+ colorspacesmm
+ pthread
+ Ice
+ IceUtil
+ IceStorm
+ glog
+)
diff --git a/src/tools/visualStates_py/samples/sample2/sample2.cpp b/src/tools/visualStates_py/samples/sample2/sample2.cpp
new file mode 100644
index 000000000..bac72f1f8
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample2/sample2.cpp
@@ -0,0 +1,106 @@
+#include "sample2.h"
+#include
+#include
+#include
+
+void State0::runCode() {
+
+}
+
+void State1::runCode() {
+
+}
+
+void State2::runCode() {
+
+}
+
+void Tran1::runCode() {
+
+}
+
+void Tran2::runCode() {
+
+}
+
+void Interfaces::connectProxies(int argc, char* argv[]) {
+ Config::Properties props = Config::load(argc, argv);
+ jdrc = new Comm::Communicator(props);
+
+ pose3d = Comm::getPose3dClient(jdrc, "sample2.pose3d");
+ if (pose3d == NULL) {
+ throw "invalid proxy pose3d";
+ }
+ std::cout << "pose3d is connected" << std::endl;
+}
+
+void Interfaces::destroyProxies() {
+ if (jdrc != 0) {
+ }
+}
+
+
+pthread_t guiThread;
+RunTimeGui* runTimeGui = NULL;
+bool displayGui = false;
+
+void readArgs(int *argc, char* argv[]) {
+ int i;
+ std::string splitedArg;
+
+ for(i = 0; i < *argc; i++) {
+ splitedArg = strtok(argv[i], "=");
+ if (splitedArg.compare("--displaygui") == 0){
+ splitedArg = strtok(NULL, "=");
+ if (splitedArg.compare("true") == 0 || splitedArg.compare("True") == 0){
+ displayGui = true;
+ std::cout << "displayGui ENABLED" << std::endl;
+ }else{
+ displayGui = false;
+ std::cout << "displayGui DISABLED" << std::endl;
+ }
+ }
+ if(i == *argc -1){
+ (*argc)--;
+ }
+ }
+}
+
+void* runGui(void*) {
+ system("./sample2_runtime.py");
+}
+
+int main(int argc, char* argv[]) {
+ Interfaces interfaces;
+ try {
+ interfaces.connectProxies(argc, argv);
+ } catch (const Ice::Exception& ex) {
+ std::cerr << ex << std::endl;
+ interfaces.destroyProxies();
+ return 1;
+ } catch (const char* msg) {
+ std::cerr << msg << std::endl;
+ interfaces.destroyProxies();
+ return 1;
+ }
+
+ readArgs(&argc, argv);
+
+ if (displayGui) {
+ pthread_create(&guiThread, NULL, &runGui, NULL);
+ runTimeGui = new RunTimeGui();
+
+ }
+ State* state0 = new State0(0, true, &interfaces, 100, NULL, runTimeGui);
+ State* state1 = new State1(1, true, &interfaces, 100, state0, runTimeGui);
+ State* state2 = new State2(2, false, &interfaces, 100, state0, runTimeGui);
+
+ Transition* tran1 = new Tran1(1, 2, 1000);
+ state1->addTransition(tran1);
+ Transition* tran2 = new Tran2(2, 1, 1000);
+ state2->addTransition(tran2);
+
+ state0->startThread();
+
+ state0->join();
+}
diff --git a/src/tools/visualStates_py/samples/sample2/sample2.h b/src/tools/visualStates_py/samples/sample2/sample2.h
new file mode 100644
index 000000000..78b2d9135
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample2/sample2.h
@@ -0,0 +1,58 @@
+#ifndef sample2_H
+#define sample2_H
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+class Interfaces {
+public:
+ Comm::Communicator* jdrc;
+ Comm::Pose3dClient* pose3d;
+
+ virtual void connectProxies(int argc, char* argv[]);
+ virtual void destroyProxies();
+};
+
+class State0 : public State {
+public:
+ Interfaces* interfaces;
+ State0(int id, bool initial, Interfaces* interfaces, int cycleDuration, State* parent, RunTimeGui* gui):
+ State(id, initial, cycleDuration, parent, gui) {this->interfaces = interfaces;}
+ virtual void runCode();
+};
+
+class State1 : public State {
+public:
+ Interfaces* interfaces;
+ State1(int id, bool initial, Interfaces* interfaces, int cycleDuration, State* parent, RunTimeGui* gui):
+ State(id, initial, cycleDuration, parent, gui) {this->interfaces = interfaces;}
+ virtual void runCode();
+};
+
+class State2 : public State {
+public:
+ Interfaces* interfaces;
+ State2(int id, bool initial, Interfaces* interfaces, int cycleDuration, State* parent, RunTimeGui* gui):
+ State(id, initial, cycleDuration, parent, gui) {this->interfaces = interfaces;}
+ virtual void runCode();
+};
+
+class Tran1 : public TemporalTransition {
+ public:
+ Tran1(int id, int destId, int elapsedTime):TemporalTransition(id, destId, elapsedTime) {}
+ virtual void runCode();
+};
+
+class Tran2 : public TemporalTransition {
+ public:
+ Tran2(int id, int destId, int elapsedTime):TemporalTransition(id, destId, elapsedTime) {}
+ virtual void runCode();
+};
+
+#endif
\ No newline at end of file
diff --git a/src/tools/visualStates_py/samples/sample2/sample2.xml b/src/tools/visualStates_py/samples/sample2/sample2.xml
new file mode 100644
index 000000000..9fe1678e3
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample2/sample2.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+ ice
+ pose3d
+
+ pose3d
+ localhost
+ 9001
+ Pose3d
+
+
+
+
+
+ 0.0
+ 0.0
+ root
+
+
+ 100
+
+ 903.0
+ 922.0
+ state 1
+
+
+ 100
+
+ 0
+
+ 1025.0
+ 954.0
+ transition 1
+ 1
+ 2
+
+
+
+
+ 1031.0
+ 1096.0
+ state 2
+
+
+ 100
+
+ 0
+
+ 860.0
+ 1054.0
+ transition 2
+ 2
+ 1
+
+
+
+
+
diff --git a/src/tools/visualStates_py/samples/sample2/sample2.yml b/src/tools/visualStates_py/samples/sample2/sample2.yml
new file mode 100644
index 000000000..f608faf10
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample2/sample2.yml
@@ -0,0 +1,7 @@
+sample2:
+ NodeName: sample2
+ pose3d:
+ Name: pose3d
+ Proxy: pose3d:default -h localhost -p 9001
+ Server: 1
+ Topic: ''
diff --git a/src/tools/visualStates_py/samples/sample2/sample2_runtime.py b/src/tools/visualStates_py/samples/sample2/sample2_runtime.py
new file mode 100755
index 000000000..7d0b34241
--- /dev/null
+++ b/src/tools/visualStates_py/samples/sample2/sample2_runtime.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+import sys
+sys.path.append("/opt/jderobot/lib/python2.7/visualStates_py")
+
+from PyQt5.QtWidgets import QApplication
+from codegen.python.runtimegui import RunTimeGui
+
+gui = None
+
+def runGui():
+ global gui
+ app = QApplication(sys.argv)
+ gui = RunTimeGui()
+ gui.activateIPC()
+
+ gui.addState(0, "root", True, 0.0, 0.0, None)
+ gui.addState(1, "state 1", True, 903.0, 922.0, 0)
+ gui.addState(2, "state 2", False, 1031.0, 1096.0, 0)
+
+ gui.addTransition(1, "transition 1", 1, 2, 1025.0, 954.0)
+ gui.addTransition(2, "transition 2", 2, 1, 860.0, 1054.0)
+
+ gui.emitLoadFromRoot()
+ gui.emitActiveStateById(0)
+ gui.show()
+ app.exec_()
+
+if __name__ == "__main__":
+ runGui()
+
diff --git a/src/tools/visualStates_py/visualStates_py b/src/tools/visualStates_py/visualStates_py
new file mode 100644
index 000000000..1b0b65a8e
--- /dev/null
+++ b/src/tools/visualStates_py/visualStates_py
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+python /opt/jderobot/lib/python2.7/visualStates_py/visualStates.py $*