Move to subdirectory

This commit is contained in:
David Walsh
2019-07-19 12:43:02 -04:00
parent 1cf300f0c4
commit 8026e28d43
7400 changed files with 0 additions and 510024 deletions

View File

@@ -0,0 +1,93 @@
<div class="tab-pane" id="rosbridgeconnection">
<div class="panel panel-default">
<div class="panel-body">
<form class="form-inline" role="form" onsubmit="return validateForm()">
<div id="ConnectionIPForm" class="form-group" align="center">
<span>
<label id="ConnectionIPLabel" class="control-label" for="inputWarning">
Connect To:
</label>
</span>
<span>
<div class="input-group">
<input type="text" id="ConnectionIPInput" class="form-control" placeholder="ROS Bridge Master IP" placeholder="No IP Address yet">
<span class="input-group-btn">
<button id="ConnectionButton" type="button" onclick="ros.attemptConnection()" class="btn btn-primary">
Connect
<script type="text/javascript">
document.getElementById("ConnectionIPInput").value = ros.connectionName;
</script>
</button>
</span>
</div>
</span>
</div>
</form>
</div>
<div class="panel panel-default">
<div class="panel-heading">
Predefined ROSBridge Connections
</div>
<div class="panel-body">
<button id="localhostButton" type="button" onclick="ros.attemptConnection('ws://localhost:9090')" class="btn btn-primary">
localhost
<script type="text/javascript">
document.getElementById("ConnectionIPInput").value = ros.connectionName;
</script>
</button>
<button id="TitanButton" type="button" onclick="ros.attemptConnection('ws://titan.local:9090')" class="btn btn-primary">
Titan
<script type="text/javascript">
document.getElementById("ConnectionIPInput").value = ros.connectionName;
</script>
</button>
<button id="PhoebeButton" type="button" onclick="ros.attemptConnection('ws://phoebe.local:9090')" class="btn btn-primary">
Phoebe
<script type="text/javascript">
document.getElementById("ConnectionIPInput").value = ros.connectionName;
</script>
</button>
<button id="RheaButton" type="button" onclick="ros.attemptConnection('ws://rhea.local:9090')" class="btn btn-primary">
Rhea
<script type="text/javascript">
document.getElementById("ConnectionIPInput").value = ros.connectionName;
</script>
</button>
</div>
</div>
</div>
<script type="text/javascript">
// Create a connection to the rosbridge WebSocket server.
ros.connect(ros.connectionName);
</script>
<div class="panel panel-default">
<div class="panel-heading">
ROS Topics.
</div>
<div class="panel-body">
<div class="col-sm-1" id="ROSTopics">
N/A
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
ROS Nodes.
</div>
<div class="panel-body">
<div class="col-sm-1" id="ROSNodes">
N/A
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,706 @@
<div id="coordinator">
<div class="col-md-6">
<div class="hand-panel hand-panel-left panel panel-default">
<div class="panel-heading">
<i class="far fa-2x fa-hand-point-left"></i>
Left Arm
</div>
<div class="panel-body">
<div class="status-bar">
<div class="status-container">
<div class="safety-monitor panel panel-default panel-horizontal">
<div class="panel-heading">
Safety Monitor
</div>
<div class="panel-body text-center">
<div class="status-list">
<ul class="list-group list-group-horizontal">
<li id="left_safetyRunning" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Running</label>
</div>
</div>
</li>
<li id="left_safetyStopped" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Stopped</label>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="action-button panel-footer">
<button type="button" onclick="triggerService('/left/aescape/mode/activateSafetyController')" class="btn">
Activate
</button>
</div>
</div>
</div>
<div class="status-container">
<div class="franka panel panel-default panel-horizontal">
<div class="panel-heading">
Franka Arm
</div>
<div class="panel-body text-center">
<div class="status-list">
<ul class="list-group list-group-horizontal">
<li id="left_frankaModeOther" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Other</label>
</div>
</div>
</li>
<li id="left_frankaModeIdle" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Idle</label>
</div>
</div>
</li>
<li id="left_frankaModeMove" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Move</label>
</div>
</div>
</li>
<li id="left_frankaModeGuiding" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Guiding</label>
</div>
</div>
</li>
<li id="left_frankaModeReflex" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Reflex</label>
</div>
</div>
</li>
<li id="left_frankaModeUserStopped" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>User Stopped</label>
</div>
</div>
</li>
<li id="left_frankaModeErrorRecovery" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Automatic Error Recovery</label>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="action-button panel-footer">
<button id="left_fixFrankaButton" type="button" onclick="triggerService('/left/aescape/hardware/resetFrankaError')" class="btn">
Fix Errors
</button>
</div>
</div>
</div>
<div class="status-container">
<div class="franka-force force-bar panel panel-default panel-horizontal">
<div class="panel-heading">
Franka Force
</div>
<div class="panel-body text-center">
<div class="status-list">
<div class="commanded">
<div class="progress">
<!-- <div class="progress-bar-label">Commanded</div> -->
<div class="progress-bar bg-success" role="progressbar" id="frankaForceCommandedLeft" aria-valuenow="25" aria-valuemin="0" aria-valuemax="200">N/A</div>
</div>
<ul class="list-group list-group-horizontal text-center">
<li class="list-group-item force-value">
<h4>X: <span id="frankaForceLeftCommandedX">0.0</span></h4>
</li>
<li class="list-group-item force-value">
<h4>Y: <span id="frankaForceLeftCommandedY">0.0</span></h4>
</li>
<li class="list-group-item force-value">
<h4>Z: <span id="frankaForceLeftCommandedZ">0.0</span></h4>
</li>
</ul>
</div>
<div class="observed">
<div class="progress">
<!-- <div class="progress-bar-label">Observed</div> -->
<div class="progress-bar bg-success" role="progressbar" id="frankaForceObservedLeft" aria-valuenow="25" aria-valuemin="0" aria-valuemax="200">
<span>N/A</span>
<div>
<span>Observed</span>
</div>
</div>
</div>
<ul class="list-group list-group-horizontal text-center">
<li class="list-group-item force-value">
<h4>X: <span id="frankaForceLeftObservedX">0.0</span></h4>
</li>
<li class="list-group-item force-value">
<h4>Y: <span id="frankaForceLeftObservedY">0.0</span></h4>
</li>
<li class="list-group-item force-value">
<h4>Z: <span id="frankaForceLeftObservedZ">0.0</span></h4>
</li>
</ul>
</div>
</div>
</div>
<div class="action-button panel-footer">
</div>
</div>
</div>
<div class="status-container">
<div class="robotiq force-bar panel panel-default panel-horizontal">
<div class="panel-heading">
Robotiq
</div>
<div class="panel-body text-center">
<div class="status-list">
<div class="progress" id="robotiqForce">
<div class="progress-bar bg-success" role="progressbar" id="robotiqForceBar" aria-valuenow="25" aria-valuemin="0" aria-valuemax="200">N/A</div>
</div>
<ul class="list-group list-group-horizontal text-center">
<li class="list-group-item force-value">
<h4>X: <span id="robotiqX">0.0</span></h4>
</li>
<li class="list-group-item force-value">
<h4>Y: <span id="robotiqY">0.0</span></h4>
</li>
<li class="list-group-item force-value">
<h4>Z: <span id="robotiqZ">0.0</span></h4>
</li>
</ul>
</div>
</div>
<div class="action-button panel-footer">
<button id="calibrateButton" type="button" onclick="triggerService('/left/aescape/hardware/calibrateRobotiq')" class="btn">
Calibrate
</button>
</div>
</div>
</div>
</div>
<div class="control-container col-md-6">
<div class="control-card panel panel-default">
<div class="panel-heading">
EEF Configuration
<i class="fas fa-info-circle" tabindex="0" data-toggle="popover" data-trigger="focus" data-content="This selects the end-effector attached to the left arm."></i>
</div>
<div class="panel-body text-center">
<div class="button-area">
<button type="button" onclick="setEEFConfig('left', 'teach')" active class="btn btn-primary col-md-6">
Recording EEF
</button>
<button type="button" onclick="setEEFConfig('left', 'play')" class="btn btn-primary col-md-6">
Massage EEF
</button>
</div>
</div>
<div class="action-area panel-footer">
<div class="message">
<!--You must be in "Stopped Mode" to change the EEF configuration! -->
</div>
</div>
</div>
</div>
<div class="control-container col-md-6">
<div id="left-operation-mode" class="control-card-six control-card panel panel-default">
<div class="panel-heading">
Operation Mode
<i class="fas fa-info-circle" tabindex="0" data-toggle="popover" data-trigger="focus" data-content="This selects the operation mode of the left arm."></i>
</div>
<div class="panel-body text-center">
<div class="button-area">
<button id="left_teachingModeButton" type="button" onclick="triggerService('/left/aescape/mode/activateTeachingController')" class="btn btn-primary col-md-4">
Teaching
</button>
<button id="left_executionModeButton" type="button" onclick="triggerService('/left/aescape/mode/activateExecutionController')" class="btn btn-primary col-md-4">
Massage
</button>
<button id="left_readyModeButton" type="button" onclick="triggerService('/left/aescape/mode/activateReadyController')" class="btn btn-primary col-md-4">
Ready
</button>
<button id="left_standbyModeButton" type="button" onclick="triggerService('/left/aescape/mode/activateStandbyController')" class="btn btn-primary col-md-4">
Standby
</button>
<button id="left_stoppedModeButton" type="button" onclick="triggerService('/left/aescape/mode/stopControllers')" class="btn btn-primary col-md-4">
Stopped
</button>
</div>
<!--
<div class="col-md-6">
Safety Monitor Status:
<div class="row-md-3">
<h4><span id="left_safetyRunning" class="label label-default">Running</span></h4>
</div>
<div class="row-md-3">
<h4><span id="left_safetyStopped" class="label label-default">Stopped</span></h4>
</div>
<div class="row-md-3">
<button type="button" onclick="triggerService('/left/aescape/mode/activateSafetyController')" class="btn btn-sm">
Activate Safety Monitor
</button>
</div>
</div>
-->
</div>
<div class="action-area panel-footer">
<div class="message">
</div>
</div>
</div>
</div>
<!--
<div class="control-container col-md-6">
<div class="control-card panel panel-default">
<div class="panel-heading">
Robotiq
<i class="fas fa-info-circle"></i>
</div>
<div class="panel-body text-center">
<div class="progress" id="robotiqForce">
<div class="progress-bar bg-success" role="progressbar" id="robotiqForceBar" aria-valuenow="25" aria-valuemin="0" aria-valuemax="200">N/A</div>
</div>
<div class="button-area">
Current Robotiq Values:
<h4>X: <span id="robotiqX" class="label label-default">0.0</span></h4>
<h4>Y: <span id="robotiqY" class="label label-default">0.0</span></h4>
<h4>Z: <span id="robotiqZ" class="label label-default">0.0</span></h4>
</div>
</div>
<div class="action-area panel-footer">
<div class="button">
<button id="calibrateButton" type="button" onclick="triggerService('/left/aescape/hardware/calibrateRobotiq')" class="btn btn-primary">
Calibrate Robotiq
</button>
</div>
</div>
</div>
</div>
-->
<div class="control-container teaching-mode-operations col-md-7">
<div class="control-card panel panel-default">
<div class="panel-heading">
Teaching Mode Operations
<i class="fas fa-info-circle" tabindex="0" data-toggle="popover" data-trigger="focus" data-content="This helps recoding a new massage!"></i>
</div>
<div class="panel-body text-center">
<div class="button-area">
<button id="recordingStartButton" type="button" onclick="startTeachRecoding()" class="btn btn-primary col-md-6">
Start Recording
</button>
<button id="recordingStopButton" type="button" onclick="stopTeachRecording()" class="btn btn-primary col-md-6">
Stop Recording
</button>
</div>
</div>
<div class="action-area panel-footer">
<div id="RecordingStatusLabel" class="message">
<!-- TO DO: Show errors in bag manager -->
</div>
<div class="slider-options tagging-options" id="teachTags">
<div class="col-md-10">
<!--full with naming box search:no new:yes-->
<select id="teachBagFileName" placeholder="Filename"></select>
<!--full width category box search:yes new:yes-->
<select id="teachBagCategory" placeholder="Category"></select>
<!--full width tags box search:yes new:yes-->
<select id="teachBagTags" placeholder="Tags"></select>
</div>
<div class="col-md-2">
<button class="btn btn-primary" onclick="hideTaggingOptions('teach', true)">Tag</button>
<button class="btn btn-primary" onclick="hideTaggingOptions('teach', false)">Cancel</button>
</div>
</div>
<div id="teachTagError" class="col-md-10 error"></div>
<div class="clearfix"></div>
</div>
</div>
</div>
<div class="control-container play-mode-operations col-md-10">
<div class="control-card panel panel-default execution-control">
<div class="panel-heading">
Play Mode Operations
<i class="fas fa-info-circle" tabindex="0" data-toggle="popover" data-trigger="focus" data-content="This helps selecting and playback of recorded massages!"></i>
</div>
<div class="panel-body text-center">
<div class="button-area">
<button id="executionLoadButton" type="button" onclick="displayLoadingOptions()" class="btn btn-primary col-md-3">
Load Recording
</button>
<button id="executionLoadButton" type="button" onclick="triggerService('/aescape/massageReady')" class="btn btn-primary col-md-3">
Complete Body Scaling
</button>
<button id="executionStartButton" type="button" onclick="playLoadedRecording()" class="btn btn-primary col-md-3">
Play Loaded Recording
</button>
<button id="executionStopButton" type="button" onclick="stopPlayingRecording()" class="btn btn-primary col-md-3">
Stop Playing Recording
</button>
</div>
<div>
<!-- <div class="row-md-4">
<<div class="col-md-3"> -->
<!-- Bagfile name must not start with "/"
<button class="btn btn-primary" type="button" onclick="updateRecordingsList()">
Refresh List
</button>
</div> -->
</div>
</div>
<div class="action-area panel-footer">
<div class="message" id="ExecutionStatusLabel">
<!-- TO DO: Show errors in bag manager -->
</div>
<!-- TO DO: Bagfile name must not start with "/" -->
<div class="slider-options tagging-options" id="playTags">
<div class="col-md-10">
<!--full with naming box search:no new:yes-->
<select id="playBagFileName" placeholder="Filename"></select>
<!--full width category box search:yes new:yes-->
<select id="playBagCategory" placeholder="Category"></select>
<!--full width tags box search:yes new:yes-->
<select id="playBagTags" placeholder="Tags"></select>
</div>
<div class="col-md-2">
<button class="btn btn-primary" onclick="hideTaggingOptions('play', true)">Tag</button>
<button class="btn btn-primary" onclick="hideTaggingOptions('play', false)">Cancel</button>
</div>
</div>
<div class="slider-options loading-options" id="loadBags">
<div class="col-md-10">
<div class="dropdown">
<div>
<select id="loadBagList" placeholder="Select bag to play"></select>
<select id="armMode"></select>
</div>
<!-- <i class="fas fa-sync-alt" onclick="updateRecordingsList()"></i> -->
</div>
</div>
<div class="col-md-2">
<!-- <i class="fas fa-check-circle" onclick="hideLoadingOptions(true)"></i> -->
<button class="btn btn-primary" onclick="hideLoadingOptions(true)">Load</button>
<button class="btn btn-primary" onclick="hideLoadingOptions(false)">Cancel</button>
</div>
</div>
<div id="playTagError" class="col-md-10 error"></div>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
<div class="panel-footer">
</div>
</div>
</div>
<div class="col-md-6">
<div class="hand-panel hand-panel-right panel panel-default">
<div class="panel-heading">
Right Arm
<i class="far fa-2x fa-hand-point-right"></i>
</div>
<div class="panel-body">
<div class="status-bar">
<div class="status-container">
<div class="safety-monitor panel panel-default panel-horizontal">
<div class="panel-heading">
Safety Monitor
</div>
<div class="panel-body text-center">
<div class="status-list">
<ul class="list-group list-group-horizontal">
<li id="right_safetyRunning" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Running</label>
</div>
</div>
</li>
<li id="right_safetyStopped" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Stopped</label>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="action-button panel-footer">
<button type="button" onclick="triggerService('/left/aescape/mode/activateSafetyController')" class="btn">
Activate
</button>
</div>
</div>
</div>
<div class="status-container">
<div class="franka panel panel-default panel-horizontal">
<div class="panel-heading">
Franka Arm
</div>
<div class="panel-body text-center">
<div class="status-list">
<ul class="list-group list-group-horizontal">
<li id="right_frankaModeOther" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Other</label>
</div>
</div>
</li>
<li id="right_frankaModeIdle" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Idle</label>
</div>
</div>
</li>
<li id="right_frankaModeMove" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Move</label>
</div>
</div>
</li>
<li id="right_frankaModeGuiding" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Guiding</label>
</div>
</div>
</li>
<li id="right_frankaModeReflex" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Reflex</label>
</div>
</div>
</li>
<li id="right_frankaModeUserStopped" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>User Stopped</label>
</div>
</div>
</li>
<li id="right_frankaModeErrorRecovery" class="list-group-item">
<div class="pretty p-default p-round">
<input type="checkbox" class="disabled"/>
<div class="state p-success-o">
<label>Automatic Error Recovery</label>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="action-button panel-footer">
<button id="right_fixFrankaButton" type="button" onclick="triggerService('/right/aescape/hardware/resetFrankaError')" class="btn">
Fix Errors
</button>
</div>
</div>
</div>
<div class="status-container">
<div class="franka-force force-bar panel panel-default panel-horizontal">
<div class="panel-heading">
Franka Force
</div>
<div class="panel-body text-center">
<div class="status-list">
<div class="commanded">
<div class="progress">
<!-- <div class="progress-bar-label">Commanded</div> -->
<div class="progress-bar bg-success" role="progressbar" id="frankaForceCommandedRight" aria-valuenow="25" aria-valuemin="0" aria-valuemax="200">N/A</div>
</div>
<ul class="list-group list-group-horizontal text-center">
<li class="list-group-item force-value">
<h4>X: <span id="frankaForceRightCommandedX">0.0</span></h4>
</li>
<li class="list-group-item force-value">
<h4>Y: <span id="frankaForceRightCommandedY">0.0</span></h4>
</li>
<li class="list-group-item force-value">
<h4>Z: <span id="frankaForceRightCommandedZ">0.0</span></h4>
</li>
</ul>
</div>
<div class="observed">
<div class="progress">
<!-- <div class="progress-bar-label">Observed</div> -->
<div class="progress-bar bg-success" role="progressbar" id="frankaForceObservedRight" aria-valuenow="25" aria-valuemin="0" aria-valuemax="200">
<span>N/A</span>
<div>
<span>Observed</span>
</div>
</div>
</div>
<ul class="list-group list-group-horizontal text-center">
<li class="list-group-item force-value">
<h4>X: <span id="frankaForceRightObservedX">0.0</span></h4>
</li>
<li class="list-group-item force-value">
<h4>Y: <span id="frankaForceRightObservedY">0.0</span></h4>
</li>
<li class="list-group-item force-value">
<h4>Z: <span id="frankaForceRightObservedZ">0.0</span></h4>
</li>
</ul>
</div>
</div>
</div>
<div class="action-button panel-footer">
</div>
</div>
</div>
</div>
<div class="control-container col-md-6">
<div class="control-card panel panel-default">
<div class="panel-heading">
EEF Configuration
<i class="fas fa-info-circle" tabindex="0" data-toggle="popover" data-trigger="focus" data-content="This selects the end-effector attached to the right arm."></i>
</div>
<div class="panel-body text-center">
<div class="button-area">
<button type="button" onclick="setEEFConfig('right', 'teach')" class="btn btn-primary col-md-6">
Recording EEF
</button>
<button type="button" onclick="setEEFConfig('right', 'play')" class="btn btn-primary col-md-6">
Massage EEF
</button>
</div>
</div>
<div class="action-area panel-footer">
<div class="message">
<!--You must be in "Stopped Mode" to change the EEF configuration! -->
</div>
</div>
</div>
</div>
<div class="control-container col-md-6">
<div id="right-operation-mode" class="control-card-six control-card panel panel-default">
<div class="panel-heading">
Operation Mode
<i class="fas fa-info-circle" tabindex="0" data-toggle="popover" data-trigger="focus" data-placement="bottom" data-content="This selects the operation mode of the right arm."></i>
</div>
<div class="panel-body text-center">
<div class="button-area">
<button id="right_teachingModeButton" type="button" onclick="triggerService('/right/aescape/mode/activateTeachingController')" class="btn btn-primary col-md-4">
Teaching
</button>
<button id="right_executionModeButton" type="button" onclick="triggerService('/right/aescape/mode/activateExecutionController')" class="btn btn-primary col-md-4">
Massage
</button>
<button id="right_readyModeButton" type="button" onclick="triggerService('/right/aescape/mode/activateReadyController')" class="btn btn-primary col-md-4">
Ready
</button>
<button id="right_standbyModeButton" type="button" onclick="triggerService('/right/aescape/mode/activateStandbyController')" class="btn btn-primary col-md-4">
Standby
</button>
<button id="right_stoppedModeButton" type="button" onclick="triggerService('/right/aescape/mode/stopControllers')" class="btn btn-primary col-md-4">
Stopped
</button>
</div>
</div>
<div class="action-area panel-footer">
<div class="message">
</div>
</div>
</div>
</div>
<!-- <div class="panel panel-default">
<div class="panel-heading">
Robotiq
</div>
<div class="panel-body text-center">
<div class="col-md-4">
Current Robotiq Values:
<div class="row-md-3">
<h4>X: <span id="robotiqX" class="label label-default">0.0</span></h4>
</div>
<div class="row-md-3">
<h4>Y: <span id="robotiqY" class="label label-default">0.0</span></h4>
</div>
<div class="row-md-3">
<h4>Z: <span id="robotiqZ" class="label label-default">0.0</span></h4>
</div>
</div>
<div class="row-md-3">
<button id="calibrateButton" type="button" onclick="triggerService('/right/aescape/hardware/calibrateRobotiq')" class="btn btn-primary">
Calibrate Robotiq
</button>
</div>
</div>
</div> -->
</div>
<div class="panel-footer">
</div>
</div>
<button type="button" onclick="triggerService('/aescape/safety_activate')" class="safety-button danger btn">
Stop Now!
</button>
</div>
</div>
</div>
<!-- <div class="panel panel-default">
<div class="panel-heading">
Execution Recording Operations
</div>
<div class="panel-body text-center">
<button id="executionStartButton" type="button" onclick="triggerService('/startExecutionRecording')" class="btn btn-primary">
Start Recording Execution
</button>
<button id="executionRecordingStopButton" type="button" onclick="triggerService('/stopExecutionRecording')" class="btn btn-primary">
Stop Recording Execution
</button>
</div>
</div> -->

View File

@@ -0,0 +1,661 @@
///////////////////////////////////////////////////////////////////////////////////
// Publishers
///////////////////////////////////////////////////////////////////////////////////
function triggerTopic(topicName)
{
var topic = new ROSLIB.Topic({
ros : ros,
name : topicName,
messageType : 'std_msgs/Empty'
});
var msg = new ROSLIB.Message({});
topic.publish(msg);
}
////////////////////////////////////////////////////////////////
// Topics
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// Subscribers
////////////////////////////////////////////////////////////////
class ArmControls
{
constructor(namespace) {
this.namespace = namespace;
// Franka Status
this.frankaStatusTopic = new ROSLIB.Topic({
ros : ros,
name : '/'+this.namespace+'/franka_state_controller/franka_states',
messageType : 'franka_msgs/FrankaState',
throttle_rate : 500 // 2Hz
});
this.frankaStatusTopic.subscribe(this.frankaStatus.bind(this));
// Mode Status
this.modeStatusTopic = new ROSLIB.Topic({
ros : ros,
name : '/'+this.namespace+'/aescape/mode/status',
messageType : 'std_msgs/String',
throttle_rate : 500 // 2Hz
});
this.modeStatusTopic.subscribe(this.modeStatus.bind(this));
// Safety Status
this.safetyStatusTopic = new ROSLIB.Topic({
ros : ros,
name : '/'+this.namespace+'/aescape/mode/safety_status',
messageType : 'std_msgs/String',
throttle_rate : 500 // 2Hz
});
this.safetyStatusTopic.subscribe(this.safetyStatus.bind(this));
this.frankaForceObservedTopic = new ROSLIB.Topic({
ros : ros,
name : '/'+this.namespace+'/franka_state_controller/F_ext_base',
messageType : 'geometry_msgs/WrenchStamped',
throttle_rate : 500 // 2Hz
});
this.frankaForceObservedTopic.subscribe(this.frankaForce.bind(this, 'observed'));
this.frankaForceCommandedTopic = new ROSLIB.Topic({
ros : ros,
name : '/'+this.namespace+'/robot_goal',
messageType : 'aescape_control/RobotGoal',
throttle_rate : 500 // 2Hz
});
this.frankaForceCommandedTopic.subscribe(this.frankaForce.bind(this, 'commanded'));
this.lastActiveButton = {
safetyMode : null,
frankaMode : null,
operationMode : null,
};
}
// Operation Mode
modeStatus(message) {
var operationModeToButtonMap = {
"stopped" : "stoppedModeButton",
"standby" : "standbyModeButton",
"teach" : "teachingModeButton",
"execution" : "executionModeButton",
"ready" : "readyModeButton"
}
if (this.namespace == "left")
{
document.getElementById("recordingStartButton").disabled = true
document.getElementById("executionStartButton").disabled = true
}
if (message.data == "ready")
{
if (this.namespace == "left")
{
document.getElementById("recordingStartButton").disabled = false
document.getElementById("executionStartButton").disabled = false
}
}
var operationModeLastActive = this.lastActiveButton.operationMode;
if(operationModeLastActive && operationModeLastActive != message.data) {
var operationModeButton = operationModeToButtonMap[operationModeLastActive];
if (operationModeButton) {
document.getElementById(this.namespace+"_"+operationModeButton).classList.remove("active");
}
}
var operationModeButton = operationModeToButtonMap[message.data];
if (operationModeButton) {
document.getElementById(this.namespace+"_"+operationModeButton).classList.add('active');
}
this.lastActiveButton.operationMode = message.data;
}
// FrankaState
frankaStatus(message) {
var frankaModeToButtonMap = {
0 : "frankaModeOther",
1 : "frankaModeIdle",
2 : "frankaModeMove",
3 : "frankaModeGuiding",
4 : "frankaModeReflex",
5 : "frankaModeUserStopped",
6 : "frankaModeErrorRecovery"
}
var frankaModeLastActive = this.lastActiveButton.frankaMode;
if(frankaModeLastActive && frankaModeLastActive != message.robot_mode) {
var frankaButton = frankaModeToButtonMap[frankaModeLastActive];
if (frankaButton) {
document.getElementById(this.namespace+"_"+frankaButton).getElementsByTagName("input")[0].checked = false;
document.getElementById(this.namespace+"_"+frankaButton).getElementsByTagName("input")[0].disabled = true;
}
}
var frankaButton = frankaModeToButtonMap[message.robot_mode];
if (frankaButton) {
document.getElementById(this.namespace+"_"+frankaButton).getElementsByTagName("input")[0].disabled = false;
document.getElementById(this.namespace+"_"+frankaButton).getElementsByTagName("input")[0].checked = true;
}
if(message.robot_mode == 0 || message.robot_mode == 4) {
document.getElementById(this.namespace+"_"+"fixFrankaButton").classList.add("danger");
} else {
document.getElementById(this.namespace+"_"+"fixFrankaButton").classList.remove("danger");
}
//if(message.robot_mode == 1) {
// document.getElementById(this.namespace+"_"+"fixFrankaButton").classList.add("warning");
//} else {
// document.getElementById(this.namespace+"_"+"fixFrankaButton").classList.remove("warning");
//}
this.lastActiveButton.frankaMode = message.robot_mode;
}
safetyStatus(message) {
var safetyStatusToButtonMap = {
"stopped" : "safetyStopped",
"running" : "safetyRunning"
}
var safetyButtonLastActive = this.lastActiveButton.safetyMode;
if(safetyButtonLastActive && safetyButtonLastActive != message.data) {
var safetyButton = safetyStatusToButtonMap[safetyButtonLastActive];
if(safetyButton) {
document.getElementById(this.namespace+"_"+safetyButton).getElementsByTagName("input")[0].checked = false;
document.getElementById(this.namespace+"_"+safetyButton).getElementsByTagName("input")[0].disabled = true;
}
}
var safetyButton = safetyStatusToButtonMap[message.data];
if(safetyButton) {
document.getElementById(this.namespace+"_"+safetyButton).getElementsByTagName("input")[0].disabled = false;
document.getElementById(this.namespace+"_"+safetyButton).getElementsByTagName("input")[0].checked = true;
}
this.lastActiveButton.safetyMode = message.data;
}
frankaForce(forceTypeCode, message) {
if(this.namespace == 'left') {
var bindedArm = "Left";
}
if(this.namespace == 'right') {
var bindedArm = "Right";
}
if (forceTypeCode == 'observed') {
var forceType = "Observed";
}
if (forceTypeCode == 'commanded') {
var forceType = "Commanded";
}
// if(this.namespace == 'right' && forceTypeCode == 'commanded') {
// console.log("frankaForce");
// console.log(message)
// }
var force = message.wrench.force
document.getElementById("frankaForce" + bindedArm + forceType + "X").innerHTML = force.x.toFixed(1)
document.getElementById("frankaForce" + bindedArm + forceType + "Y").innerHTML = force.y.toFixed(1)
document.getElementById("frankaForce" + bindedArm + forceType + "Z").innerHTML = force.z.toFixed(1)
var totalForce = math.norm([force.x, force.y, force.z]).toFixed(1)
var totalForcePercent = totalForce/2
var doc = document.getElementById("frankaForce" + forceType + bindedArm);
doc.style.width = totalForcePercent + "%";
doc.innerHTML = totalForce + " N";
doc.setAttribute('aria-valuenow', totalForce);
}
}
var leftArmControls = new ArmControls('left');
var rightArmControls = new ArmControls('right');
var lastActiveButton = {
teachingMode : null,
executionMode : null
}
// Robotiq Data
var robotiqDataTopic = new ROSLIB.Topic({
ros : ros,
name : '/left/monitor/eef_wrench',
messageType : 'geometry_msgs/WrenchStamped',
throttle_rate : 500 // 2Hz
});
robotiqDataTopic.subscribe(function(message) {
var force = message.wrench.force
document.getElementById("robotiqX").innerHTML = force.x.toFixed(1)
document.getElementById("robotiqY").innerHTML = force.y.toFixed(1)
document.getElementById("robotiqZ").innerHTML = force.z.toFixed(1)
var totalForce = math.norm([force.x, force.y, force.z]).toFixed(1)
var totalForcePercent = totalForce/2
doc = document.getElementById("robotiqForceBar");
doc.style.width = totalForcePercent + "%";
doc.innerHTML = totalForce + " N";
doc.setAttribute('aria-valuenow', totalForce);
if ((Math.abs(force.x) > 0.5) || (Math.abs(force.y) > 0.5) || (Math.abs(force.z) > 0.5))
{
//consider adding warning buttons
} else {
//document.getElementById("calibrateButton").disabled = true;
}
});
// Recording bag
var recordingBagTopic = new ROSLIB.Topic({
ros : ros,
name : '/aescape/bags/recording_status',
messageType : 'std_msgs/String'
});
recordingBagTopic.subscribe(function(message) {
if (message.data == "stopped")
{
//document.getElementById("RecordingStatusLabel").innerHTML = 'Not Running';
}
else if (message.data == "running")
{
//document.getElementById("RecordingStatusLabel").innerHTML = 'Running!';
}
var teachingModeToButtonMap = {
"stopped" : "recordingStopButton",
"running" : "recordingStartButton"
}
var teachingModeLastActive = lastActiveButton.teachingMode;
//status changed
if(teachingModeLastActive && teachingModeLastActive != message.data) {
var teachingModeButton = teachingModeToButtonMap[teachingModeLastActive];
if (teachingModeButton) {
document.getElementById(teachingModeButton).classList.remove("active");
}
if(message.data == 'stopped') {
triggerService('/left/aescape/mode/activateReadyController');
triggerService('/right/aescape/mode/activateReadyController');
displayTaggingOptions('teach');
}
}
var teachingModeButton = teachingModeToButtonMap[message.data];
if (teachingModeButton) {
document.getElementById(teachingModeButton).classList.add("active");
}
lastActiveButton.teachingMode = message.data;
});
// Execution bag
// Use playback status instead of this
var executingBagTopic = new ROSLIB.Topic({
ros : ros,
name : '/aescape/bags/execution_status',
messageType : 'std_msgs/String'
});
executingBagTopic.subscribe(function(message) {
if (message.data == "stopped")
{
//document.getElementById("ExecutionStatusLabel").innerHTML = 'Not Running';
}
else if (message.data == "running")
{
//document.getElementById("ExecutionStatusLabel").innerHTML = 'RUNNING!';
}
var executionModeToButtonMap = {
"stopped" : "executionStopButton",
"running" : "executionStartButton"
}
var executionModeLastActive = lastActiveButton.executionMode;
if(executionModeLastActive && executionModeLastActive != message.data) {
var executionModeButton = executionModeToButtonMap[executionModeLastActive];
if (executionModeButton) {
document.getElementById(executionModeButton).classList.remove("active");
}
}
var executionModeButton = executionModeToButtonMap[message.data];
if (executionModeButton) {
document.getElementById(executionModeButton).classList.add("active");
}
lastActiveButton.executionMode = message.data;
});
// Playback status
var lastPlaybackStatus;
var lastStatusBag;
var playbackStatus = new ROSLIB.Topic({
ros : ros,
name : '/left/playback/status',
messageType : 'std_msgs/String'
});
playbackStatus.subscribe(function(message) {
message = JSON.parse(message.data);
console.log("message");
console.log(message);
status = message.status;
bagName = message.bag_file;
if (true) {
if (status === "playing") {
} else if (status === "stopped") {
triggerService('/aescape/bags/stopPlayingBag');
triggerService('/left/aescape/mode/activateReadyController');
triggerService('/right/aescape/mode/activateReadyController');
displayTaggingOptions('play');
} else if (status === "loaded") {
enableUI();
triggerService('/left/aescape/mode/activateReadyController');
triggerService('/right/aescape/mode/activateReadyController');
displayMessage(true, "Loaded the selected bag file!")
}
}
});
// Last played bag
var lastPlayedBag = new ROSLIB.Topic({
ros : ros,
name : '/aescape/bags/last_played',
messageType : 'std_msgs/String'
});
lastPlayedBag.subscribe(function(message) {
//document.getElementById("lastbagText").innerHTML = message.data
console.log("Last played bag");
console.log(message);
});
//Last recorded bag
var lastRecordedBag = new ROSLIB.Topic({
ros : ros,
name : '/aescape/bags/last_recorded',
messageType : 'std_msgs/String'
});
lastRecordedBag.subscribe(function(message) {
//document.getElementById("lastbagText").innerHTML = message.data
console.log("Last recorded bag");
console.log(message);
});
////////////////////////////////////////////////////////////////
// Services
////////////////////////////////////////////////////////////////
function triggerService(serviceName, toSend, callback) {
disableUI();
var callback = callback || $.noop;
if(!toSend) {
serviceType = 'std_srvs/demobot.Trigger'
} else {
serviceType = 'std_srvs/demobot.TriggerMessage'
}
var service = new ROSLIB.Service({
ros : ros,
name : serviceName,
serviceType : serviceType,
});
if(!toSend) {
var request = new ROSLIB.ServiceRequest({});
} else {
var toSend = JSON.stringify(toSend);
var request = new ROSLIB.ServiceRequest({message : toSend});
}
/*
var service = new ROSLIB.Service({
ros : ros,
name : serviceName,
serviceType : 'std_srvs/demobot.TriggerMessage'
});
if(toSend) {
toSend = JSON.stringify(toSend)
} else {
toSend = ""
}
*/
//var request = new ROSLIB.ServiceRequest({message : toSend});
var serviceCallTimeStamp = Date.now();
var serviceCallReturned = false;
service.callService(request, function(result) {
serviceCallReturned = true;
if(result.success == true) {
$(document).ready(function(){
$.notify({
message: "Going good! "+ serviceName
}, {
"placement" : {
from: "bottom",
align: "right"
},
type: 'success',
delay: 1000
});
});
enableUI();
return callback(null, {success : true});
} else {
$(document).ready(function(){
$.notify({
message: "Something went wrong :( " + serviceName
}, {
"placement" : {
from: "bottom",
align: "right"
},
type: 'danger',
delay: 1000
});
});
enableUI();
return callback("Something went wrong :( " + serviceName, {success : false});
}
}, function(error){
$(document).ready(function(){
serviceCallReturned = true;
$.notify({
message: "Something went wrong :( " + serviceName
}, {
"placement" : {
from: "bottom",
align: "right"
},
type: 'danger',
delay: 1000
});
});
enableUI();
return callback("Something went wrong :( " + serviceName, {success : false})
});
var responseCheckInterval = setInterval(function() {
var timeElapsedSinceServiceCall = Date.now() - serviceCallTimeStamp; // milliseconds elapsed since start
if(serviceCallReturned) {
clearInterval(responseCheckInterval);
return;
} else if (timeElapsedSinceServiceCall > 3000){
$(document).ready(function(){
$.notify({
message: "Timeout on " + serviceName
}, {
"placement" : {
from: "bottom",
align: "right"
},
type: 'danger',
delay: 1000
});
});
clearInterval(responseCheckInterval);
enableUI();
return;
}
}, 1000);
}
//document.addEventListener("keydown", invokeSafetyController);
function invokeSafetyController(event)
{
var keyID = event.keyCode;
//8 == backspace, 46 == delete
if(keyID == 46) {
triggerService('/aescape/safety_activate');
}
}
function setEEFConfig(arm, config) {
var operationModeSelector = '#' + arm + '-operation-mode';
document.querySelectorAll(operationModeSelector + ' button').forEach(function(element){
element.classList.add('disabled')
})
var serviceMap = {
teach : 'setTrainingEEF',
play : 'setExecutionEEF'
}
var service = '/' + arm + '/aescape/hardware/' + serviceMap[config]
triggerService(service, false, function(error, result){
document.querySelectorAll(operationModeSelector + ' button').forEach(function(element){
element.classList.remove('disabled')
})
})
}
function startTeachRecoding() {
async.waterfall([
function(callback) {
triggerService('/left/aescape/hardware/calibrateRobotiq', false, function(err, res){
//callback(err, res);
callback(null, null);
});
},
function(response, callback) {
triggerService('/left/aescape/mode/activateTeachingController', false, callback);
},
function(response, callback) {
triggerService('/aescape/bags/startTeachRecording', false, callback)
}
], function (err, result) {
console.log("starting teach recoding");
});
}
function stopTeachRecording() {
async.waterfall([
function(callback) {
triggerService('/aescape/bags/stopTeachRecording', false, callback);
},
// function(response, callback) {
// triggerService('/left/aescape/mode/activateReadyController', false, callback);
// },
function(response, callback) {
//displayTaggingOptions('teach');
callback();
}
], function (err, result) {
console.log(err);
});
}
function playLoadedRecording() {
async.waterfall([
function(callback) {
triggerService('/left/aescape/mode/activateExecutionController', false, callback);
},
function(response, callback) {
var singleArmMode = $('#armMode').val();
if (singleArmMode == "1") {
singleArmMode = true;
callback(null, null);
} else {
singleArmMode = false;
triggerService('/right/aescape/mode/activateExecutionController', false, callback);
}
},
function(response, callback) {
triggerTopic('/left/run_trajectory', false, callback)
}
], function (err, result) {
});
}
function stopPlayingRecording() {
async.waterfall([
function(callback) {
triggerService('/aescape/bags/stopPlayingBag', false, callback);
},
function(response, callback) {
triggerService('/left/aescape/mode/activateReadyController', false, callback);
},
function(response, callback) {
triggerService('/right/aescape/mode/activateReadyController', false, callback);
},
function(response, callback) {
//displayTaggingOptions('play');
callback();
}
], function (err, result) {
// result now equals 'done'
});
}

View File

@@ -0,0 +1,373 @@
var bagList = Array();
function getBagList(callback)
{
var service = new ROSLIB.Service({
ros : ros,
name : '/aescape/bags/getBagList',
serviceType : 'demobot/TriggerList'
});
toSend = {
message : String(Math.random())
}
var request = new ROSLIB.ServiceRequest(toSend);
service.callService(request, function(result) {
callback(JSON.parse(result.message));
});
}
function getBagCategoryList(callback)
{
var service = new ROSLIB.Service({
ros : ros,
name : '/aescape/bags/getCategoryList',
serviceType : 'demobot/TriggerList'
});
var request = new ROSLIB.ServiceRequest({});
service.callService(request, function(result) {
callback(JSON.parse(result.message));
});
}
function getBagTagList(callback)
{
var service = new ROSLIB.Service({
ros : ros,
name : '/aescape/bags/getTagList',
serviceType : 'demobot/TriggerList'
});
var request = new ROSLIB.ServiceRequest({});
service.callService(request, function(result) {
callback(JSON.parse(result.message));
});
}
setTimeout(function(){
document.querySelector('.hand-panel-right .status-bar').style.height = document.querySelector('.hand-panel-left .status-bar').offsetHeight + 20 + "px";
$(function () {
$('[data-toggle="popover"]').popover()
})
}, 100);
function displayTaggingOptions(mode) {
hideAllSlidingControllers();
var modeTag = '#' + mode + 'Tags';
var fileNameSelector = '#' + mode + 'BagFileName';
var categorySelector = '#' + mode + 'BagCategory';
var tagSelector = '#' + mode + 'BagTags';
//Subscribe to topics from the backend which indicate recording or playback is complete
document.querySelector(modeTag).classList.add('open');
//Putting this in a timeout to wait for the animation to finish completing
setTimeout(function(){
document.querySelector(modeTag).style.overflow = "visible";
}, 600)
var $fileNameSelect = $(fileNameSelector).selectize({
valueField: 'name',
labelField: 'name',
searchField: ['name'],
options: [],
create: true,
placeholder : "Enter a name for the bag"
});
var fileNameSelectize = $fileNameSelect[0].selectize;
fileNameSelectize.clearOptions()
// /aescape/bags/getBagList
getBagList(function(results){
fileNameSelectize.addOption(results)
if(results[0]) {
fileNameSelectize.setValue(results[0]._id);
}
})
var $categoryNameSelect = $(categorySelector).selectize({
valueField: 'name',
labelField: 'name',
searchField: ['name'],
options: [],
create: true,
placeholder : "Enter or select a category for the bag"
});
var categoryNameSelectize = $categoryNameSelect[0].selectize;
categoryNameSelectize.clearOptions()
getBagCategoryList(function(results){
categoryNameSelectize.addOption(results.map(function(element){
return {name : element}
}));
})
var $tagSelect = $(tagSelector).selectize({
valueField: 'name',
labelField: 'name',
searchField: ['name'],
maxItems: 20,
options: [],
create: true,
placeholder : "Enter or select tags for the bag"
});
var tagSelectize = $tagSelect[0].selectize;
tagSelectize.clearOptions()
getBagTagList(function(results){
tagSelectize.addOption(results.map(function(element){
return {name : element}
}));
})
}
function hideTaggingOptions(mode, updateValues=false) {
if(!mode) {
return;
}
var modeTag = '#' + mode + 'Tags';
var bagLabelSelector = '#' + mode + 'BagFileName';
var categorySelector = '#' + mode + 'BagCategory';
var tagSelector = '#' + mode + 'BagTags';
var errorSelector = '#' + mode + 'TagError';
if(updateValues) {
var bagLabel = $(bagLabelSelector).val();
var category = $(categorySelector).val();
var tags = $(tagSelector).val() || [];
getBagList(function(results){
if(!(results && results[0] && results[0]._id)) {
displayMessage(false, "Could not retrieve the last recorded bag :(");
return;
}
bag_id = results[0]._id;
updateBagMetadata(mode, bag_id, bagLabel, category, tags, function(updateError) {
if(updateError) {
displayMessage(flase, updateError);
} else {
displayMessage("Bag data saved successfully!");
//clear selectize
$(bagLabelSelector).selectize()[0].selectize.destroy();
$(categorySelector).selectize()[0].selectize.destroy();
$(tagSelector).selectize()[0].selectize.destroy();
}
});
})
}
//TO DO: Wait for the response from the backend before setting the display to none
document.querySelector(modeTag).style.overflow = "hidden";
document.querySelector(modeTag).classList.remove('open');
}
function updateBagMetadata(mode, bag_id, bag_label, category, tags, callback) {
if(!mode) {
return callback();
}
if(!bag_id) {
return callback();
}
var toSend = {
mode : mode,
bag_id : bag_id,
bag_label : bag_label,
category : category,
tags : tags
}
triggerService('/aescape/bags/updateBagMeta', toSend, function(error, result) {
if(!result) {
return callback("Something went wrong in the backend while updating.");
}
else {
return callback();
}
})
}
function displayLoadingOptions() {
hideAllSlidingControllers();
selector = "#loadBags";
document.querySelector(selector).classList.add('open');
//Putting this in a timeout to wait for the animation to finish completing
setTimeout(function(){
document.querySelector(selector).style.overflow = "visible";
}, 420) //This is not a Hitchhiker's reference. This is not a 420 reference. This value has been computed to match the speed of the larger drop down.
var $select = $('#loadBagList').selectize({
valueField: '_id',
labelField: 'name',
searchField: ['name', 'category', 'tags'],
options: [],
create: false,
placeholder : "Select bag to play",
render : {
item: function(item, escape) {
name = item.name;
category = item.category || 'None';
return '<div class="bag-select-element">' +
'<div class="bag-select-element">' +
'<span class="filename">' + escape(name) + '</span>' +
'<span class="category">' + ' (' + escape(category) + ') ' + '</span>' +
'</div>' +
'</div>';
},
option: function(item, escape) {
name = item.name;
category = item.category || 'None';
return '<div class="bag-select-element bag-option">' +
'<div class="primary">' +
'<div class="filename">' + escape(name) + '</div>' +
'<div class="category">' + escape(category) + '</div>' +
'</div>' +
'<div class="secondary">' +
'<div class="tags">' +
item.tags.map(function(tag) {
return '<span class="tag label label-info">' + escape(tag) + '</span>'
}).join(' ') +
'</div>' +
'<div class="timestamp">' + escape(item.created_at) + '</div>' +
'</div>' +
'</div>';
}
}
});
$('#loadBagList').next().find('div.selectize-input > input').prop('disabled', 'disabled');
getBagList(function(results){
if(!results) {
displayMessage(false, "Could not fetch a list of recordings :(")
}
var selectize = $select[0].selectize;
selectize.clearOptions();
//results = [{filename : 'testfile', category: 'testcategory', tags : ['testtag1', 'testtag2', 'testtag3']}, {filename : 'testfile2', category: 'testcategory2', tags : ['testtag21', 'testtag22', 'testtag23']}]
console.log(results);
selectize.addOption(results);
if(results[0]) {
selectize.setValue(results[0].filename);
}
})
var $armModeSelect = $('#armMode').selectize({
valueField: 'value',
labelField: 'name',
options: [],
create: false,
placeholder : "Select dual or single arm mode"
});
var armSelectize = $armModeSelect[0].selectize;
armSelectize.clearOptions()
armSelectize.addOption([{name: 'Dual-arm', value: false}, {name: 'Single-arm', value: true}]);
armSelectize.setValue(false);
$('#armMode').next().find('div.selectize-input > input').prop('disabled', 'disabled');
}
function hideLoadingOptions(loadBag) {
var singleArmMode = $('#armMode').val();
if (singleArmMode == "1") {
singleArmMode = true
} else {
singleArmMode = false
}
if(loadBag) {
var selectedBagId = $('#loadBagList').val();
disableUI();
loadSelectedBagFile(selectedBagId, singleArmMode, function(updateError){
// if(updateError) {
// displayMessage(false, "Something went wrong in the backend while fetching the bag files :(")
// } else {
// displayMessage(true, "Loaded the selected bag file!")
// }
})
}
var selector = '#loadBags';
document.querySelector(selector).style.overflow = "hidden";
document.querySelector(selector).classList.remove('open');
}
function loadSelectedBagFile(selectedBagId, singleArmMode, callback) {
var toSend = {
bag_id : selectedBagId,
single_arm : singleArmMode
}
triggerService('/aescape/bags/startPlayingRecording', toSend, function(error, result) {
if(!result) {
return callback("Something went wrong in the backend while updating.");
}
else {
return callback();
}
})
/*
var toSendString = JSON.stringify(toSend);
var topic = new ROSLIB.Topic({
ros : ros,
name : "/left/playback/control",
messageType : 'std_msgs/String'
});
var msg = new ROSLIB.Message({data:toSendString});
topic.publish(msg);
*/
}
function hideAllSlidingControllers () {
document.querySelectorAll('.slider-options').forEach(function(element){
element.style.overflow = "hidden";
element.classList.remove('open');
})
}
function displayMessage (success, message) {
if(success) {
type = 'success';
} else {
type = 'danger';
}
$(document).ready(function(){
$.notify({
message: message
}, {
"placement" : {
from: "bottom",
align: "right"
},
type: type,
delay: 1000
});
});
}

View File

@@ -0,0 +1,104 @@
///////////////////////////////////////////////////////////////////////////////////
// Publishers
///////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// Topics
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// Subscribers
////////////////////////////////////////////////////////////////
// Operation Mode
var modeStatus = new ROSLIB.Topic({
ros : ros,
name : '/aescape/mode/status',
messageType : 'std_msgs/String'
});
modeStatus.subscribe(function(message) {
document.getElementById("stoppedModeButton").className = "btn btn-secondary"
document.getElementById("standbyModeButton").className = "btn btn-primary"
document.getElementById("teachingModeButton").className = "btn btn-primary"
document.getElementById("executionModeButton").className = "btn btn-primary"
if (message.data === "stopped") {
document.getElementById("stoppedModeButton").className = "btn btn-warning"
} else if (message.data === "standby")
{
document.getElementById("standbyModeButton").className = "btn btn-primary btn-success"
} else if (message.data === "teach")
{
document.getElementById("teachingModeButton").className = "btn btn-primary btn-success"
} else if (message.data === "execution")
{
document.getElementById("executionModeButton").className = "btn btn-primary btn-success"
}
});
// Playing Bag
var bagPlayingTopic = new ROSLIB.Topic({
ros : ros,
name : '/aescape/bags/playing',
messageType : 'std_msgs/String'
});
bagPlayingTopic.subscribe(function(message) {
document.getElementById("bagPlayingText").innerHTML = message.data
});
////////////////////////////////////////////////////////////////
// Services
////////////////////////////////////////////////////////////////
function triggerService(serviceName)
{
var service = new ROSLIB.Service({
ros : ros,
name : serviceName,
serviceType : 'std_srvs/Trigger'
});
var request = new ROSLIB.ServiceRequest({});
service.callService(request, function(result) {
console.log('Result for service call on '
+ serviceName
+ ': '
+ result.sum);
});
}
function triggerMessageService(serviceName, textInput)
{
var text = document.getElementById(textInput).value
var service = new ROSLIB.Service({
ros : ros,
name : serviceName,
serviceType : 'demobot.TriggerMessage'
});
var request = new ROSLIB.ServiceRequest({
message : text
});
service.callService(request, function(result) {
console.log('Result for service call on '
+ serviceName
+ ': '
+ result.sum);
});
}

View File

@@ -0,0 +1,122 @@
<!-- <div class="panel panel-default">
<div class="panel-heading">
Select Operation Mode
</div>
<div class="panel-body text-center">
<button id="teachingModeButton" type="button" onclick="triggerService('/aescape/mode/activateTeachingController')" class="btn btn-primary">
Teaching Mode
</button>
<button id="executionModeButton" type="button" onclick="triggerService('/aescape/mode/activateExecutionController')" class="btn btn-primary">
Massage Mode
</button>
<button id="standbyModeButton" type="button" onclick="triggerService('/aescape/mode/activateStandbyController')" class="btn btn-primary">
Standby Mode
</button>
<button id="stoppedModeButton" type="button" onclick="triggerService('/aescape/mode/stopControllers')" class="btn btn-primary">
Stopped Mode
</button>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
Hardware Commands
</div>
<div class="panel-body text-center">
<button id="fixFrankaButton" type="button" onclick="triggerService('/aescape/hardware/resetFrankaError')" class="btn btn-primary">
Fix Franka Errors
</button>
<button id="calibrateButton" type="button" onclick="triggerService('/aescape/hardware/calibrateRobotiq')" class="btn btn-primary">
Calibrate Robotiq
</button>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
Teaching Mode Operations
</div>
<div class="panel-body text-center">
<button id="recordingStartButton" type="button" onclick="triggerService('/aescape/bags/startTeachRecording')" class="btn btn-primary">
Start Teach Recording
</button>
<button id="recordingStopButton" type="button" onclick="triggerService('/aescape/bags/stopTeachRecording')" class="btn btn-primary">
Stop Teach Recording
</button>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
Execution Mode Operations
</div>
<div class="panel-body text-center">
Last Bag Playing:
<span id="bagPlayingText">
None
</span>
<div>
<button id="executionStartButton" type="button" onclick="triggerService('/aescape/bags/startPlayingLastRecording')" class="btn btn-primary">
Play Last Recording
</button>
<button id="executionStopButton" type="button" onclick="triggerService('/aescape/bags/stopPlayingBag')" class="btn btn-primary">
Stop Playing Recording
</button>
<div class="row">
<div class="col-md-3">
Bagfile name must not start with "/"
<div class="input-group">
<input type="text" id="bagNameText" class="form-control" placeholder="bag_filename">
<span class="input-group-btn">
<button class="btn btn-primary" type="button" onclick="triggerMessageService('/startPlayingRecording', 'bagNameText')">
<span>
Start Playing Bag
</span>
</button>
</span>
</div>
</div>
</div>
</div>
</div> -->
<script type="text/javascript" src="vision/js/ros_scripts.js"></script>
<script type="text/javascript" src="vision/js/update_guis.js"></script>
<div class="panel panel-default">
<div class="panel-heading">
Camera Views
</div>
<div class="panel-body">
Webcam
<div class="row-lg-4">
<img height="350" alt="No Camera Image" id="imageStream" src="http://titan.aescape.co:8080/stream?topic=/webcam/image_raw&type=ros_compressed"></img>
</div>
Realsense Red
<div class="row-lg-4">
<img height="350" alt="No Camera Image" id="imageStream" src="http://titan.aescape.co:8080/stream?topic=/real_red/color/image_raw&type=ros_compressed"></img>
</div>
Realsense Green
<div class="row-lg-4">
<img height="350" alt="No Camera Image" id="imageStream" src="http://titan.aescape.co:8080/stream?topic=/real_green/color/image_raw&type=ros_compressed"></img>
</div>
Thermal
<div class="row-lg-4">
<img height="350" alt="No Camera Image" id="imageStream" src="http://titan.aescape.co:8080/stream?topic=/thermal/image_raw&type=ros_compressed"></img>
</div>
</div>
</div>
<!-- <div class="panel panel-default">
<div class="panel-heading">
Execution Recording Operations
</div>
<div class="panel-body text-center">
<button id="executionStartButton" type="button" onclick="triggerService('/startExecutionRecording')" class="btn btn-primary">
Start Recording Execution
</button>
<button id="executionRecordingStopButton" type="button" onclick="triggerService('/stopExecutionRecording')" class="btn btn-primary">
Stop Recording Execution
</button>
</div>
</div> -->