roswww_static: infrastructure for web-based Clover plugins (#230)

* Package for generating static web sites for ROS

* rosstatic: add CMakeLists.txt

* rosstatic: utilize rospkg, store static directory in ROS_HOME

* rosstatic: default_package param

* rosstatic: fix URLs in docs

* clover.launch: make clover the default package for www

* Unused import

* Rename rosstatic to roswww_static

* Fixes
This commit is contained in:
Oleg Kalachev
2020-06-13 02:08:00 +03:00
committed by GitHub
parent c71a46ce9d
commit bcb7351a90
10 changed files with 132 additions and 7 deletions

View File

@@ -20,7 +20,7 @@
# Example:
# DocumentRoot /home/krypton/htdocs
DocumentRoot /home/pi/catkin_ws/src/clover/clover/www
DocumentRoot /home/pi/.ros/www
# Redirect:
# ---------

View File

@@ -82,4 +82,9 @@
<!-- Shell access through ROS service -->
<node name="shell" pkg="clover" type="shell" output="screen" if="$(arg shell)"/>
<!-- Update static directory -->
<node pkg="roswww_static" name="roswww_static" type="main.py" clear_params="true">
<param name="default_package" value="clover"/>
</node>
</launch>

View File

@@ -12,8 +12,8 @@
<script src="js/roslib.js"></script>
<script type="text/javascript">
document.querySelector("#wvs").href = location.origin + ':8080';
document.querySelector("#butterfly").href = location.origin + ':57575';
document.querySelector("#wvs").href = location.protocol + '//' + location.hostname + ':8080';
document.querySelector("#butterfly").href = location.protocol + '//' + location.hostname + ':57575';
// Determine image version
var ros = new ROSLIB.Ros({ url: 'ws://' + location.hostname + ':9090' });

View File

@@ -41,7 +41,7 @@ An example of a web page, working with `roslib.js`:
[Taking off, landing and all the rest operations](programming.md) can be implemented in a similar way.
The page should be placed in the `/home/pi/catkin_ws/src/clover/clover/www/` directory. After that, it will be available at `http://192.168.11.1/<page_name>.html`. When the page is opened, browser should show an alert with the drone telemetry and constantly print the state of the flight controller to the console.
The page should be placed in the `/home/pi/catkin_ws/src/clover/clover/www/` directory. After that, it will be available at `http://192.168.11.1/clover/<page_name>.html`. When the page is opened, browser should show an alert with the drone telemetry and constantly print the state of the flight controller to the console.
<img src="../assets/js-ros.png" class="center zoom"/>
@@ -49,6 +49,6 @@ See additional information in [`roslibjs` tutorial](http://wiki.ros.org/roslibjs
## Web GCS
See an example of simplified web ground control station on Clover at http://192.168.11.1/gcs.html.
See an example of simplified web ground control station on Clover at http://192.168.11.1/clover/gcs.html.
<img src="../assets/web-gcs.png" class="center zoom"/>

View File

@@ -41,7 +41,7 @@
[Взлет, посадка и все остальные операции](programming.md) могут быть осуществлены аналогичным образом.
Страница должна быть помещена в каталог `/home/pi/catkin_ws/src/clover/clover/www/`. После этого она станет доступна по адресу `http://192.168.11.1/<имя_страницы>.html`. При открытии страницы браузер должен показать окно с телеметрией дрона, а также постоянно выводить состояние полетного контроллера в консоль.
Страница должна быть помещена в каталог `/home/pi/catkin_ws/src/clover/clover/www/`. После этого она станет доступна по адресу `http://192.168.11.1/clover/<имя_страницы>.html`. При открытии страницы браузер должен показать окно с телеметрией дрона, а также постоянно выводить состояние полетного контроллера в консоль.
<img src="../assets/js-ros.png" class="center zoom"/>
@@ -49,6 +49,6 @@
## Браузерная GCS
Смотрите также пример реализации упрощенной браузерной наземной станции (GCS) на Клевере по адресу http://192.168.11.1/gcs.html.
Смотрите также пример реализации упрощенной браузерной наземной станции (GCS) на Клевере по адресу http://192.168.11.1/clover/gcs.html.
<img src="../assets/web-gcs.png" class="center zoom"/>

View File

@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.0)
project(roswww_static)
find_package(catkin REQUIRED)
catkin_package()
install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})

17
roswww_static/README.md Normal file
View File

@@ -0,0 +1,17 @@
# roswww_static
roswww_static creates a static web directory for your ROS-powered system with symlinks to all the `www` subdirectories found in your ROS packages. This way you can use any external web server (e. g. [nginx](https://nginx.org/), [Monkey](https://github.com/monkey/monkey), [Caddy](https://caddyserver.com)) to serve you static data, in compatible with `roswww` manner.
Note: you should configure your web server to make it follow symlinks.
## Instructions
* Run `main.py` node and it will generate the symlinks and index file.
* Point your static web server path to `~/.ros/www`.
You can rerun `main.py` if the list of installed packages changes.
## Parameters
* `index`  path for index page, otherwise packages list would be generated.
* `default_package`  if set then the index page would redirect to this package's page.

View File

@@ -0,0 +1,6 @@
<launch>
<node pkg="roswww_static" name="roswww_static" type="main.py" clear_params="true" output="screen">
<!-- <param name="index" value="$(find my_package)/www/index.html"/> -->
<!-- <param name="default_package" value="my_package"/> -->
</node>
</launch>

40
roswww_static/main.py Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env python
# TODO: add custom header, footer
# TODO: symlinks or copy param
import os
import shutil
import rospy
import rospkg
rospy.init_node('roswww_static')
rospack = rospkg.RosPack()
www = rospkg.get_ros_home() + '/www'
index_file = rospy.get_param('~index_file', None)
default_package = rospy.get_param('~default_package', None)
shutil.rmtree(www, ignore_errors=True) # reset www directory content
os.mkdir(www)
packages = rospack.list()
index = '<h1>Packages list</h1>\n<ul>\n'
for name in packages:
path = rospack.get_path(name)
if os.path.exists(path + '/www'):
rospy.loginfo('found www path for %s package', name)
os.symlink(path + '/www', www + '/' + name)
index += '<li><a href="{name}/">{name}</a></li>'.format(name=name)
if default_package is not None:
redirect_html = '<meta http-equiv=refresh content="0; url={name}/">'.format(name=default_package)
open(www + '/index.html', 'w').write(redirect_html)
elif index_file is not None:
rospy.loginfo('symlinking index file')
os.symlink(index_file, www + '/index.html')
else:
open(www + '/index.html', 'w').write(index)

49
roswww_static/package.xml Normal file
View File

@@ -0,0 +1,49 @@
<?xml version="1.0"?>
<package format="2">
<name>roswww_static</name>
<version>0.0.0</version>
<description>Static web pages for ROS packages</description>
<maintainer email="okalachev@gmail.com">Oleg Kalachev</maintainer>
<license>MIT</license>
<!-- Url tags are optional, but multiple are allowed, one per tag -->
<!-- Optional attribute type can be: website, bugtracker, or repository -->
<!-- Example: -->
<!-- <url type="website">http://wiki.ros.org/roswww_static</url> -->
<!-- Author tags are optional, multiple are allowed, one per tag -->
<!-- Authors do not have to be maintainers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!-- The *depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
<!-- <depend>roscpp</depend> -->
<!-- Note that this is equivalent to the following: -->
<!-- <build_depend>roscpp</build_depend> -->
<!-- <exec_depend>roscpp</exec_depend> -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use build_export_depend for packages you need in order to build against this package: -->
<!-- <build_export_depend>message_generation</build_export_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>message_runtime</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<!-- Use doc_depend for packages you need only for building documentation: -->
<!-- <doc_depend>doxygen</doc_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>