Skip to content

Commit

Permalink
Various minor improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
pschillinger committed Apr 19, 2019
1 parent 49fdd4b commit 8e6d4c4
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 32 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
nwjs/
.*/**
3 changes: 3 additions & 0 deletions launch/flexbe_full.launch
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

<launch>

<arg name="no_app" default="false" />

<include file="$(find flexbe_app)/launch/flexbe_ocs.launch" >
<arg name="offline" value="false"/>
<arg name="no_app" value="$(arg no_app)"/>
</include>

<include file="$(find flexbe_onboard)/launch/behavior_onboard.launch" />
Expand Down
4 changes: 3 additions & 1 deletion launch/flexbe_ocs.launch
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
<arg name="offline_arg" value="--offline" if="$(arg offline)" />
<arg name="offline_arg" value="" unless="$(arg offline)" />

<arg name="no_app" default="false" />

<node name="behavior_mirror" pkg="flexbe_mirror" type="behavior_mirror_sm" output="screen" />

<node name="flexbe_app" pkg="flexbe_app" type="run_app" args="$(arg offline_arg)" output="screen" />
<node name="flexbe_app" pkg="flexbe_app" type="run_app" args="$(arg offline_arg)" output="screen" unless="$(arg no_app)" />

<node name="behavior_launcher" pkg="flexbe_widget" type="be_launcher" output="screen" />

Expand Down
16 changes: 16 additions & 0 deletions src/_helper/checking.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ Checking = new (function() {
return error;
}

try {
// this needs to work when starting a behavior
Behavior.createStructureInfo();
} catch (error) {
var container_path = error.path.replace("/"+error.path.split("/").pop(), "");
var container = Behavior.getStatemachine().getStateByPath(container_path);
if (container instanceof BehaviorState) {
error.error += "<br />Note: Since this error is inside a contained behavior, please open this behavior directly and fix it there.";
error.error += "<br />Affected behavior: " + container.getBehaviorName();
container = container.getBehaviorStatemachine();
}
UI.Statemachine.setDisplayedSM(container);
UI.Menu.toStatemachineClicked();
return error.error;
}

return undefined;
}

Expand Down
49 changes: 27 additions & 22 deletions src/_model/behavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ Behavior = new (function() {
var result = [];

createStateStructure(root_sm, result);

return result;
}

Expand All @@ -349,31 +350,35 @@ Behavior = new (function() {
result.path = s.getStatePath();
result.outcomes = s.getOutcomes();
result.transitions = [];
if (s.getContainer() != undefined) {
result.autonomy = s.getAutonomy();
var transitions = s.getContainer().getTransitions();
for (var i=0; i<result.outcomes.length; i++) {
var transition = transitions.findElement(function(element) {
return element.getFrom().getStateName() == s.getStateName() && element.getOutcome() == result.outcomes[i];
});
var target_name = transition.getTo().getStateName();
if (s.getContainer().isConcurrent() && transition.getTo().getStateClass() == ':CONDITION') {
target_name = target_name.split('#')[0];
try {
if (s.getContainer() != undefined) {
result.autonomy = s.getAutonomy();
var transitions = s.getContainer().getTransitions();
for (var i=0; i<result.outcomes.length; i++) {
var transition = transitions.findElement(function(element) {
return element.getFrom().getStateName() == s.getStateName() && element.getOutcome() == result.outcomes[i];
});
var target_name = transition.getTo().getStateName();
if (s.getContainer().isConcurrent() && transition.getTo().getStateClass() == ':CONDITION') {
target_name = target_name.split('#')[0];
}
result.transitions.push(target_name);
}
result.transitions.push(target_name);
}
}
result.children = [];
if (s instanceof BehaviorState) {
s = s.getBehaviorStatemachine();
}
if (s instanceof Statemachine) {
var children = s.getStates();
for (var c=0; c<children.length; c++) {
var child = children[c];
result.children.push(children[c].getStateName());
createStateStructure(children[c], info);
result.children = [];
if (s instanceof BehaviorState) {
s = s.getBehaviorStatemachine();
}
if (s instanceof Statemachine) {
var children = s.getStates();
for (var c=0; c<children.length; c++) {
var child = children[c];
result.children.push(children[c].getStateName());
createStateStructure(children[c], info);
}
}
} catch (error) {
throw {path: error.path || result.path, error: error.error || error};
}
info.push(result);
}
Expand Down
13 changes: 12 additions & 1 deletion src/io/io_modelgenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,18 @@ IO.ModelGenerator = new (function() {
}
if (state_def == undefined) {
var state_key = s_def.state_class;
var state_def = WS.Statelib.getClassFromLib(state_key);
var state_def = WS.Statelib.getClassFromLib(state_key, WS.Statelib.isClassUnique(state_key)? undefined : lib_def => {
for (var j=0; j<s_def.transitions_from.length; j++) {
if (!lib_def.getOutcomes().contains(s_def.transitions_from[j].outcome)) {
return false;
}
}
return true;
});
if (state_def != undefined && !WS.Statelib.isClassUnique(state_key)) {
T.logWarn("State class name " + state_key + " is not unique, but was able to re-construct.");
T.logWarn("Please save behavior again to fix this for the future.");
}
}
if (state_def == undefined) {
T.logError("Unable to find state definition for: " + state_key);
Expand Down
9 changes: 8 additions & 1 deletion src/rc/rc_pubsub.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,13 +447,20 @@ RC.PubSub = new (function() {
RC.Controller.signalStarted();
RC.Sync.register("BehaviorStart", 60);

var behavior_structure = undefined;
try {
behavior_structure = Behavior.createStructureInfo();
} catch (error) {
T.logError("Failed to construct behavior structure, execution might fail: " + error);
}

// request start
behavior_start_publisher.publish({
behavior_name: Behavior.getBehaviorName(),
autonomy_level: autonomy,
arg_keys: param_keys,
arg_values: param_vals,
structure: Behavior.createStructureInfo()
structure: behavior_structure
});
RC.Sync.setProgress("BehaviorStart", 0.2, false);
});
Expand Down
23 changes: 20 additions & 3 deletions src/ui/ui_runtimecontrol.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,21 @@ UI.RuntimeControl = new (function() {
var doc = "";

if (state instanceof Statemachine) {
doc += "<b>Statemachine</b><br />";
doc += "<b>Container</b><br /><br />";
if (state.isConcurrent()) {
doc += "Execution type: Concurrency<br />";
doc += "<i>Parallel execution of all elements.</i><br />";
} else if (state.isPriority()) {
doc += "Execution type: Priority<br />";
doc += "<i>Execution supersedes all other containers.</i><br />";
} else {
doc += "Execution type: Statemachine<br />";
doc += "<i>Sequential execution based on outcomes.</i><br />";
}
doc += "<br />Double-click the displayed container symbol to look inside."
} else if (state instanceof BehaviorState) {
doc += "<b>Behavior</b><br />";
doc += "<b>" + state.getBehaviorName() + "</b> (Behavior)<br />";
doc += WS.Behaviorlib.getByName(state.getBehaviorName()).getBehaviorDesc() + "<br />";
} else if (WS.Statelib.getFromLib(state_type) != undefined) {
doc += "<b>" + state_type + "</b><br />";
doc += WS.Statelib.getFromLib(state_type).getStateDesc() + "<br />";
Expand All @@ -224,6 +236,11 @@ UI.RuntimeControl = new (function() {
doc += " (" + resolved + ")</div>";
}
}
doc += "<br /><br />";
doc += "<b>Outcomes:</b><br />";
WS.Statelib.getFromLib(state_type).getOutcomeDesc().forEach(outcome => {
doc += "<div><b>" + outcome.name + "</b>: " + outcome.desc + "</div>";
});
}

document.getElementById("runtime_documentation_text").innerHTML = doc;
Expand Down Expand Up @@ -501,7 +518,7 @@ UI.RuntimeControl = new (function() {
});
var selection_box = document.getElementById("selection_rc_autonomy");
var autonomy_value = parseInt(selection_box.options[selection_box.selectedIndex].value);
RC.PubSub.sendBehaviorStart(param_keys, param_vals, autonomy_value);
RC.PubSub.sendBehaviorStart(param_keys, param_vals, autonomy_value);
});
}

Expand Down
4 changes: 2 additions & 2 deletions src/window.html
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,12 @@ <h1>No connection!</h1>
<ul>
<li>
Make sure the onboard behavior engine is running in the current ROS environment. You can start it with the following command:<br />
<input id="rc_command_engine" type="text" value="roslaunch flexbe_onboard behavior_onboard.launch" class="code_copy" readonly="readonly" size="39" />
<input id="rc_command_engine" type="text" value="roslaunch flexbe_onboard behavior_onboard.launch" class="code_copy" readonly="readonly" size="38" />
<br /><br />
</li>
<li>
Make sure that operator control software is running for starting a behavior and monitoring its execution. You can start it with the following command:<br />
<input id="rc_command_engine" type="text" value="roslaunch flexbe_widget behavior_ocs.launch" class="code_copy" readonly="readonly" size="34" />
<input id="rc_command_engine" type="text" value="roslaunch flexbe_app flexbe_ocs.launch no_app:=true" class="code_copy" readonly="readonly" size="39" />
<br /><br />
</li>
<li>
Expand Down
4 changes: 2 additions & 2 deletions src/ws/ws_statelib.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ WS.Statelib = new (function() {
}
}

this.getClassFromLib = function(state_class) {
this.getClassFromLib = function(state_class, filter_function) {
for (var i=0; i<statelib.length; ++i) {
if (state_class == statelib[i].getStateClass())
if (state_class == statelib[i].getStateClass() && (!filter_function || filter_function(statelib[i])))
return statelib[i];
}
}
Expand Down

0 comments on commit 8e6d4c4

Please sign in to comment.