Merge branch 'release/0.0.1'
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 2.8.3)
|
||||
project(rosbridge_gui)
|
||||
project(aescape_lab_ui)
|
||||
|
||||
## Find catkin macros and libraries
|
||||
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
|
||||
@@ -82,7 +82,7 @@ find_package(catkin REQUIRED COMPONENTS
|
||||
## DEPENDS: system dependencies of this project that dependent projects also need
|
||||
catkin_package(
|
||||
# INCLUDE_DIRS include
|
||||
# LIBRARIES rosbridge_gui
|
||||
# LIBRARIES aescape_lab_ui
|
||||
# CATKIN_DEPENDS roscpp rospy std_msgs
|
||||
# DEPENDS system_lib
|
||||
)
|
||||
@@ -99,8 +99,8 @@ include_directories(
|
||||
)
|
||||
|
||||
## Declare a cpp library
|
||||
# add_library(rosbridge_gui
|
||||
# src/${PROJECT_NAME}/rosbridge_gui.cpp
|
||||
# add_library(aescape_lab_ui
|
||||
# src/${PROJECT_NAME}/aescape_lab_ui.cpp
|
||||
# )
|
||||
|
||||
## Declare a cpp executable
|
||||
@@ -108,7 +108,7 @@ include_directories(
|
||||
|
||||
## Add cmake target dependencies of the executable/library
|
||||
## as an example, message headers may need to be generated before nodes
|
||||
# add_dependencies(rosbridge_gui_node rosbridge_gui_generate_messages_cpp)
|
||||
# add_dependencies(aescape_lab_ui_node aescape_lab_ui_generate_messages_cpp)
|
||||
|
||||
## Specify libraries to link a library or executable target against
|
||||
|
||||
@@ -127,7 +127,7 @@ include_directories(
|
||||
# )
|
||||
|
||||
## Mark executables and/or libraries for installation
|
||||
# install(TARGETS rosbridge_gui rosbridge_gui_node
|
||||
# install(TARGETS aescape_lab_ui aescape_lab_ui_node
|
||||
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
@@ -152,7 +152,7 @@ include_directories(
|
||||
#############
|
||||
|
||||
## Add gtest based cpp test target and link libraries
|
||||
# catkin_add_gtest(${PROJECT_NAME}-test test/test_rosbridge_gui.cpp)
|
||||
# catkin_add_gtest(${PROJECT_NAME}-test test/test_aescape_lab_ui.cpp)
|
||||
# if(TARGET ${PROJECT_NAME}-test)
|
||||
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
|
||||
# endif()
|
||||
|
||||
64
README.md
64
README.md
@@ -1,51 +1,19 @@
|
||||
# ROSBRIDGE GUI
|
||||
# Aescape Lab UI
|
||||
|
||||
The purpose of this project is an example of how to write a web page that can be accessed by any device on the same network as the host computer by accessing the IP of that host computer.
|
||||
## To install
|
||||
```
|
||||
sudo apt install npm -y
|
||||
sudo npm install http-server -g
|
||||
sudo ln -s /usr/bin/nodejs /usr/bin/node
|
||||
```
|
||||
|
||||
The best way to contribute to this project is to make a new brach from the master branch called the name of the robot that it is used for. This will also alow maximum colaberation between labs. This can be accomplished by going to the tabs Commits->Branches then select "New Branch"
|
||||
|
||||
### Quick Start Guide
|
||||
|
||||
If you are connecting to a remote computer that is running the roscore, you need to run the following lines in the terminal:
|
||||
|
||||
sudo route add 192.168.2.1 gw <Host computer IP>
|
||||
export ROS_MASTER_URI=http://<Host computer IP>:11311
|
||||
export ROS_IP=<your IP>
|
||||
|
||||
Make sure you have the web_video_server installed:
|
||||
|
||||
sudo apt-get install ros-indigo-web-video-server
|
||||
|
||||
Make sure you have ROSBridge installed:
|
||||
|
||||
sudo apt-get install ros-indigo-rosbridge-suite
|
||||
|
||||
Then run the bash file in the working directory by running the following in the terminal.
|
||||
|
||||
. launch.bash
|
||||
|
||||
#### Just display the webpage
|
||||
|
||||
If you just want to test the webpage, navigate to the working directory in the terminal and type
|
||||
|
||||
python -m SimpleHTTPServer
|
||||
|
||||
Then open http://localhost:8000/. or yourIPAddress:8000
|
||||
|
||||
# Making Changes
|
||||
|
||||
Feel free to clone this project, make a new branch and use it as a base for your own GUI.
|
||||
|
||||
You can easily customise the "Data Display" pannel by changing the HTML "data\_dsisplay\data\_display.html" file.
|
||||
|
||||
All ROS related Javascript should go in the "data\_display/js/ros\_scripts.js" file.
|
||||
All functions that are used to update the GUI should go in the "data\_display/js/update_guis.js" file.
|
||||
|
||||
DO NOT MAKE CHANGES OUTISDE OF THIS DIECTORY AS IT WILL CAUSE MERG PROBLEMS.
|
||||
|
||||
By using ROSBridge, this GUI will attempt to display relevant information over the web for any device.
|
||||
|
||||
# Screen Shots
|
||||
|
||||
Screen shots are in the root working directory
|
||||
## To run
|
||||
Set your master to be what you want - default is `phoebe`.
|
||||
Then run
|
||||
```
|
||||
roslaunch aescape_lab_ui lab_ui.launch
|
||||
```
|
||||
|
||||
## To access
|
||||
Use Hamachi network:
|
||||
http://titan.aescape.co:8000
|
||||
Binary file not shown.
Binary file not shown.
@@ -7,7 +7,32 @@ ros.recording = false;
|
||||
ros.connected = false;
|
||||
|
||||
// ros.connectionName = 'ws://192.168.1.105:9090';
|
||||
ros.connectionName = 'ws://localhost:9090';
|
||||
|
||||
function getQueryVariable(variable)
|
||||
{
|
||||
var query = window.location.search.substring(1);
|
||||
var vars = query.split("&");
|
||||
for (var i=0;i<vars.length;i++) {
|
||||
var pair = vars[i].split("=");
|
||||
if(pair[0] == variable){
|
||||
return pair[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var master = "localhost"
|
||||
master = getQueryVariable("master")
|
||||
if(master == null)
|
||||
{
|
||||
master = window.location.hostname
|
||||
//"localhost"
|
||||
}
|
||||
console.log('Master = ' + master);
|
||||
|
||||
ros.connectionName = 'ws://' + master + ':9090';
|
||||
// ros.connectionName = 'ws://localhost:9090';
|
||||
// ros.connectionName = 'ws://titan.aescape.co:9090';
|
||||
console.log('ros.connectionName = ' + ros.connectionName);
|
||||
|
||||
// If there is an error on the backend, an 'error' emit will be emitted.
|
||||
ros.on('error', function(error) {
|
||||
@@ -19,7 +44,7 @@ ros.on('error', function(error) {
|
||||
document.getElementById("ROSNodes").innerHTML = "No Nodes Detected";
|
||||
|
||||
rosbridgeconnection_badge
|
||||
console.log(error);192
|
||||
console.log(error);
|
||||
});
|
||||
// Find out exactly when we made a connection.
|
||||
ros.on('connection', function() {
|
||||
@@ -29,7 +54,7 @@ ros.on('connection', function() {
|
||||
document.getElementById("ConnectionIPInput").value = ros.connectionName;
|
||||
document.getElementById("ConnectionIPLabel").innerHTML = 'Connection made at:';
|
||||
document.getElementById("rosbridgeconnection_badge").innerHTML = 'Connected';
|
||||
document.getElementById("ConnectionButton").className = "btn btn-success"
|
||||
document.getElementById("ConnectionButton").className = "btn btn-success";
|
||||
|
||||
ros.nodes = Array();
|
||||
ros.topics = Array();
|
||||
@@ -47,7 +72,7 @@ ros.on('close', function() {
|
||||
ros.topics = Array();
|
||||
});
|
||||
// Create a connection to the rosbridge WebSocket server.
|
||||
ros.connect(ros.connectionName);
|
||||
//ros.connect(ros.connectionName);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -115,65 +140,10 @@ bagNotifier.subscribe(function(message) {
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ros.buildTopicList = function(fresh_topics)
|
||||
{
|
||||
|
||||
// console.log(topics)
|
||||
// fresh_topics = fresh_topics.sort();
|
||||
// First check that all our current topics are in the list of fresh_topics
|
||||
for( var topic = 0; topic < ros.topics.length; topic ++)
|
||||
{
|
||||
|
||||
if (fresh_topics.indexOf(ros.topics[topic].name) > -1)
|
||||
{
|
||||
// We know that we have already found that topic so we don't need to remove it
|
||||
}
|
||||
else
|
||||
{
|
||||
// That topic is no longer being published so we need ro remove it
|
||||
ros.topics.splice(topic,1);
|
||||
}
|
||||
}
|
||||
|
||||
for (var topic =0; topic < fresh_topics.length; topic ++ )
|
||||
{
|
||||
if (ros.topics.indexOfTopic(fresh_topics[topic]) > -1)
|
||||
{
|
||||
// We know that we have already found that topic so we don't need to re-add it
|
||||
}
|
||||
else
|
||||
{
|
||||
// We do not have that topic so we need to add it
|
||||
// create the new topic
|
||||
var new_topic = new Topic(fresh_topics[topic]);
|
||||
// make sure to put in in the list in the order
|
||||
ros.topics.push(new_topic);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ros.topics.sort(function(a, b) {
|
||||
if ( a.name < b.name )
|
||||
return -1;
|
||||
if ( a.name > b.name )
|
||||
return 1;
|
||||
return 0;
|
||||
})
|
||||
|
||||
};
|
||||
|
||||
|
||||
ros.getTopicsList = function()
|
||||
{
|
||||
// var topicList = [];
|
||||
return ros.topics;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// attept to connect to the ros master from the IP given orgrab it from the form
|
||||
ros.attemptConnection = function(ipAddress)
|
||||
{
|
||||
ros.close();
|
||||
if( typeof ipAddress !== "undefined")
|
||||
{
|
||||
ros.connectionName = ipAddress;
|
||||
@@ -184,6 +154,7 @@ ros.attemptConnection = function(ipAddress)
|
||||
}
|
||||
console.log('Connection = ' + ros.connectionName);
|
||||
ros.connect(ros.connectionName);
|
||||
getMasterName();
|
||||
}
|
||||
|
||||
function toggleRecording()
|
||||
@@ -210,3 +181,22 @@ function toggleRecording()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getMasterName()
|
||||
{
|
||||
var service = new ROSLIB.Service({
|
||||
ros : ros,
|
||||
name : '/rosapi/service_host',
|
||||
serviceType : 'rosapi/ServiceHost'
|
||||
});
|
||||
|
||||
var request = new ROSLIB.ServiceRequest({
|
||||
service: '/rosout/get_loggers' // Only the master hosts this service.
|
||||
});
|
||||
|
||||
service.callService(request, function(result) {
|
||||
console.log('Master Name = ' + result.host);
|
||||
document.getElementById("MasterName").innerHTML = result.host;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,99 +1,27 @@
|
||||
|
||||
|
||||
$("#myImage").click ( function (evt) {
|
||||
|
||||
var jThis = $(this);
|
||||
var offsetFromParent = jThis.position ();
|
||||
var topThickness = (jThis.outerHeight(true) - jThis.height() ) / 2;
|
||||
var leftThickness = (jThis.outerWidth (true) - jThis.width () ) / 2;
|
||||
|
||||
//--- (x,y) coordinates of the mouse click relative to the image.
|
||||
var x = evt.pageX - offsetFromParent.left - leftThickness;
|
||||
var y = evt.pageY - offsetFromParent.top - topThickness;
|
||||
|
||||
ReportDims ();
|
||||
$('#rez').append ('<p>User clicked at: ' + x + ', ' + y + ' (x,y).</p>')
|
||||
} );
|
||||
|
||||
|
||||
function ReportDims () {
|
||||
w = $("#myImage").width ();
|
||||
h = $("#myImage").height ();
|
||||
$('#rez').text ('The image is ' + w + ' by ' + h + ' (w by h).');
|
||||
}
|
||||
|
||||
ReportDims ();
|
||||
|
||||
function updateVoltage(voltage)
|
||||
{
|
||||
|
||||
var voltage_min = 9.5;
|
||||
var voltage_max = 12.5;
|
||||
var voltage_range = voltage_max - voltage_min;
|
||||
|
||||
var voltage_percentage = (voltage - voltage_min) / voltage_range * 100;
|
||||
|
||||
var voltage_string = "";
|
||||
voltage_string = voltage_string.concat(voltage_percentage);
|
||||
voltage_string = voltage_string.substring(0,4);
|
||||
voltage_string = voltage_string.concat('%');
|
||||
|
||||
document.getElementById("VoltageDisplay").style.width = voltage_string;
|
||||
document.getElementById("VoltageDisplay").innerHTML = voltage_string;
|
||||
|
||||
if (voltage_percentage < 50 && voltage_percentage > 25 ) {
|
||||
document.getElementById("VoltageDisplay").className = "progress-bar progress-bar-warning"
|
||||
}
|
||||
else if ( voltage_percentage <= 25)
|
||||
{
|
||||
document.getElementById("VoltageDisplay").className = "progress-bar progress-bar-danger"
|
||||
var sound = document.getElementById("audio");
|
||||
sound.play()
|
||||
console.log("Pay Sound")
|
||||
}
|
||||
else
|
||||
{
|
||||
document.getElementById("VoltageDisplay").className = "progress-bar progress-bar-success"
|
||||
}
|
||||
};
|
||||
|
||||
function updateTopicsGUI()
|
||||
{
|
||||
|
||||
ros.getTopics(ros.buildTopicList);
|
||||
ros.getTopics(function(result)
|
||||
{
|
||||
ros.topics = result;
|
||||
});
|
||||
|
||||
var topics = ros.getTopicsList();
|
||||
var topics = ros.topics;
|
||||
|
||||
if(topics != null){
|
||||
var innerHTML = "";
|
||||
for (var i = 0; i < topics.length; i++ )
|
||||
{
|
||||
innerHTML = innerHTML.concat(generateTopicCheckbox(topics[i]));
|
||||
innerHTML = innerHTML.concat(topics[i]);
|
||||
innerHTML = innerHTML.concat("<br>");
|
||||
}
|
||||
document.getElementById("ROSTopics").innerHTML = innerHTML;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function generateTopicCheckbox(topic)
|
||||
{
|
||||
var str = "<div class=\"checkbox\">";
|
||||
var checked_str = "unchecked";
|
||||
if (topic.bag == true)
|
||||
{
|
||||
checked_str = "checked"
|
||||
}
|
||||
str =str.concat("<label><input type=\"checkbox\" onclick=\"toggleToBag(\'"+ topic.name + "\')\" id=\"" + topic.name + "_checkbox\" "+ checked_str +">");
|
||||
str = str.concat(topic.name);
|
||||
str = str.concat("</label></div>");
|
||||
return str;
|
||||
};
|
||||
|
||||
function toggleToBag(topic_name)
|
||||
{
|
||||
// if($.inArray(topic_name, ros.topics))
|
||||
ros.topics[ros.topics.indexOfTopic(topic_name)].bag = !ros.topics[ros.topics.indexOfTopic(topic_name)].bag ;
|
||||
}
|
||||
|
||||
function updateNodesGUI()
|
||||
{
|
||||
@@ -113,19 +41,18 @@ function updateNodesGUI()
|
||||
{
|
||||
innerHTML = innerHTML.concat(nodes[i]);
|
||||
innerHTML = innerHTML.concat("<br>");
|
||||
|
||||
}
|
||||
document.getElementById("ROSNodes").innerHTML = innerHTML;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
window.setInterval(function(){
|
||||
// window.setInterval(function(){
|
||||
|
||||
updateTopicsGUI();
|
||||
updateNodesGUI();
|
||||
// updateTopicsGUI();
|
||||
// updateNodesGUI();
|
||||
|
||||
}, 500);
|
||||
// }, 5000);
|
||||
|
||||
function validateForm()
|
||||
{
|
||||
|
||||
186
coordinator/coordinator.html
Normal file
186
coordinator/coordinator.html
Normal file
@@ -0,0 +1,186 @@
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Select Operation Mode
|
||||
</div>
|
||||
<div class="panel-body text-center">
|
||||
<div class="col-md-6">
|
||||
<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="readyModeButton" type="button" onclick="triggerService('/aescape/mode/activateReadyController')" class="btn btn-primary">
|
||||
Ready 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 class="col-md-6">
|
||||
Safety Monitor Status:
|
||||
<div class="row-md-3">
|
||||
<h4><span id="safetyRunning" class="label label-default">Running</span></h4>
|
||||
</div>
|
||||
<div class="row-md-3">
|
||||
<h4><span id="safetyStopped" class="label label-default">Stopped</span></h4>
|
||||
</div>
|
||||
<div class="row-md-3">
|
||||
<button type="button" onclick="triggerService('/aescape/mode/activateSafetyController')" class="btn btn-sm btn-default">
|
||||
Activate Safety Monitor
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Franka Arm Status
|
||||
</div>
|
||||
<div class="panel-body text-center">
|
||||
<div class="col-md-4">
|
||||
Current Robot Status:
|
||||
<!-- <div class="col-md-3" id="FrankaStatus">
|
||||
N/A
|
||||
</div> -->
|
||||
<div class="row-md-3">
|
||||
<h4><span id="frankaModeOther" class="label label-default">Other</span></h4>
|
||||
</div>
|
||||
<div class="row-md-3">
|
||||
<h4><span id="frankaModeIdle" class="label label-default">Idle</span></h4>
|
||||
</div>
|
||||
<div class="row-md-3">
|
||||
<h4><span id="frankaModeMove" class="label label-default">Move</span></h4>
|
||||
</div>
|
||||
<div class="row-md-3">
|
||||
<h4><span id="frankaModeGuiding" class="label label-default">Guiding</span></h4>
|
||||
</div>
|
||||
<div class="row-md-3">
|
||||
<h4><span id="frankaModeReflex" class="label label-default">Reflex</span></h4>
|
||||
</div>
|
||||
<div class="row-md-3">
|
||||
<h4><span id="frankaModeUserStopped" class="label label-default">User Stopped</span></h4>
|
||||
</div>
|
||||
<div class="row-md-3">
|
||||
<h4><span id="frankaModeErrorRecovery" class="label label-default">Automatic Error Recovery</span></h4>
|
||||
</div>
|
||||
</div>
|
||||
<button id="fixFrankaButton" type="button" onclick="triggerService('/aescape/hardware/resetFrankaError')" class="btn btn-primary">
|
||||
Fix Franka Errors
|
||||
</button>
|
||||
</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('/aescape/hardware/calibrateRobotiq')" class="btn btn-primary">
|
||||
Calibrate Robotiq
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Teaching Mode Operations
|
||||
</div>
|
||||
<div class="panel-body text-center">
|
||||
<span class="row">
|
||||
<label id="RecordingStatusLabel" class="label-warning">
|
||||
Bag manager not connected!
|
||||
</label>
|
||||
</span>
|
||||
<button type="button" onclick="triggerService('/aescape/mode/activateReadyController')" class="btn btn-default">
|
||||
Activate Ready Mode
|
||||
</button>
|
||||
<button id="recordingStartButton" type="button" onclick="triggerService('/aescape/hardware/calibrateRobotiq'); triggerService('/aescape/mode/activateTeachingController'); triggerService('/aescape/bags/startTeachRecording')" class="btn btn-primary">
|
||||
Start Teach Recording
|
||||
</button>
|
||||
<button id="recordingStopButton" type="button" onclick="triggerService('/aescape/bags/stopTeachRecording'); triggerService('/aescape/mode/activateReadyController')" 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">
|
||||
|
||||
<span class="row">
|
||||
<label id="ExecutionStatusLabel" class="label-warning">
|
||||
Bag manager not connected!
|
||||
</label>
|
||||
</span>
|
||||
|
||||
Last Bag Playing:
|
||||
<span id="lastbagText">
|
||||
None
|
||||
</span>
|
||||
<div>
|
||||
<button type="button" onclick="triggerService('/aescape/mode/activateReadyController')" class="btn btn-default">
|
||||
Activate Ready Mode
|
||||
</button>
|
||||
<button id="executionStartButton" type="button" onclick="triggerService('/aescape/mode/activateExecutionController'); triggerService('/aescape/bags/startPlayingLastRecording')" class="btn btn-primary">
|
||||
Play Last Recording
|
||||
</button>
|
||||
<button id="executionStopButton" type="button" onclick="triggerService('/aescape/bags/stopPlayingBag'); triggerService('/aescape/mode/activateReadyController')" 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>
|
||||
|
||||
</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> -->
|
||||
261
coordinator/js/ros_scripts.js
Normal file
261
coordinator/js/ros_scripts.js
Normal file
@@ -0,0 +1,261 @@
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Publishers
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Topics
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Subscribers
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Operation Mode
|
||||
var modeStatus = new ROSLIB.Topic({
|
||||
ros : ros,
|
||||
name : '/aescape/mode/status',
|
||||
messageType : 'std_msgs/String',
|
||||
throttle_rate : 500 // 2Hz
|
||||
});
|
||||
|
||||
modeStatus.subscribe(function(message) {
|
||||
document.getElementById("stoppedModeButton").className = "btn btn-secondary"
|
||||
document.getElementById("standbyModeButton").className = "btn btn-primary"
|
||||
document.getElementById("readyModeButton").className = "btn btn-primary"
|
||||
document.getElementById("teachingModeButton").className = "btn btn-primary"
|
||||
document.getElementById("executionModeButton").className = "btn btn-primary"
|
||||
|
||||
document.getElementById("recordingStartButton").disabled = true
|
||||
document.getElementById("executionStartButton").disabled = true
|
||||
|
||||
|
||||
|
||||
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"
|
||||
}
|
||||
else if (message.data == "ready")
|
||||
{
|
||||
document.getElementById("readyModeButton").className = "btn btn-primary btn-success"
|
||||
document.getElementById("recordingStartButton").disabled = false
|
||||
document.getElementById("executionStartButton").disabled = false
|
||||
}
|
||||
});
|
||||
|
||||
// Safety Status
|
||||
var safetyStatusTopic = new ROSLIB.Topic({
|
||||
ros : ros,
|
||||
name : '/aescape/mode/safety_status',
|
||||
messageType : 'std_msgs/String',
|
||||
throttle_rate : 500 // 2Hz
|
||||
});
|
||||
|
||||
safetyStatusTopic.subscribe(function(message) {
|
||||
document.getElementById("safetyRunning").className = 'label label-default';
|
||||
document.getElementById("safetyStopped").className = 'label label-default';
|
||||
|
||||
if (message.data == "stopped")
|
||||
{
|
||||
document.getElementById("safetyStopped").className = 'label label-danger';
|
||||
}
|
||||
else if (message.data == "running")
|
||||
{
|
||||
document.getElementById("safetyRunning").className = 'label label-success';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 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';
|
||||
document.getElementById("RecordingStatusLabel").className = 'label label-warning';
|
||||
}
|
||||
else if (message.data == "running")
|
||||
{
|
||||
document.getElementById("RecordingStatusLabel").innerHTML = 'RUNNING!';
|
||||
document.getElementById("RecordingStatusLabel").className = 'label label-success';
|
||||
}
|
||||
});
|
||||
|
||||
// Executing Bag
|
||||
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';
|
||||
document.getElementById("ExecutionStatusLabel").className = 'label label-warning';
|
||||
}
|
||||
else if (message.data == "running")
|
||||
{
|
||||
document.getElementById("ExecutionStatusLabel").innerHTML = 'RUNNING!';
|
||||
document.getElementById("ExecutionStatusLabel").className = 'label label-success';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Last Bag
|
||||
var bagPlayingTopic = new ROSLIB.Topic({
|
||||
ros : ros,
|
||||
name : '/aescape/bags/last_played',
|
||||
messageType : 'std_msgs/String'
|
||||
});
|
||||
|
||||
bagPlayingTopic.subscribe(function(message) {
|
||||
document.getElementById("lastbagText").innerHTML = message.data
|
||||
});
|
||||
|
||||
// FrankaState
|
||||
var frankaStatus = new ROSLIB.Topic({
|
||||
ros : ros,
|
||||
name : '/franka_state_controller/franka_states',
|
||||
messageType : 'franka_msgs/FrankaState',
|
||||
throttle_rate : 500 // 2Hz
|
||||
});
|
||||
|
||||
frankaStatus.subscribe(function(message) {
|
||||
document.getElementById("frankaModeOther").className = "label label-default"
|
||||
document.getElementById("frankaModeIdle").className = "label label-default"
|
||||
document.getElementById("frankaModeMove").className = "label label-default"
|
||||
document.getElementById("frankaModeGuiding").className = "label label-default"
|
||||
document.getElementById("frankaModeReflex").className = "label label-default"
|
||||
document.getElementById("frankaModeUserStopped").className = "label label-default"
|
||||
document.getElementById("frankaModeErrorRecovery").className = "label label-default"
|
||||
document.getElementById("fixFrankaButton").className = "btn btn-primary"
|
||||
|
||||
if (message.robot_mode == 0)
|
||||
{
|
||||
document.getElementById("frankaModeOther").className = "label label-warning"
|
||||
document.getElementById("fixFrankaButton").className = "btn btn-danger"
|
||||
}
|
||||
else if (message.robot_mode == 1)
|
||||
{
|
||||
document.getElementById("frankaModeIdle").className = "label label-warning"
|
||||
document.getElementById("fixFrankaButton").className = "btn btn-danger"
|
||||
}
|
||||
else if (message.robot_mode == 2)
|
||||
{
|
||||
document.getElementById("frankaModeMove").className = "label label-warning"
|
||||
document.getElementById("fixFrankaButton").className = "btn btn-success"
|
||||
}
|
||||
else if (message.robot_mode == 3)
|
||||
{
|
||||
document.getElementById("frankaModeGuiding").className = "label label-warning"
|
||||
document.getElementById("fixFrankaButton").className = "btn btn-default"
|
||||
}
|
||||
else if (message.robot_mode == 4)
|
||||
{
|
||||
document.getElementById("frankaModeReflex").className = "label label-warning"
|
||||
document.getElementById("fixFrankaButton").className = "btn btn-danger"
|
||||
|
||||
}
|
||||
else if (message.robot_mode == 5)
|
||||
{
|
||||
document.getElementById("frankaModeUserStopped").className = "label label-warning"
|
||||
document.getElementById("fixFrankaButton").className = "btn btn-default"
|
||||
}
|
||||
else if (message.robot_mode == 6)
|
||||
{
|
||||
document.getElementById("frankaModeErrorRecovery").className = "label label-warning"
|
||||
document.getElementById("fixFrankaButton").className = "btn btn-default"
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Robotiq Data
|
||||
var robotiqDataTopic = new ROSLIB.Topic({
|
||||
ros : ros,
|
||||
name : '/robotiq_ft_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)
|
||||
|
||||
if ((Math.abs(force.x) > 0.5) || (Math.abs(force.y) > 0.5) || (Math.abs(force.z) > 0.5))
|
||||
{
|
||||
document.getElementById("calibrateButton").className = "btn btn-danger"
|
||||
} else {
|
||||
document.getElementById("calibrateButton").className = "btn btn-default"
|
||||
}
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
0
coordinator/js/update_guis.js
Normal file
0
coordinator/js/update_guis.js
Normal file
Binary file not shown.
Binary file not shown.
@@ -42,61 +42,3 @@
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ##################################### D-PAD ######################################### -->
|
||||
<!--
|
||||
|
||||
<p>Click in the actual image. Relative coordinates will be displayed.</p>
|
||||
<p id="rez"></p>
|
||||
<div>
|
||||
<img id="myImage" src="/backend/images/D-pad.png">
|
||||
-->
|
||||
|
||||
<!-- ##################################### END D-PAD ######################################### -->
|
||||
|
||||
|
||||
<!-- ##################################### Example Progress Bar ######################################### -->
|
||||
|
||||
<div class="panel panel-default">
|
||||
|
||||
<div class="panel-heading">
|
||||
Example Pannel Heading
|
||||
</div>
|
||||
|
||||
|
||||
<div class="panel-body">
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<label>
|
||||
Bar Title
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="progress">
|
||||
<div id="progressBar1" class="progress-bar progress-bar-striped active" role="progressbar"
|
||||
aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width:100%" >
|
||||
No data recieved yet. </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ##################################### END Example Progress Bar ######################################### -->
|
||||
|
||||
<!-- ##################################### Example Image ######################################### -->
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Camera Image
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="col-lg-4">
|
||||
<img height="350" alt="No Camera Image" id="imageStream" src="http://localhost:8080/stream?topic=/camera/image"></img>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ##################################### END Example Image ######################################### -->
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
function sendRosMessageExample()
|
||||
{
|
||||
publishStringExample(String(document.getElementById("sendRosMessageExample").value))
|
||||
}
|
||||
|
||||
function update_sendRosMessageExample(msg)
|
||||
{
|
||||
document.getElementById("recievedMessageDiv").innerHTML = msg
|
||||
}
|
||||
|
||||
function update_ProgressBar(value)
|
||||
{
|
||||
|
||||
// This would be a great way of getting a float or int from a rosTopic and displaying it.
|
||||
// I would suggest storing the data as a data field in the ros_scripts then updating it every 500 or 1000 ms rather than updating the gui every time you recieve a message
|
||||
var num_string = "";
|
||||
num_string = num_string.concat(value);
|
||||
num_string = num_string.substring(0,4);
|
||||
num_string = num_string.concat("%");
|
||||
|
||||
doc = document.getElementById("progressBar1");
|
||||
|
||||
doc.style.width = num_string;
|
||||
doc.innerHTML = num_string;
|
||||
|
||||
if (value < 50 && value > 25 ) {
|
||||
doc.className = "progress-bar progress-bar-warning";
|
||||
}
|
||||
else if ( value <= 25)
|
||||
{
|
||||
doc.className = "progress-bar progress-bar-danger";
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.className = "progress-bar progress-bar-success";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
window.setInterval(function(){
|
||||
|
||||
update_ProgressBar(Math.random() * 100);
|
||||
|
||||
}, 1000);
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 56 KiB |
2844
include/js/roslib.js
2844
include/js/roslib.js
File diff suppressed because it is too large
Load Diff
3
include/js/roslib.min.js
vendored
3
include/js/roslib.min.js
vendored
File diff suppressed because one or more lines are too long
157
index.html
157
index.html
@@ -2,6 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Lab UI</title>
|
||||
<!--
|
||||
Link to included files. These are typically done by fetching from the web.
|
||||
Because this needs to run without an internet conection, the files were saved
|
||||
@@ -26,87 +27,80 @@ Tutorials can be found here: http://www.w3schools.com/bootstrap/default.asp
|
||||
|
||||
<script type="text/javascript" src="backend/js/Topic.js"></script>
|
||||
|
||||
<audio id="audio" src="audio/beep-04.mp3" autostart="false" ></audio>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
|
||||
<script>
|
||||
$(function(){
|
||||
$("#includedContent").load("data_display/data_display.html");
|
||||
$("#coordinatorContent").load("coordinator/coordinator.html");
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" src="coordinator/js/ros_scripts.js"></script>
|
||||
<script type="text/javascript" src="coordinator/js/update_guis.js"></script>
|
||||
|
||||
<script type="text/javascript" src="data_display/js/ros_scripts.js"></script>
|
||||
<script type="text/javascript" src="data_display/js/update_guis.js"></script>
|
||||
|
||||
<!-- <script>
|
||||
$(function(){
|
||||
$("#visionContent").load("vision/vision.html");
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" src="vision/js/ros_scripts.js"></script>
|
||||
<script type="text/javascript" src="vision/js/update_guis.js"></script> -->
|
||||
|
||||
<meta content="text/html; charset=UTF-8; X-Content-Type-Options=nosniff" http-equiv="Content-Type" />
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div id="jumbotronTitle" class="jumbotron">
|
||||
<h1>ROS Display</h1>
|
||||
</div>
|
||||
|
||||
<!-- ##################################### ROS BAG PANEL ######################################### -->
|
||||
<!-- ROS Bag Panel -->
|
||||
<div class="panel panel-default">
|
||||
|
||||
<div class="panel-heading">
|
||||
ROS Bag
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
Bagfile name must not start with "/"
|
||||
<div class="input-group">
|
||||
<input type="text" id="recordText" class="form-control" placeholder="bag_filename">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-primary" id="recordButton" type="button" onclick="toggleRecording()">
|
||||
<span id="recordButtonText">
|
||||
Start
|
||||
</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="jumbotronTitle" class="jumbotron text-center">
|
||||
<h1>Lab UI</h1>
|
||||
|
||||
</div>
|
||||
<!-- ##################################### END ROS BAG PANEL ######################################### -->
|
||||
|
||||
|
||||
<ul id="tabs" class="nav nav-pills" data-tabs="tabs" >
|
||||
<li class="active">
|
||||
<a href="#DataDisplay" data-toggle="tab">
|
||||
Data Display
|
||||
</a>
|
||||
</li>
|
||||
<li> <a href="#rosbridgeconnection" data-toggle="tab">
|
||||
ROS Bridge Connection
|
||||
<span id="rosbridgeconnection_badge" class="badge">
|
||||
Not Connected
|
||||
</span></a></li>
|
||||
</ul>
|
||||
<div class="container">
|
||||
<div class="col-md-1">
|
||||
Master:
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label id="MasterName"></label>
|
||||
<script>
|
||||
getMasterName();
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-md-3">
|
||||
<ul id="tabs" class="nav nav-pills" data-tabs="tabs" >
|
||||
<li> <a href="#rosbridgeconnection" data-toggle="tab">
|
||||
ROS Bridge Connection
|
||||
<span id="rosbridgeconnection_badge" class="badge">
|
||||
Not Connected
|
||||
</span></a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<a href="#Coordinator" data-toggle="tab">
|
||||
Coordinator
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="vision/vision.html">
|
||||
Vision
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="my-tab-content" class="tab-content">
|
||||
|
||||
<div class="tab-pane active" id="DataDisplay">
|
||||
|
||||
|
||||
<!-- ##################################### ROBOT DISPLAY PANEL ######################################### -->
|
||||
<div id="includedContent"></div>
|
||||
<!-- ##################################### END DISPLAY PANEL ######################################### -->
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="tab-pane active" id="Coordinator">
|
||||
<div id="coordinatorContent"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- <div class="tab-pane" id="Vision">
|
||||
<div id="visionContent"></div>
|
||||
</div> -->
|
||||
|
||||
|
||||
<div class="tab-pane" id="rosbridgeconnection">
|
||||
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
|
||||
@@ -132,18 +126,53 @@ Tutorials can be found here: http://www.w3schools.com/bootstrap/default.asp
|
||||
</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. Checked topics will be bagged when "Start" is selected.
|
||||
ROS Topics.
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<div id="ROSTopics">
|
||||
<div class="col-sm-1" id="ROSTopics">
|
||||
N/A
|
||||
</div>
|
||||
</div>
|
||||
@@ -151,7 +180,7 @@ Tutorials can be found here: http://www.w3schools.com/bootstrap/default.asp
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
ROS Nodes
|
||||
ROS Nodes.
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
|
||||
26
launch.bash
26
launch.bash
@@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
kill_child_processes() {
|
||||
isTopmost=$1
|
||||
curPid=$2
|
||||
childPids=`ps -o pid --no-headers --ppid ${curPid}`
|
||||
for childPid in $childPids
|
||||
do
|
||||
kill_child_processes 0 $childPid
|
||||
done
|
||||
if [ $isTopmost -eq 0 ]; then
|
||||
kill -9 $curPid 2> /dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# Ctrl-C trap. Catches INT signal
|
||||
trap "kill_child_processes 1 $$; exit 0" INT
|
||||
|
||||
chmod a+x src/bagger.py
|
||||
|
||||
x-terminal-emulator -e "roslaunch rosbridge_gui all.launch" &
|
||||
x-terminal-emulator -e "python -m SimpleHTTPServer 8000" &
|
||||
x-terminal-emulator -e "rosrun web_video_server web_video_server"
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<launch>
|
||||
<include file="$(find rosbridge_server)/launch/rosbridge_websocket.launch" />
|
||||
<include file="$(find rosbridge_gui)/launch/bagger.launch" />
|
||||
<include file="$(find rosbridge_gui)/launch/talker.launch" />
|
||||
</launch>
|
||||
@@ -1,3 +0,0 @@
|
||||
<launch>
|
||||
<node name="bagger" pkg="rosbridge_gui" type="bagger.py" />
|
||||
</launch>
|
||||
8
launch/lab_ui.launch
Executable file
8
launch/lab_ui.launch
Executable file
@@ -0,0 +1,8 @@
|
||||
<launch>
|
||||
<include file="$(find rosbridge_server)/launch/rosbridge_websocket.launch" />
|
||||
|
||||
<node name="lab_ui_web_server" pkg="aescape_lab_ui" type="webserver.sh" respawn="false" />
|
||||
|
||||
<node name="lab_ui_video_server" pkg="web_video_server" type="web_video_server" respawn="false" />
|
||||
|
||||
</launch>
|
||||
@@ -1,3 +0,0 @@
|
||||
<launch>
|
||||
<node name="talker" pkg="rosbridge_gui" type="talker.py" />
|
||||
</launch>
|
||||
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
<package>
|
||||
<name>rosbridge_gui</name>
|
||||
<name>aescape_lab_ui</name>
|
||||
<version>0.0.0</version>
|
||||
<description>The rosbridge_gui package</description>
|
||||
<description>The aescape_lab_ui package</description>
|
||||
|
||||
<!-- One maintainer tag required, multiple allowed, one person per tag -->
|
||||
<!-- Example: -->
|
||||
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
|
||||
<maintainer email="turner.glen@gmail.com">glen</maintainer>
|
||||
<maintainer email="david@aescape.co">David</maintainer>
|
||||
|
||||
|
||||
<!-- One license tag required, multiple allowed, one license per tag -->
|
||||
@@ -41,6 +41,8 @@
|
||||
<run_depend>rospy</run_depend>
|
||||
<run_depend>std_msgs</run_depend>
|
||||
|
||||
<run_depend>web_video_server</run_depend>
|
||||
<run_depend>rosbridge_server</run_depend>
|
||||
|
||||
<!-- The export tag contains other, unspecified, tags -->
|
||||
<export>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 60 KiB |
7
scripts/webserver.sh
Executable file
7
scripts/webserver.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
cd $(rospack find aescape_lab_ui)
|
||||
# python3 -m http.server 8000
|
||||
|
||||
# Node webserver: https://www.npmjs.com/package/http-server
|
||||
http-server -p 8000
|
||||
@@ -1,49 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
import rospy
|
||||
from std_msgs.msg import String
|
||||
import rospkg
|
||||
import subprocess
|
||||
import os
|
||||
import signal
|
||||
|
||||
class Bagger(object):
|
||||
|
||||
def __init__(self):
|
||||
rospy.init_node("bagger", anonymous=True)
|
||||
rospy.Subscriber("bag_publisher", String, self.callback)
|
||||
self.pub = rospy.Publisher("bag_notifier", String, queue_size=10)
|
||||
self.proc = None
|
||||
rospack = rospkg.RosPack()
|
||||
self.data_path = os.path.join(rospack.get_path("rosbridge_gui"), "data")
|
||||
|
||||
def callback(self, msg):
|
||||
if msg.data == "STOP" and self.proc is not None:
|
||||
os.killpg(self.proc.pid, signal.SIGINT)
|
||||
self.pub.publish("STOPPED")
|
||||
else:
|
||||
msg_data = msg.data.split()
|
||||
self.pub.publish(str(len(msg_data)))
|
||||
self.pub.publish(str(msg_data))
|
||||
if len(msg_data) == 0: # We only got the name of the bag file and not any topics
|
||||
bag_file_name = os.path.join(self.data_path, "bag_file")
|
||||
self.proc = subprocess.Popen(["rosbag", "record",
|
||||
"--all", "-o", bag_file_name], preexec_fn=os.setsid)
|
||||
self.pub.publish("STARTED")
|
||||
elif len(msg_data) == 1: # We only got the name of the bag file and not any topics
|
||||
bag_file_name = os.path.join(self.data_path, msg_data)
|
||||
self.proc = subprocess.Popen(["rosbag", "record",
|
||||
"--all", "-o", bag_file_name], preexec_fn=os.setsid)
|
||||
self.pub.publish("STARTED")
|
||||
else: #we posibly have a bag file name and a list of topics
|
||||
if msg_data[0].startswith("/"): #then we know there is no bag file name
|
||||
msg_data = ["bagfile"] + msg_data
|
||||
msg_data[0] = os.path.join(self.data_path, msg_data[0])
|
||||
processList = ["rosbag", "record", "-o"] + msg_data
|
||||
self.pub.publish(" ".join(processList))
|
||||
self.proc = subprocess.Popen( processList, preexec_fn=os.setsid)
|
||||
self.pub.publish("STARTED")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
Bagger()
|
||||
rospy.spin()
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# license removed for brevity
|
||||
import rospy
|
||||
from std_msgs.msg import String
|
||||
|
||||
def talker():
|
||||
pub = rospy.Publisher('chatter', String, queue_size=10)
|
||||
rospy.init_node('talker', anonymous=True)
|
||||
rate = rospy.Rate(10) # 10hz
|
||||
while not rospy.is_shutdown():
|
||||
hello_str = "hello world %s" % rospy.get_time()
|
||||
rospy.loginfo(hello_str)
|
||||
pub.publish(hello_str)
|
||||
rate.sleep()
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
talker()
|
||||
except rospy.ROSInterruptException:
|
||||
pass
|
||||
104
vision/js/ros_scripts.js
Normal file
104
vision/js/ros_scripts.js
Normal 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);
|
||||
});
|
||||
}
|
||||
0
vision/js/update_guis.js
Normal file
0
vision/js/update_guis.js
Normal file
122
vision/vision.html
Normal file
122
vision/vision.html
Normal 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> -->
|
||||
Reference in New Issue
Block a user