EmbeddedMontiArc issueshttps://git.rwth-aachen.de/groups/monticore/EmbeddedMontiArc/-/issues2021-10-20T17:43:13+02:00https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/simulators/simulation/-/issues/24Proper Error/Exception handling2021-10-20T17:43:13+02:00Jean MeuriceProper Error/Exception handlingThe entire simulator could use a proper error handling concept that would be used throughout all simulator projects.
Goals:
- Describe a concept for designing exceptions and how they are propagated through the simulator.
- It has to sup...The entire simulator could use a proper error handling concept that would be used throughout all simulator projects.
Goals:
- Describe a concept for designing exceptions and how they are propagated through the simulator.
- It has to support exceptions occurring remotely (autopilot, remote server) as well as in other languages (ex: c++ for the hardware_emulator)
- Ideally a comprehensible stack trace would show additional contextual information at different points in the call/catch stack.
- List all the *errors* (that are relevant to a *user*) and define a system to properly notify them.
- Define a system to properly notify *exceptions* (bugs/missing features).https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/simulators/simulation/-/issues/25Proper Logging2021-10-20T18:59:13+02:00Jean MeuriceProper Logging## Idea
Re-instate *proper* logging: well structured, controllable, efficient (using ifs).
## Task
- Define a *target tree* which would well represent the different logging points of interest.
- The different branches/leaves in that t...## Idea
Re-instate *proper* logging: well structured, controllable, efficient (using ifs).
## Task
- Define a *target tree* which would well represent the different logging points of interest.
- The different branches/leaves in that tree should be easily enabled/disabled for debugging.
- The code uses `if`s on its corresponding target before logging to minimize overhead.https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMAM2Cpp/-/issues/31Issues of dynamic port and connect2019-06-06T10:56:43+02:00Wei XuIssues of dynamic port and connectProblems occurs when the dynamic port and connect are applied in the Autopilot model.<br>
1. Dynamic ports free problem <br>
After every execution of Autopilot model, dynamic input and output ports should be free by the `free_#port_n...Problems occurs when the dynamic port and connect are applied in the Autopilot model.<br>
1. Dynamic ports free problem <br>
After every execution of Autopilot model, dynamic input and output ports should be free by the `free_#port_name#` method in Autopilot.h, which is called in AutopilotAdapter.cpp. <br>
For simple component like:<br>
```js
dynamic component Autopilot {
port
dynamic in Q input[0:32],
dynamic out Q output[0:32];
@input::connect{
connect input[?] -> output[?];
}
}
```
Free of dynamic inputs and outputs works, when we use the `free_input` method of autopilot.h in AutopilotAdapter.cpp, like follows:<br>
```js
bool free_input(int input_indexref)
{
if( (input_indexref < 0) || (32 <= input_indexref) || (!__input_connected[input_indexref]) ){ return false;}
__input_free_request.push(input_indexref);
dynamicfree();
return true;
}
```
It‘s because in the `dynamicfree()` method, `__output_free_request` will be pushed and then free, when it connects to in the dynamic input port.
```js
void __event_body_free_EventHandler_1_(){
while(input_has_free_request()){
int _input_dynPortID = input_free_request_front();
for(long i = __event_connects_EventHandler_1_.size()-1; i >= 0; --i){
int* _connected_idxs = __event_connects_EventHandler_1_.at(i);
if( (_input_dynPortID == _connected_idxs[0]) ){
int _output_dynPortID = _connected_idxs[1]; __output_free_request.push(_output_dynPortID);
if(__parent != NULL){__parent_dynamic(__parent, false, true);}
if(__output_free_request.front() == _output_dynPortID){ __output_free_request.pop(); }
dynamicconnect_remove(&__dynamic_double_connect, NULL, &(input[_input_dynPortID]), &(output[_output_dynPortID]));
__event_connects_EventHandler_1_.erase(__event_connects_EventHandler_1_.begin()+i);
__output_connected[_output_dynPortID] = false;
free(_connected_idxs);
}
}
}
}
```
But when component is defined as follows:
```js
dynamic component Autopilot {
port
dynamic in Q input[0:32],
dynamic out Q output[0:32];
instance Autopilot1 ap1;
@ input::connect{
connect input[?] -> ap1.input[?];
}
@ ap1.output1::connect{
connect ap1.output1[?] -> output[?];
}
}
```
```js
dynamic component Autopilot1{
port
dynamic in Q input[0:32],
dynamic out Q output1[0:32],
dynamic out Q output2[0:32];
@ input::connect{}
implementation Math{
for i = 1:32
if is_connected(input,i)
if ports_connect(output1, i, input(i))
output1(i) = input(i);
end
if ports_connect(output2, i, input(i))
output2(i) = input(i);
end
end
end
}
}
```
Free of dynamic output ports depends on the free event:
```js
void __event_body_free_EventHandler_3_(){
while(ap1.output1_has_free_request()){
int _ap1_output1_dynPortID = ap1.output1_free_request_front();
for(long i = __event_connects_EventHandler_3_.size()-1; i >= 0; --i){
int* _connected_idxs = __event_connects_EventHandler_3_.at(i);
if( (_ap1_output1_dynPortID == _connected_idxs[0]) ){
int _output_dynPortID = _connected_idxs[1]; __output_free_request.push(_output_dynPortID);
if(__parent != NULL){__parent_dynamic(__parent, false, true);}
if(__output_free_request.front() == _output_dynPortID){ __output_free_request.pop(); }
dynamicconnect_remove(&__dynamic_double_connect, NULL, &(ap1.output1[_ap1_output1_dynPortID]), &(output[_output_dynPortID]));
__event_connects_EventHandler_3_.erase(__event_connects_EventHandler_3_.begin()+i);
__output_connected[_output_dynPortID] = false;
free(_connected_idxs);
}
}
}
}
```
But, the `ap1.output1_has_free_request()` is never pushed in instance ap1, because there is no connect between the dynamic input ports and output1 ports in instance ap1, so dynamic output ports of Autopilot can not be free correctly.<br>
When we use the ports_free method in Autopilot1 component:
```js
dynamic component Autopilot1{
port
dynamic in Q input[0:32],
dynamic out Q output1[0:32],
dynamic out Q output2[0:32];
@ input::connect{}
implementation Math{
for i = 1:32
if is_connected(input,i)
if ports_connect(output1, i, input(i))
output1(i) = input(i);
end
Z r = ports_free(output1,i);
if ports_connect(output2, i, input(i))
output2(i) = input(i);
end
Z r = ports_free(output2,i);
end
end
}
}
```
The free request can be pushed into `ap1.output1_has_free_request()` with `__ports_free_1` method:
```js
bool __ports_free_1(int idx0){
if((idx0 < 0) || (32 <= idx0) || (!__output1_connected[idx0])){return false;}__output1_free_request.push(idx0);
if(__parent != NULL){__parent_dynamic(__parent, false, true);}
__output1_connected[idx0] = false;
return true;
}
```
Problem is that `__output1_connected[idx0]` can not be set to false in this method, it means this port is free now and next connect will occupy this port, which leads to error that no matter how many inputs request there is just one output connect request.<br>
Also, when component like follows, there are two Autopilot1 instances:
```js
dynamic component Autopilot {
port
dynamic in Q input[0:32],
dynamic out Q output[0:32];
instance Autopilot1 ap1,ap2;
@ input::connect{
connect input[?] -> ap1.input[?];
}
@ ap1.output1::connect{
connect ap1.output1[?] -> ap2.input[?];
}
@ ap2.output1::connect{
connect ap2.output1[?] -> output[?];
}
}
```
```js
dynamic component Autopilot1{
port
dynamic in Q input[0:32],
dynamic out Q output1[0:32],
dynamic out Q output2[0:32];
@ input::connect{}
implementation Math{
for i = 1:32
if is_connected(input,i)
if ports_connect(output1, i, input(i))
output1(i) = input(i);
end
Z r = ports_free(output1,i);
if ports_connect(output2, i, input(i))
output2(i) = input(i);
end
Z r = ports_free(output2,i);
end
end
}
}
```
Free of dynamic output ports depends on the free event:
```js
void __event_body_free_EventHandler_4_(){
while(ap2.output1_has_free_request()){
int _ap2_output1_dynPortID = ap2.output1_free_request_front();
for(long i = __event_connects_EventHandler_4_.size()-1; i >= 0; --i){
int* _connected_idxs = __event_connects_EventHandler_4_.at(i);
if( (_ap2_output1_dynPortID == _connected_idxs[0]) ){
int _output_dynPortID = _connected_idxs[1]; __output_free_request.push(_output_dynPortID);
if(__parent != NULL){__parent_dynamic(__parent, false, true);}
if(__output_free_request.front() == _output_dynPortID){ __output_free_request.pop(); }
dynamicconnect_remove(&__dynamic_double_connect, NULL, &(ap2.output1[_ap2_output1_dynPortID]), &(output[_output_dynPortID]));
__event_connects_EventHandler_4_.erase(__event_connects_EventHandler_4_.begin()+i);
__output_connected[_output_dynPortID] = false;
free(_connected_idxs);
}
}
}
}
```
Free of dynamic output port in Autopilot depends on `ap2.output1_has_free_request()`, although ports_free method is defined in Autopilot1, there is no `__ports_free#number#` method in generated autopilot_ap2.h file. It means that ports_free method can just be converted in the outer layer of the whole component.<br>
The structure like this problem occurs component is very important in the autopilot. Because there are several subcomponents, which all need the content of dynamic input. But once dynamic input port connects to the dynamic port in sub-component, connect request of dynamic input will be pop, so we need the component like Autopilot1, which aims to copy the connect request of dynamic input port.<br>
When the dynamic port in Autopilot can not be free, after several frames of simulation, all ports will be occupied and over flow. JVM is broken down and shows RUNTIME error.
2. Problems in instance ports<br>
When the structure of Autopilot Model like follows:
```js
dynamic component Autopilot {
port
dynamic in Q input[0:32],
dynamic out Q output[0:32];
instance Autopilot1 ap1[0:32];
instance Autopilot2 ap2[0:32];
instance Autopilot3 ap3;
@ input::connect{
connect input[?] -> ap1[?].input;
connect ap1[?].output1 -> ap3.input1[?];
connect ap1[?].output2 -> ap3.input2[?];
connect input[?] -> ap2[?].input;
connect ap2[?].output3 -> ap3.input3[?];
connect ap2[?].output4 -> ap3.input4[?];
}
@ ap3.output1::connect{
connect ap3.output1[?] -> output[?];
}
@ ap3.output2::connect{
connect ap3.output2[?] -> output[?];
}
}
```
```js
component Autopilot1{
port
in Q input,
out Q output1,
out Q output2;
implementation Math{
output1 = input;
output2 = input;
}
}
```
```js
component Autopilot2{
port
in Q input,
out Q output3,
out Q output4;
implementation Math{
output3 = input;
output4 = input;
}
}
```
```js
dynamic component Autopilot4{
port
dynamic in Q input1[0:32],
dynamic in Q input2[0:32],
dynamic out Q output[0:32];
@input1::connect{}
@input2::connect{}
implementation Math{
for i = 1:32
if is_connected(input1,i)&&is_connected(input2,i)
if ports_connect(output,i,42.123)
output(i) = input1(i) + input2(i);
end
end
end
}
}
```
```js
dynamic component Autopilot3{
port
dynamic in Q input1[0:32],
dynamic in Q input2[0:32],
dynamic in Q input3[0:32],
dynamic in Q input4[0:32],
dynamic out Q output1[0:32],
dynamic out Q output2[0:32];
instance Autopilot4 ap4,ap5;
@ input1::connect{
connect input1[?] -> ap4.input1[?];
}
@ input2::connect{
connect input2[?] -> ap4.input2[?];
}
@ ap4.output::connect{
connect ap4.output[?] -> output1[?];
}
@ input3::connect{
connect input3[?] -> ap5.input1[?];
}
@ input4::connect{
connect input4[?] -> ap5.input2[?];
}
@ ap5.output::connect{
connect ap5.output[?] -> output2[?];
}
}
```
The structure can be shown in a Figure:![Structure](/uploads/4e347387c743ee3060d235ac372904c3/Structure.png)
In the generated c++ file of autopilot, there is a undefined connect method `ap3.connect_input1_input2_input3_input4`, which is called in autopilot.h. This leads to the error when c++ files are compiled to dll file.
```js
void __event_body_EventHandler_9_()
{
while(__event_condition_EventHandler_9_()){
int* _connected_idxs = (int *)calloc(7, sizeof(int));
int _input_dynPortID = __input_connect_request.front(); __input_connect_request.pop(); _connected_idxs[0] = _input_dynPortID;
int _ap2_dynINSTID = dynamicconnect(32, __ap2_connected); if( _ap2_dynINSTID < 0 ){ free(_connected_idxs); return; } _connected_idxs[1] = _ap2_dynINSTID;
int _ap1_dynINSTID = dynamicconnect(32, __ap1_connected); if( _ap1_dynINSTID < 0 ){ free(_connected_idxs); return; } _connected_idxs[2] = _ap1_dynINSTID;
int _ap3_input1_dynPortID = -1;
int _ap3_input2_dynPortID = -1;
int _ap3_input3_dynPortID = -1;
int _ap3_input4_dynPortID = -1;
if(!ap3.connect_input1_input2_input3_input4(&_ap3_input1_dynPortID, ap1[_ap1_dynINSTID].output1, &_ap3_input2_dynPortID, ap1[_ap1_dynINSTID].output2, &_ap3_input3_dynPortID, ap2[_ap2_dynINSTID].output3, &_ap3_input4_dynPortID, ap2[_ap2_dynINSTID].output4)){ free(_connected_idxs); return ;}
_connected_idxs[3] = _ap3_input1_dynPortID;_connected_idxs[4] = _ap3_input2_dynPortID;_connected_idxs[5] = _ap3_input3_dynPortID;_connected_idxs[6] = _ap3_input4_dynPortID;
__dynamic_double_connect.push_back({&ap1[_ap1_dynINSTID], &(input[_input_dynPortID]), &(ap1[_ap1_dynINSTID].input)});
__dynamic_double_connect.push_back({&ap3, &(ap1[_ap1_dynINSTID].output1), &(ap3.input1[_ap3_input1_dynPortID])});
__dynamic_double_connect.push_back({&ap3, &(ap1[_ap1_dynINSTID].output2), &(ap3.input2[_ap3_input2_dynPortID])});
__dynamic_double_connect.push_back({&ap2[_ap2_dynINSTID], &(input[_input_dynPortID]), &(ap2[_ap2_dynINSTID].input)});
__dynamic_double_connect.push_back({&ap3, &(ap2[_ap2_dynINSTID].output3), &(ap3.input3[_ap3_input3_dynPortID])});
__dynamic_double_connect.push_back({&ap3, &(ap2[_ap2_dynINSTID].output4), &(ap3.input4[_ap3_input4_dynPortID])});
__event_connects_EventHandler_9_.push_back(_connected_idxs);
}
}
```
3. Port free in Streamtest<br>
Dynamic ports can not be free in current Streamtest project, when dynamic component is tested with TestWrapper and Stream File. Because free_methods of dynamic component are not called. So, the length of Stream data can just be one. Otherwise, it leads to error when tests second group of stream data, the reason is that last used ports are not free.Evgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMAM2Cpp/-/issues/32Issues with dynamic using2019-07-11T17:19:56+02:00Wei XuIssues with dynamic usingSome bugs occurred when dynamic ports are used in cooperative Autopilot development.
1. Generation of connecting method<br>
Duplicate Method for the copy of dynamic message inputs shows as follows:<br>
```js
dynamic component St...Some bugs occurred when dynamic ports are used in cooperative Autopilot development.
1. Generation of connecting method<br>
Duplicate Method for the copy of dynamic message inputs shows as follows:<br>
```js
dynamic component Statusduplicate{
ports
// copy statusmessage for dupilcate in ports
dynamic in Statusmessage status_msg[0:32],
dynamic out Statusmessage status_msg1[0:32],
...
out Statusmessage smsg;
@ status_msg::connect{/*interface for dynamic ports*/}
implementation Math{
for i = 1:32
if is_connected(status_msg,i)
smsg = status_msg(i);
if ports_connect(status_msg1, i, smsg)
status_msg1(i) = smsg;
end
....
end
end
}
}
```
Once the Statusduplicate component is instantiated is the structure like follows
```js
dynamic component Autopilot{
ports
dynamic in Statusmessage status_msg[0:32],
...
instance Statusduplicate s_dup;
instance Autopilot1 ap1;
@ status_msg::connect{
connect status_msg[?] -> s_dup.status_msg[?];
}
@ s_dup.status_msg1::connect{
connect s_dup.status_msg1 -> ap1.status_msg[?];
}
}
dynamic component Autopilot1{
ports
dynamic in Statusmessage status_msg[0:32],
...
instance Statusduplicate s_dup;
@ status_msg::connect{
connect status_msg[?] -> s_dup.status_msg[?];
}
}
```
the generated c++ file of Statusduplicate instance in Autopilot1 wont't contain the ports_connect methods.
2. When there are dynamic connects and static connects in one component, sometimes the execution order in generated c++ file is not correct, but it happens irregularly, so current the detailed problems cannot locate.
3. Generation of C++ files costs too long time when there are dynamic ports and connects in the model, the generation of around 4000 lines component costs over 10 hours(without dynamic using only 10 - 20 minutes), it may due to some redundant processes. Evgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMAM2Middleware/-/issues/33Failing EMADL Tests2019-09-04T21:13:34+02:00Alexander David HellwigFailing EMADL TestsThe tests
- de.monticore.lang.monticar.generator.middleware.CliTest#testEMADLAndRosGenerator
- de.monticore.lang.monticar.generator.middleware.CliTest#testSingleEMADLGenerator
- de.monticore.lang.monticar.generator.middleware.CliTest#tes...The tests
- de.monticore.lang.monticar.generator.middleware.CliTest#testEMADLAndRosGenerator
- de.monticore.lang.monticar.generator.middleware.CliTest#testSingleEMADLGenerator
- de.monticore.lang.monticar.generator.middleware.CliTest#testEMADLConfigFile
- de.monticore.lang.monticar.generator.middleware.GenerationTest#testEMADLMiddlewareGeneration
are all failing.https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMAMOpt2Cpp/-/issues/2Problem classification2020-08-19T19:27:07+02:00Evgeny KusmenkoProblem classificationOptimization problems can be classified into different categories, cf. thesis of Christoph Richter, e.g. linear, quadratic, convex, etc.
EMAMOpt2CPP provides a [class](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMA...Optimization problems can be classified into different categories, cf. thesis of Christoph Richter, e.g. linear, quadratic, convex, etc.
EMAMOpt2CPP provides a [class](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMAMOpt2Cpp/-/blob/master/src/main/java/de/monticore/lang/monticar/generator/cpp/optimizationSolver/problem/OptimizationProblemClassification.java
) detecting the problem class:
However, it seems to eb buggy. The corresponding [test](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMAMOpt2Cpp/-/blob/master/src/test/java/de/monticore/lang/monticar/generator/cpp/optimizationSolver/problem/OptimizationProblemClassificationTest.java) has not been implemented.
Please investigate and try to fix this. We need a classification to enable an appropriate choice of solvers and also to possibly forbid some classes in safety critical systems.Jan Philipp HallerJan Philipp Haller2020-09-02https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMAM2Cpp/-/issues/46Index conversion bug2020-09-30T20:21:49+02:00Sascha DewesIndex conversion bugThere seems to be a bug with the conversion from EMA indices to Cpp indices. In the following example it looks like the ceil function was mistaken for an array as the generator applies the decrementation twice to the inputarray index.
I...There seems to be a bug with the conversion from EMA indices to Cpp indices. In the following example it looks like the ceil function was mistaken for an array as the generator applies the decrementation twice to the inputarray index.
Input Code:
```
implementation Math {
for i=1:3
outputarray(i) = ceil(inputarray(i));
end
}
```
Output Code:
```
void execute()
{
for( auto i=1;i<=3;++i){
outputarray(i-1) = ceil(inputarray(i-1-1));
}
}
```
The same Problem occurs when there is no actual array inside the function brackets.
Input Code:
```
implementation Math {
for i=1:3
Q x = inputarray(i);
outputarray(i) = ceil(x);
end
}
```
Output Code:
```
void execute()
{
for( auto i=1;i<=3;++i){
double x = inputarray(i-1);
outputarray(i-1) = ceil(x-1);
}
}
```https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/CNNArch2Gluon/-/issues/4Check if if-else is required2020-11-12T19:20:19+01:00Julian Johannes Steinsberger-DührßenCheck if if-else is requiredhttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/CNNArch2Gluon/-/blob/master/src/main/resources/templates/gluon/CNNSupervisedTrainer.ftl#L323https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/CNNArch2Gluon/-/blob/master/src/main/resources/templates/gluon/CNNSupervisedTrainer.ftl#L323Evgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/issues/17Create default Dockerfile to be able to test basic scripts2020-11-20T16:27:50+01:00Andreas WahlenCreate default Dockerfile to be able to test basic scriptsCreate a Dockerfile and add it to the repository to allow testing of EMADL models using the streamtest plugin.
Something like that would work (dependency is a local `jdk-8u271-linux-x64.tar.gz` file which is the Oracle JDK 8):
```docke...Create a Dockerfile and add it to the repository to allow testing of EMADL models using the streamtest plugin.
Something like that would work (dependency is a local `jdk-8u271-linux-x64.tar.gz` file which is the Oracle JDK 8):
```docker
FROM ubuntu:bionic
RUN apt update && apt install -y --no-install-recommends maven g++ make cmake libarmadillo-dev
WORKDIR /root
COPY jdk-8u271-linux-x64.tar.gz .
RUN tar -xzf jdk-8u271-linux-x64.tar.gz
RUN rm jdk-8u271-linux-x64.tar.gz
RUN mv jdk1.8.0_271 /opt
RUN update-alternatives --install "/usr/bin/java" "java" "/opt/jdk1.8.0_271/bin/java" 1
RUN update-alternatives --set "java" "/opt/jdk1.8.0_271/bin/java"
```
A corresponding `.gitlab-ci.yml` would look like this (settings.xml and pom.xml files are mandatory):
```yml
stages:
- integration
testIIR:
stage: integration
image: registry.git.rwth-aachen.de/se-student/ws2021/labs/connectedcars/ema
script:
- mvn streamtest:streamtest-execute -s settings.xml
except:
changes:
- README.md
- .gitignore
- .gitkeep
```
In the mean time: Feel free to choose [this image](https://git.rwth-aachen.de/se-student/ws2021/labs/connectedcars/ema/container_registry) for testing of basic models (which do not have any specific dependencies)Evgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/issues/18Bug: Access struct member of a port array2021-02-01T16:26:20+01:00Andreas WahlenBug: Access struct member of a port arrayAssume one has created an own struct type and wants to define an array of ports of this type.
Example:
```
struct MyStruct {
Q myMember;
}
```
```
component MyComponent {
port
in MyStruct inputStruct[2],
out Q ...Assume one has created an own struct type and wants to define an array of ports of this type.
Example:
```
struct MyStruct {
Q myMember;
}
```
```
component MyComponent {
port
in MyStruct inputStruct[2],
out Q outputMember;
implementation Math {
outputMember = inputStruct(1).myMember; // could not parse...
}
}
```
The problem seems to be the inline access of an element of the array and the member of this element at once. It works when one puts it into separat lines.Evgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/issues/19Semantics Update probably broke something2021-02-12T08:53:51+01:00Lukas BramSemantics Update probably broke somethingHi, we noticed that since the ExecutionSemantics update, the generator isn't able to compile the ema autopilot anymore. I tried to get a CI-Pipeline that reproduces the error, but the maven-streamtest plugin has some dependency-problems ...Hi, we noticed that since the ExecutionSemantics update, the generator isn't able to compile the ema autopilot anymore. I tried to get a CI-Pipeline that reproduces the error, but the maven-streamtest plugin has some dependency-problems at the moment, so it doesn't work. So I can only give you the error and a few of the files.
The error:
```
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
Scanning dependencies of target TestEmadlAutoPilotAdapter
[ 9%] Building CXX object CMakeFiles/TestEmadlAutoPilotAdapter.dir/network.cpp.o
[ 18%] Building CXX object CMakeFiles/TestEmadlAutoPilotAdapter.dir/server_adapter.cpp.o
In file included from /home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/server_adapter.h:8,
from /home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/server_adapter.cpp:1:
/home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/./de_rwth_connectedcars_testAutoPilot.h: In member function ‘void de_rwth_connectedcars_testAutoPilot::execute()’:
/home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/./de_rwth_connectedcars_testAutoPilot.h:36:1: error: ‘mps’ was not declared in this scope
36 | mps.currentVelKMH = true_velocity;
| ^~~
/home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/./de_rwth_connectedcars_testAutoPilot.h:37:1: error: ‘path’ was not declared in this scope
37 | path.current_pos = true_position;
| ^~~~
/home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/./de_rwth_connectedcars_testAutoPilot.h:38:1: error: ‘steering’ was not declared in this scope; did you mean ‘set_steering’?
38 | steering.currentAngle = true_compass;
| ^~~~~~~~
| set_steering
/home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/./de_rwth_connectedcars_testAutoPilot.h:40:1: error: ‘constr’ was not declared in this scope; did you mean ‘confstr’?
40 | constr.maxAllVelocity = trajectory_x;
| ^~~~~~
| confstr
/home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/./de_rwth_connectedcars_testAutoPilot.h:44:1: error: ‘coef’ was not declared in this scope; did you mean ‘cosf’?
44 | coef.execute();
| ^~~~
| cosf
/home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/./de_rwth_connectedcars_testAutoPilot.h:45:1: error: ‘pid’ was not declared in this scope
45 | pid.kI = coef.kI;
| ^~~
/home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/./de_rwth_connectedcars_testAutoPilot.h:49:1: error: ‘error’ was not declared in this scope; did you mean ‘perror’?
49 | error.currentVel = mps.currentVelMPS;
| ^~~~~
| perror
/home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/./de_rwth_connectedcars_testAutoPilot.h:50:1: error: ‘velCalc’ was not declared in this scope
50 | velCalc.currentVel = mps.currentVelMPS;
| ^~~~~~~
/home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/./de_rwth_connectedcars_testAutoPilot.h:52:1: error: ‘driveProf’ was not declared in this scope
52 | driveProf.maxAllVel = constr.maxVelocity;
| ^~~~~~~~~
/home/lukas/workspace/EmbeddedMontiArc/vcg-tools/build_environment/ema/src/target/cpp/./de_rwth_connectedcars_testAutoPilot.h:82:1: error: ‘res2pedal’ was not declared in this scope
82 | res2pedal.controlValue = pid.controlValue;
| ^~~~~~~~~
make[2]: *** [CMakeFiles/TestEmadlAutoPilotAdapter.dir/build.make:95: CMakeFiles/TestEmadlAutoPilotAdapter.dir/server_adapter.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:99: CMakeFiles/TestEmadlAutoPilotAdapter.dir/all] Error 2
make: *** [Makefile:149: all] Error 2
[ERROR] During compilation, an error occured. See above for more details.
```
What I noticed so far is that the resulting cpp files are erronuous. The component `coef` for example, is not directly part of the root component `TestAutopilot`. Instead it is a subcomponent of the `Velocity` component, which is itself a subcomponent of the `MovementController`, which again is a subcompoment of `TestAutopilot`. So the correct way to reference it in the resulting de_rwth_connectedcars_testAutoPilot.h cpp file should be `moveCont.vel.coef.execute();` but it instead was referenced like this `coef.execute();`.
And here the important files:
[de_rwth_connectedcars_testAutoPilot.h](/uploads/d264dac1be7d1b2d0d345898d6fb16d0/de_rwth_connectedcars_testAutoPilot.h)
[de_rwth_connectedcars_testAutoPilot_moveCon.h](/uploads/88e497a72e73061ab45138b588741397/de_rwth_connectedcars_testAutoPilot_moveCon.h)[de_rwth_connectedcars_testAutoPilot_vel.h](/uploads/93100d4b5c41f8c46dde54c2675a1d37/de_rwth_connectedcars_testAutoPilot_vel.h)[de_rwth_connectedcars_testAutoPilot_coef.h](/uploads/2ea9d5630420964080ccd196a0958ec1/de_rwth_connectedcars_testAutoPilot_coef.h)[TestAutoPilot.emadl](/uploads/cfac289f53a4c7aaecdbcd9e20af3966/TestAutoPilot.emadl)[MovementController.emadl](/uploads/e1864d011f7e16a27ab67b029e0d642c/MovementController.emadl)[Velocity.emadl](/uploads/8d93bbb55a3e10194bacccf1015e70ec/Velocity.emadl)[PIDcoef.emadl](/uploads/504cf7e5eddb58fb7b7293064725b3f7/PIDcoef.emadl)Evgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/issues/20Bug: Arrays of instances do not work2021-02-03T17:20:05+01:00Andreas WahlenBug: Arrays of instances do not workThe following can be parsed but generation of C++ code fails with "no value present":
```
component TestInstArray {
port
in Q x[2],
out Q y[2];
instance Identity idInst[2];
connect x[1] -> idInst[1].x;
connect x[2] -> idInst[2]...The following can be parsed but generation of C++ code fails with "no value present":
```
component TestInstArray {
port
in Q x[2],
out Q y[2];
instance Identity idInst[2];
connect x[1] -> idInst[1].x;
connect x[2] -> idInst[2].x;
connect idInst[1].y -> y[1];
connect idInst[2].y -> y[2];
}
```Evgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/issues/21Connect of full array2021-02-03T17:44:34+01:00Andreas WahlenConnect of full array```
component Dummy {
port
in Q x[2],
out Q y;
instance Foo bar; // assume there is an input port array like x above
connect x -> bar.x; // does not work
connect x[1] -> bar.x[1]; // currently p...```
component Dummy {
port
in Q x[2],
out Q y;
instance Foo bar; // assume there is an input port array like x above
connect x -> bar.x; // does not work
connect x[1] -> bar.x[1]; // currently possible workaround
connect x[2] -> bar.x[2];
}
```Evgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/issues/22NullPointerException instead of proper error message when undefined port is used2021-02-03T18:46:34+01:00Andreas WahlenNullPointerException instead of proper error message when undefined port is usedWhen using an undefined port (e.g. in a connect statement) the maven plugin will output a NullPointerException instead of a proper error message.When using an undefined port (e.g. in a connect statement) the maven plugin will output a NullPointerException instead of a proper error message.Evgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/issues/23StackOverflowError2021-02-10T16:41:25+01:00Andreas WahlenStackOverflowErrorPipeline: https://git.rwth-aachen.de/se-student/ws2021/labs/connectedcars/ema/-/jobs/1458084
Branch: https://git.rwth-aachen.de/se-student/ws2021/labs/connectedcars/ema/-/tree/andreaswPipeline: https://git.rwth-aachen.de/se-student/ws2021/labs/connectedcars/ema/-/jobs/1458084
Branch: https://git.rwth-aachen.de/se-student/ws2021/labs/connectedcars/ema/-/tree/andreaswEvgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/issues/24Warning for types in structs2021-02-10T17:09:12+01:00Andreas WahlenWarning for types in structs`[WARN] unknown type symbol: Q`
Where Q is the type used inside a struct. Could also be N, Z, ...
After all the generator produces the expected code correctly.`[WARN] unknown type symbol: Q`
Where Q is the type used inside a struct. Could also be N, Z, ...
After all the generator produces the expected code correctly.Evgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/issues/25Usage of type N inside structs leads to error2021-02-10T17:31:17+01:00Andreas WahlenUsage of type N inside structs leads to errorError message is: [ERROR] 0xA1038 SymbolReference Could not load full information of 'N' (Kind de.monticore.lang.monticar.ts.MCTypeSymbolKind)
No stack trace present.Error message is: [ERROR] 0xA1038 SymbolReference Could not load full information of 'N' (Kind de.monticore.lang.monticar.ts.MCTypeSymbolKind)
No stack trace present.Evgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/issues/26Output ports can not be used for further connects2021-03-14T14:15:44+01:00Andreas WahlenOutput ports can not be used for further connectsWhen using an output port as a source of a connect statement, there will be no error or warning but no corresponding code will be generated.
This should either throw an error or just work. Could be helpful in situations like the followi...When using an output port as a source of a connect statement, there will be no error or warning but no corresponding code will be generated.
This should either throw an error or just work. Could be helpful in situations like the following:
```
package ...;
component Test {
port
in x,
out y,
out z;
instance InstX instX;
instance InstY instY;
connect x -> instX.param;
connect instX.res -> y;
connect y -> instY.param; // this is the problematic line, one could of course also use instX.res again
connect instY.res -> z;
}
```Evgeny KusmenkoEvgeny Kusmenkohttps://git.rwth-aachen.de/monticore/EmbeddedMontiArc/simulators/simulation/-/issues/30Time-control bugs2021-10-20T17:46:50+02:00Jean MeuriceTime-control bugs## Problem
The time-control of the visualization does not seem to be correct.
For example, with the "simulation-speed" set to low values (1/4, 1/8, ...) the control loop can stop advancing the simulation.
Generally, the visualization ...## Problem
The time-control of the visualization does not seem to be correct.
For example, with the "simulation-speed" set to low values (1/4, 1/8, ...) the control loop can stop advancing the simulation.
Generally, the visualization does not handle the rendering time well in order to prioritize the simulation speed.
## Fixes
A correct time-control loop should adapt the FPS to keep-up the desired simulation speed up to a certain minimum FPS limit.
Right now, the updates are handled in a java `Timer` callback. This is used in order to be in the GUI thread. However this makes the control loop logic hard. Ideally, the control logic should be as presented [here](https://gafferongames.com/post/fix_your_timestep/) (with fixed time-steps).
**If the [Async Simulation and Visualization](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/simulators/basic-simulator/-/issues/3) are implemented again**, the visualization control loop would be completely different since the simulation would not have to be updated in parallel.https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/simulators/simulation/-/issues/29OpenGL visualization2021-10-20T17:38:41+02:00Jean MeuriceOpenGL visualization## Problem
- Right now, the 2D visualization of the maps and vehicles uses the `Graphics2D` java class inside the `Swing` components.
- This is not a very efficient rendering method, especially for large scale cities.
- It is also not p...## Problem
- Right now, the 2D visualization of the maps and vehicles uses the `Graphics2D` java class inside the `Swing` components.
- This is not a very efficient rendering method, especially for large scale cities.
- It is also not precise: the polygon geometry can only be passed with integer pixel positions.
## Solution
Use OpenGL rendering.
- As OpenGL library (for example): [JOGL](https://jogamp.org/jogl/www/)
- [JOGL in Swing](https://www.tutorialspoint.com/jogl/jogl_canvas_with_swing.htm) (Still up-to-date ?)
- [OpenGL 4 JOGL sample](https://github.com/jvm-graphics-labs/hello-triangle)
- TODOs:
- Test a simple 2D triangle with a basic shader.
- Make it build and run using the JOGL maven artifacts.
- Make a *colored triangle* shader with an orthogonal view matrix, test binding it to the map controls (position, zoom). Render a simple triangle (or 2)
- Make a *colored line* shader, same view matrix, test a simple outline.
- Generate the building geometry in one VBO/VAO/EBO set.
- Use the already split convex parts
- The *convex* polygon parts can be rendered using the `GL_TRIANGLE_FAN` drawing mode
- In combination with the [Primitive Restart](https://stackoverflow.com/questions/4386861/opengl-jogl-multiple-triangle-fans-in-a-vertex-array)
- Use an Element-Buffer
- Use the `PRIMITIVE_RESTART` index to separate triangle fans for different polygons
- Since we only want to draw contiguous vertices, the `glMultiDrawElements()` method can be useful
- Generate the road geometry (or visualization lines)
- Generate the vehicle geometry (one VBO/EBO/VAO set)
- Same triangle shader, but give it a view+model matrix (pre-multiplied)
- All the debug lines/elements (AABB, building outlines, ...) can be in their own VBO/EBO/VAO.
- **Check the thread interaction between Swing and OpenGL**. The OpenGL calls are not thread-safe for a given context. Be sure that the OpenGL calls happen in the correct thread.
- [Swing Threads](http://www.javapractices.com/topic/TopicAction.do?Id=153)
**Note**: The existing visualization already "pre-generates" the geometry in some way to save computation. Changing to save this geometry in OpenGL buffer would not be a big change.