├── .github └── ISSUE_TEMPLATE │ ├── bug-issue.md │ ├── discussion.md │ └── feature_request.md ├── CMakeLists.txt ├── Contributing.md ├── LICENSE ├── ReadMe.md ├── docker └── Dockerfile ├── launch └── server.launch ├── package.xml ├── public ├── assets │ ├── add.svg │ ├── altimeter.svg │ ├── altimeter_arrow.svg │ ├── altimeter_arrow_green.svg │ ├── altimeter_green.svg │ ├── area.svg │ ├── battery_100.svg │ ├── battery_100_charging.svg │ ├── battery_20.svg │ ├── battery_20_charging.svg │ ├── battery_40.svg │ ├── battery_40_charging.svg │ ├── battery_60.svg │ ├── battery_60_charging.svg │ ├── battery_80.svg │ ├── battery_80_charging.svg │ ├── battery_unknown.svg │ ├── button.svg │ ├── button_false.svg │ ├── button_true.svg │ ├── costmap.svg │ ├── default_layout.json │ ├── dropdown_edit.svg │ ├── dropdown_setup.svg │ ├── dropdown_start.svg │ ├── dropdown_stop.svg │ ├── dropdown_xy.svg │ ├── dropdown_z.svg │ ├── folder.svg │ ├── grid.svg │ ├── gridcells.svg │ ├── icon │ │ ├── 152.png │ │ ├── 16.png │ │ ├── 192.png │ │ ├── 32.png │ │ ├── 512.png │ │ ├── 96.png │ │ ├── icon.svg │ │ ├── manifest.json │ │ └── preview.jpg │ ├── image.svg │ ├── initialpose.png │ ├── initialpose.svg │ ├── inspector.svg │ ├── joypos.svg │ ├── joystick.svg │ ├── map.svg │ ├── marker.svg │ ├── markerarray.svg │ ├── node_kill.svg │ ├── node_restart.svg │ ├── nodemgr.svg │ ├── odom.svg │ ├── path.svg │ ├── pointcloud.svg │ ├── pose.svg │ ├── posearray.svg │ ├── posewithcovariancestamped.svg │ ├── range.svg │ ├── rawmap.svg │ ├── rawmap_transparent.svg │ ├── reconfigure.svg │ ├── robot_model │ │ ├── _2wd.png │ │ ├── _4wd.png │ │ ├── _arrow.png │ │ ├── _dog.png │ │ ├── _hatchback.png │ │ ├── _orca.png │ │ ├── _pancake.png │ │ ├── _rccar.png │ │ ├── _rov.png │ │ ├── _sandwich.png │ │ ├── _tortoise.png │ │ └── _tuna.png │ ├── robotmodel.svg │ ├── rosbag.svg │ ├── rosbag_active.svg │ ├── rosbridge_connected.svg │ ├── rosbridge_disconnected.svg │ ├── rosbridge_reconnect.svg │ ├── satelite.svg │ ├── scan.svg │ ├── settings.svg │ ├── simplegoal.png │ ├── simplegoal.svg │ ├── speedometer.svg │ ├── speedometer_dial.svg │ ├── speedometer_icon.svg │ ├── temp_cold.svg │ ├── temp_hot.svg │ ├── temp_unknown.svg │ ├── temp_warm.svg │ ├── tf.svg │ ├── tile_error.png │ ├── tile_loading.png │ └── waypoints.svg ├── css │ ├── font │ │ ├── LICENCE.txt │ │ ├── TRADEMARKS.txt │ │ ├── ubuntu.mono.ttf │ │ ├── ubuntu.mono.woff │ │ └── ubuntu.mono.woff2 │ └── style.css ├── head.html ├── iconbar.html ├── index.html ├── js │ ├── lib │ │ ├── nipplejs.js │ │ ├── nipplejs.min.js │ │ ├── nipplejs_LICENSE.txt │ │ ├── quaternion.min.js │ │ ├── quaternionjs_LICENSE.txt │ │ ├── roslib.min.js │ │ └── roslibjs_LICENSE.txt │ ├── main.js │ ├── modules │ │ ├── database.js │ │ ├── elements.js │ │ ├── joystick.js │ │ ├── navsat.js │ │ ├── persistent.js │ │ ├── rosbridge.js │ │ ├── status.js │ │ ├── tf.js │ │ ├── util.js │ │ └── view.js │ └── setup.js └── templates │ ├── add │ ├── add_icon.html │ ├── add_modal.html │ └── add_script.js │ ├── altimeter │ ├── altimeter_icon.html │ ├── altimeter_modal.html │ ├── altimeter_script.js │ └── altimeter_view.html │ ├── area │ ├── area_icon.html │ ├── area_modal.html │ ├── area_script.js │ └── area_view.html │ ├── battery │ ├── battery_icon.html │ ├── battery_modal.html │ └── battery_script.js │ ├── button │ ├── button_icon.html │ ├── button_modal.html │ └── button_script.js │ ├── compressedimage │ ├── compressedimage_icon.html │ ├── compressedimage_modal.html │ ├── compressedimage_script.js │ └── compressedimage_view.html │ ├── folder │ ├── folder_icon.html │ ├── folder_modal.html │ └── folder_script.js │ ├── grid │ ├── grid_icon.html │ ├── grid_modal.html │ ├── grid_script.js │ └── grid_view.html │ ├── gridcells │ ├── gridcells_icon.html │ ├── gridcells_modal.html │ ├── gridcells_script.js │ └── gridcells_view.html │ ├── initialpose │ ├── initialpose_icon.html │ ├── initialpose_modal.html │ ├── initialpose_script.js │ └── initialpose_view.html │ ├── inspector │ ├── inspector_icon.html │ ├── inspector_modal.html │ └── inspector_script.js │ ├── map │ ├── map_icon.html │ ├── map_modal.html │ ├── map_script.js │ ├── map_view.html │ └── map_worker.js │ ├── markerarray │ ├── markerarray_icon.html │ ├── markerarray_modal.html │ ├── markerarray_script.js │ └── markerarray_view.html │ ├── nodemgr │ ├── nodemgr_icon.html │ ├── nodemgr_modal.html │ └── nodemgr_script.js │ ├── odom │ ├── odom_icon.html │ ├── odom_modal.html │ ├── odom_script.js │ └── odom_view.html │ ├── path │ ├── path_icon.html │ ├── path_modal.html │ ├── path_script.js │ └── path_view.html │ ├── pointcloud │ ├── pointcloud_icon.html │ ├── pointcloud_modal.html │ ├── pointcloud_script.js │ └── pointcloud_view.html │ ├── posearray │ ├── posearray_icon.html │ ├── posearray_modal.html │ ├── posearray_script.js │ └── posearray_view.html │ ├── posewithcovariancestamped │ ├── posewithcovariancestamped_icon.html │ ├── posewithcovariancestamped_modal.html │ ├── posewithcovariancestamped_script.js │ └── posewithcovariancestamped_view.html │ ├── range │ ├── range_icon.html │ ├── range_modal.html │ ├── range_script.js │ └── range_view.html │ ├── reconfigure │ ├── reconfigure_icon.html │ ├── reconfigure_modal.html │ └── reconfigure_script.js │ ├── robotmodel │ ├── robotmodel_icon.html │ ├── robotmodel_modal.html │ ├── robotmodel_script.js │ └── robotmodel_view.html │ ├── rosbag │ ├── rosbag_icon.html │ ├── rosbag_modal.html │ └── rosbag_script.js │ ├── rosbridge │ ├── rosbridge_icon.html │ ├── rosbridge_modal.html │ └── rosbridge_script.js │ ├── satelite │ ├── satelite_icon.html │ ├── satelite_modal.html │ ├── satelite_script.js │ └── satelite_view.html │ ├── scan │ ├── scan_icon.html │ ├── scan_modal.html │ ├── scan_script.js │ └── scan_view.html │ ├── settings │ ├── settings_icon.html │ ├── settings_modal.html │ └── settings_script.js │ ├── simplegoal │ ├── simplegoal_icon.html │ ├── simplegoal_modal.html │ ├── simplegoal_script.js │ └── simplegoal_view.html │ ├── speedometer │ ├── speedometer_icon.html │ ├── speedometer_modal.html │ └── speedometer_script.js │ ├── teleop │ ├── teleop_icon.html │ ├── teleop_modal.html │ ├── teleop_script.js │ └── teleop_view.html │ ├── temperature │ ├── temperature_icon.html │ ├── temperature_modal.html │ └── temperature_script.js │ ├── tf │ ├── tf_icon.html │ ├── tf_modal.html │ ├── tf_script.js │ └── tf_view.html │ └── waypoints │ ├── waypoints_icon.html │ ├── waypoints_modal.html │ ├── waypoints_script.js │ └── waypoints_view.html ├── scripts ├── server.py ├── service_handler.py ├── test │ └── _test_button.py ├── topic_handler.py └── waypoints_to_simple_goals.py └── srv ├── GetNodeParameters.srv ├── ListExecutables.srv ├── ListPackages.srv ├── LoadMap.srv ├── ManageNode.srv ├── RecordRosbag.srv └── SaveMap.srv /.github/ISSUE_TEMPLATE/bug-issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug/Issue 3 | about: Something ain't working. 4 | title: '' 5 | labels: bug 6 | assignees: MoffKalast 7 | 8 | --- 9 | 10 | [Problem description] 11 | 12 | **Server Platform(s):** 13 | - OS: [e.g. Ubuntu 22.04] 14 | - Architecture: [e.g. x86_64] 15 | - ROS Version: [e.g. Humble] 16 | - Branch/Tag: [e.g. ros2] 17 | 18 | **Client Platform(s):** 19 | - OS: [e.g. Android 14] 20 | - Architecture: [e.g. aarch64] 21 | - Browser: [e.g. Chrome] 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/discussion.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Discussion 3 | about: Anything else you want to ask or talk about. 4 | title: '' 5 | labels: question 6 | assignees: '' 7 | 8 | --- 9 | 10 | Best head over to https://github.com/MoffKalast/vizanti/discussions 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Let's add something new. 4 | title: '' 5 | labels: enhancement 6 | assignees: MoffKalast 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | project(vizanti) 3 | 4 | find_package(catkin REQUIRED COMPONENTS 5 | dynamic_reconfigure 6 | rospy 7 | actionlib_msgs 8 | move_base_msgs 9 | std_msgs 10 | message_generation 11 | ) 12 | 13 | add_service_files( 14 | FILES 15 | GetNodeParameters.srv 16 | SaveMap.srv 17 | LoadMap.srv 18 | RecordRosbag.srv 19 | ManageNode.srv 20 | ListPackages.srv 21 | ListExecutables.srv 22 | ) 23 | 24 | generate_messages( 25 | DEPENDENCIES 26 | std_msgs 27 | ) 28 | 29 | 30 | catkin_package( 31 | CATKIN_DEPENDS dynamic_reconfigure rospy actionlib_msgs geometry_msgs move_base_msgs std_msgs message_runtime 32 | ) 33 | 34 | include_directories( 35 | ${catkin_INCLUDE_DIRS} 36 | ) 37 | 38 | file( 39 | GLOB PYTHON_SCRIPTS_DIR "scripts/*.py" 40 | ) 41 | catkin_install_python( 42 | PROGRAMS ${PYTHON_SCRIPTS_DIR} 43 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 44 | ) 45 | 46 | install( 47 | DIRECTORY public launch 48 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} 49 | ) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2023, Vid Rijavec 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # Icon Vizanti - Web Visualizer & Mission Planner for ROS 2 | 3 | [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.png)](https://opensource.org/licenses/BSD-3-Clause) [![Build Status](https://build.ros.org/buildStatus/icon?job=Ndev__vizanti__ubuntu_focal_amd64&build=4)](https://build.ros.org/job/Ndev__vizanti__ubuntu_focal_amd64/4/) 4 | 5 | Vizanti is a web-based visualization and control tool developed for more convenient operation of outdoor robots running the Robot Operating System (ROS). The application attempts to replicate RViz's orthographic 2D view as closely as possible with a smartphone friendly interface. The second goal is to allow planning and executing movement and mission commands, i.e. goals and waypoints, with custom buttons and parameter reconfigure. 6 | 7 | 8 | 9 | ## Installation 10 | 11 | As a field tool, Vizanti is designed to operate just as well without internet access, and as such the intended way is to host it on a robot, with rosbridge autoconnecting to the host IP. 12 | 13 | ```bash 14 | cd ~/catkin_ws/src 15 | git clone -b noetic-devel https://github.com/MoffKalast/vizanti.git 16 | cd .. 17 | rosdep install -i --from-path src/vizanti -y 18 | catkin_make 19 | ``` 20 | 21 | ### Docker 22 | 23 | Alternatively, you can also containerize Vizanti. For that you need to [install Docker](https://docs.docker.com/engine/install/ubuntu/) and build the container: 24 | 25 | ```bash 26 | git clone -b noetic-devel https://github.com/MoffKalast/vizanti.git 27 | cd vizanti 28 | docker build -f docker/Dockerfile -t vizanti:1.0 . 29 | ``` 30 | 31 | ## Run 32 | 33 | ```bash 34 | roslaunch vizanti server.launch 35 | ``` 36 | Or with Docker: 37 | ```bash 38 | docker run -dit --net=host --name vizanti-noetic vizanti:1.0 39 | ``` 40 | 41 | The web app can be accessed at `http://:5000`. Client settings are automatically saved in localStorage. The satelite imagery renderer also uses the indexedDB to store tiles for offline use (note that this is IP specific). By default the rosbridge instance also occupies port 5001. 42 | 43 | If you're using a mobile device connected to a robot's hotspot that doesn't have internet access, make sure to turn off mobile data. This will prevent Android from sending packets to the wrong gateway. 44 | 45 | #### Check [the wiki](https://github.com/MoffKalast/vizanti/wiki) for usage and configuration instructions, as well as feature and compatibility info. 46 | 47 | ## Contributing 48 | 49 | Please see [Contributing.md](Contributing.md) for more information. -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM osrf/ros:noetic-desktop 2 | 3 | SHELL ["/bin/bash", "-c"] 4 | 5 | # Update and build the vizanti package 6 | RUN apt-get update 7 | RUN useradd -ms /bin/bash vizanti 8 | RUN mkdir -p /home/vizanti/catkin_ws/src 9 | COPY . /home/vizanti/catkin_ws/src/vizanti/. 10 | WORKDIR "/home/vizanti/catkin_ws" 11 | RUN source /opt/ros/noetic/setup.bash && rosdep update && rosdep install -i --from-path src/vizanti -y 12 | RUN source /opt/ros/noetic/setup.bash && catkin_make 13 | 14 | USER vizanti 15 | # Launch Vizanti 16 | CMD source /home/vizanti/catkin_ws/devel/setup.bash && roslaunch vizanti server.launch -------------------------------------------------------------------------------- /launch/server.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | vizanti 3 | 0.1.0 4 | A mission planner and visualizer for controlling outdoor ROS robots. 5 | MoffKalast 6 | BSD 7 | 8 | MoffKalast 9 | rospy 10 | dynamic_reconfigure 11 | 12 | catkin 13 | actionlib_msgs 14 | geometry_msgs 15 | move_base_msgs 16 | std_msgs 17 | message_generation 18 | 19 | actionlib_msgs 20 | move_base_msgs 21 | std_msgs 22 | 23 | tf2_msgs 24 | message_runtime 25 | geometry_msgs 26 | actionlib_msgs 27 | move_base_msgs 28 | std_msgs 29 | python3-flask 30 | python3-waitress 31 | rosbridge_suite 32 | 33 | 34 | -------------------------------------------------------------------------------- /public/assets/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 49 | -------------------------------------------------------------------------------- /public/assets/altimeter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 86 | -------------------------------------------------------------------------------- /public/assets/altimeter_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 49 | -------------------------------------------------------------------------------- /public/assets/altimeter_arrow_green.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 49 | -------------------------------------------------------------------------------- /public/assets/altimeter_green.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 86 | -------------------------------------------------------------------------------- /public/assets/area.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 73 | -------------------------------------------------------------------------------- /public/assets/battery_100.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 70 | -------------------------------------------------------------------------------- /public/assets/battery_20.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 54 | -------------------------------------------------------------------------------- /public/assets/battery_20_charging.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 58 | -------------------------------------------------------------------------------- /public/assets/battery_40.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 58 | -------------------------------------------------------------------------------- /public/assets/battery_40_charging.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 61 | -------------------------------------------------------------------------------- /public/assets/battery_60.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 62 | -------------------------------------------------------------------------------- /public/assets/battery_60_charging.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 64 | -------------------------------------------------------------------------------- /public/assets/battery_80.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 66 | -------------------------------------------------------------------------------- /public/assets/battery_unknown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | 44 | 49 | 50 | 75 | -------------------------------------------------------------------------------- /public/assets/button.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | 26 | 27 | 28 | 29 | 48 | 53 | 54 | 65 | -------------------------------------------------------------------------------- /public/assets/button_false.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 21 | 22 | 23 | 24 | 43 | 48 | 49 | 57 | -------------------------------------------------------------------------------- /public/assets/button_true.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 21 | 22 | 23 | 24 | 43 | 48 | 49 | 57 | -------------------------------------------------------------------------------- /public/assets/default_layout.json: -------------------------------------------------------------------------------- 1 | { 2 | "navbar": [ 3 | { 4 | "type": "settings", 5 | "id": "settings_default" 6 | }, 7 | { 8 | "type": "rosbridge", 9 | "id": "rosbridge_default" 10 | }, 11 | { 12 | "type": "grid", 13 | "id": "grid_default" 14 | }, 15 | { 16 | "type": "tf", 17 | "id": "tf_default" 18 | } 19 | ], 20 | "view": { 21 | "center": { 22 | "x": 0, 23 | "y": 0 24 | }, 25 | "scale": 50 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /public/assets/dropdown_edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 49 | 53 | 57 | 58 | -------------------------------------------------------------------------------- /public/assets/dropdown_start.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 50 | -------------------------------------------------------------------------------- /public/assets/dropdown_stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 53 | -------------------------------------------------------------------------------- /public/assets/dropdown_z.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 41 | 42 | 61 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /public/assets/folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 83 | -------------------------------------------------------------------------------- /public/assets/icon/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/icon/152.png -------------------------------------------------------------------------------- /public/assets/icon/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/icon/16.png -------------------------------------------------------------------------------- /public/assets/icon/192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/icon/192.png -------------------------------------------------------------------------------- /public/assets/icon/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/icon/32.png -------------------------------------------------------------------------------- /public/assets/icon/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/icon/512.png -------------------------------------------------------------------------------- /public/assets/icon/96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/icon/96.png -------------------------------------------------------------------------------- /public/assets/icon/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Vizanti", 3 | "short_name": "Vizanti", 4 | "description": "A web-based visualization and control tool for outdoor robots running ROS.", 5 | "start_url": "/", 6 | "display": "fullscreen", 7 | "background_color": "#111111", 8 | "theme_color": "#111111", 9 | "orientation": "any", 10 | "icons": [ 11 | { 12 | "src": "192.png", 13 | "sizes": "192x192", 14 | "type": "image/png" 15 | }, 16 | { 17 | "src": "512.png", 18 | "sizes": "512x512", 19 | "type": "image/png" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /public/assets/icon/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/icon/preview.jpg -------------------------------------------------------------------------------- /public/assets/image.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 63 | -------------------------------------------------------------------------------- /public/assets/initialpose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/initialpose.png -------------------------------------------------------------------------------- /public/assets/initialpose.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 57 | -------------------------------------------------------------------------------- /public/assets/inspector.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 70 | -------------------------------------------------------------------------------- /public/assets/joystick.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 49 | 54 | 55 | 59 | 60 | 71 | -------------------------------------------------------------------------------- /public/assets/marker.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 52 | 55 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /public/assets/node_kill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 67 | -------------------------------------------------------------------------------- /public/assets/node_restart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 61 | -------------------------------------------------------------------------------- /public/assets/path.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 50 | -------------------------------------------------------------------------------- /public/assets/pose.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 51 | -------------------------------------------------------------------------------- /public/assets/posearray.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 66 | -------------------------------------------------------------------------------- /public/assets/posewithcovariancestamped.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 56 | -------------------------------------------------------------------------------- /public/assets/robot_model/_2wd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/robot_model/_2wd.png -------------------------------------------------------------------------------- /public/assets/robot_model/_4wd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/robot_model/_4wd.png -------------------------------------------------------------------------------- /public/assets/robot_model/_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/robot_model/_arrow.png -------------------------------------------------------------------------------- /public/assets/robot_model/_dog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/robot_model/_dog.png -------------------------------------------------------------------------------- /public/assets/robot_model/_hatchback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/robot_model/_hatchback.png -------------------------------------------------------------------------------- /public/assets/robot_model/_orca.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/robot_model/_orca.png -------------------------------------------------------------------------------- /public/assets/robot_model/_pancake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/robot_model/_pancake.png -------------------------------------------------------------------------------- /public/assets/robot_model/_rccar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/robot_model/_rccar.png -------------------------------------------------------------------------------- /public/assets/robot_model/_rov.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/robot_model/_rov.png -------------------------------------------------------------------------------- /public/assets/robot_model/_sandwich.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/robot_model/_sandwich.png -------------------------------------------------------------------------------- /public/assets/robot_model/_tortoise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/robot_model/_tortoise.png -------------------------------------------------------------------------------- /public/assets/robot_model/_tuna.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/robot_model/_tuna.png -------------------------------------------------------------------------------- /public/assets/rosbridge_connected.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 78 | -------------------------------------------------------------------------------- /public/assets/rosbridge_disconnected.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 78 | -------------------------------------------------------------------------------- /public/assets/rosbridge_reconnect.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 78 | -------------------------------------------------------------------------------- /public/assets/simplegoal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/simplegoal.png -------------------------------------------------------------------------------- /public/assets/simplegoal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 51 | -------------------------------------------------------------------------------- /public/assets/speedometer_dial.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 49 | 54 | 55 | 59 | 60 | 66 | -------------------------------------------------------------------------------- /public/assets/tf.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 75 | -------------------------------------------------------------------------------- /public/assets/tile_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/tile_error.png -------------------------------------------------------------------------------- /public/assets/tile_loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/assets/tile_loading.png -------------------------------------------------------------------------------- /public/assets/waypoints.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 39 | 44 | 45 | 66 | -------------------------------------------------------------------------------- /public/css/font/TRADEMARKS.txt: -------------------------------------------------------------------------------- 1 | Ubuntu and Canonical are registered trademarks of Canonical Ltd. 2 | 3 | The licence accompanying these works does not grant any rights 4 | under trademark law and all such rights are reserved. 5 | -------------------------------------------------------------------------------- /public/css/font/ubuntu.mono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/css/font/ubuntu.mono.ttf -------------------------------------------------------------------------------- /public/css/font/ubuntu.mono.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/css/font/ubuntu.mono.woff -------------------------------------------------------------------------------- /public/css/font/ubuntu.mono.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoffKalast/vizanti/9fedbbbcee8a92d9dfe35f7d72c3e998f2f2f1e1/public/css/font/ubuntu.mono.woff2 -------------------------------------------------------------------------------- /public/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Vizanti 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include "head.html" %} 5 | 6 | 7 | 8 | {% include "iconbar.html" %} 9 | 10 |
11 | 12 |
13 | 14 | 17 | 18 | 21 |
22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /public/js/lib/nipplejs_LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Yoann Moinet 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /public/js/lib/quaternionjs_LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Robert Eisele 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /public/js/lib/roslibjs_LICENSE.txt: -------------------------------------------------------------------------------- 1 | Software License Agreement (BSD License) 2 | 3 | Copyright (c) 2014, Worcester Polytechnic Institute, Robert Bosch 4 | LLC, Yujin Robot. All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions 8 | are met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above 13 | copyright notice, this list of conditions and the following 14 | disclaimer in the documentation and/or other materials provided 15 | with the distribution. 16 | * Neither the name of Worcester Polytechnic Institute, Robert 17 | Bosch LLC, Yujin Robot nor the names of its contributors may be 18 | used to endorse or promote products derived from this software 19 | without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /public/js/modules/database.js: -------------------------------------------------------------------------------- 1 | export class IndexedDatabase { 2 | constructor(storeName) { 3 | this.storeName = storeName; 4 | this.db = null; 5 | } 6 | 7 | async openDB() { 8 | return new Promise((resolve, reject) => { 9 | const request = indexedDB.open("vizantiDB", 1); 10 | 11 | request.onupgradeneeded = (event) => { 12 | const db = event.target.result; 13 | db.createObjectStore(this.storeName); 14 | }; 15 | 16 | request.onsuccess = (event) => { 17 | this.db = event.target.result; 18 | resolve(); 19 | }; 20 | 21 | request.onerror = (event) => { 22 | reject(event.error); 23 | }; 24 | }); 25 | } 26 | 27 | async keyExists(key) { 28 | return await this._performTransaction('readonly', (store) => { 29 | return store.getKey(key); 30 | }); 31 | } 32 | 33 | async setObject(key, value) { 34 | await this._performTransaction('readwrite', (store) => { 35 | store.put(value, key); 36 | }); 37 | } 38 | 39 | async getObject(key) { 40 | return await this._performTransaction('readonly', (store) => { 41 | return store.get(key); 42 | }); 43 | } 44 | 45 | async getAllKeys(){ 46 | return await this._performTransaction('readonly', (store) => { 47 | return store.getAllKeys(); 48 | }); 49 | } 50 | 51 | async _performTransaction(mode, operation) { 52 | return new Promise((resolve, reject) => { 53 | if (!this.db) { 54 | reject('IndexedDB not opened'); 55 | return; 56 | } 57 | 58 | const transaction = this.db.transaction(this.storeName, mode); 59 | const store = transaction.objectStore(this.storeName); 60 | 61 | const request = operation(store); 62 | if (request) { 63 | request.onsuccess = () => { 64 | resolve(request.result); 65 | }; 66 | } else { 67 | resolve(); 68 | } 69 | 70 | transaction.onerror = () => { 71 | reject(transaction.error); 72 | }; 73 | }); 74 | } 75 | } -------------------------------------------------------------------------------- /public/js/modules/elements.js: -------------------------------------------------------------------------------- 1 | import files from '../../templates/files'; 2 | 3 | async function loadElementTemplates() { 4 | let templates = {}; 5 | 6 | files.forEach(file => { 7 | const filePathParts = file.path.split('/'); 8 | const fileName = filePathParts[filePathParts.length - 1]; 9 | const [category, typeWithExtension] = fileName.split('_'); 10 | const type = typeWithExtension.split('.')[0]; 11 | 12 | if (!templates[category]) { 13 | templates[category] = {}; 14 | } 15 | 16 | templates[category][type] = file.content; 17 | }); 18 | 19 | console.table("Loaded templates:",templates) 20 | 21 | return templates; 22 | } 23 | 24 | export const elementTemplatesPromise = loadElementTemplates(); -------------------------------------------------------------------------------- /public/js/modules/joystick.js: -------------------------------------------------------------------------------- 1 | // Import nipplejs using the global window object 2 | import '../lib/nipplejs.js'; 3 | 4 | // Export the library as a named export 5 | export const nipplejs = window.nipplejs; 6 | 7 | // Clean up the global namespace by removing the library from the window object 8 | delete window.nipplejs; -------------------------------------------------------------------------------- /public/js/modules/persistent.js: -------------------------------------------------------------------------------- 1 | const defaultConfigModule = await import(`${base_url}/default_widget_config`); 2 | const default_config = defaultConfigModule.default; 3 | 4 | export function saveJsonToFile(data, filename) { 5 | const jsonData = JSON.stringify(data, null, 2); 6 | const blob = new Blob([jsonData], { type: 'application/json' }); 7 | const url = URL.createObjectURL(blob); 8 | 9 | const a = document.createElement('a'); 10 | a.href = url; 11 | a.download = filename; 12 | a.click(); 13 | 14 | URL.revokeObjectURL(url); 15 | } 16 | 17 | export class Settings { 18 | 19 | constructor() { 20 | if (localStorage.hasOwnProperty("settings")) { 21 | this.fromJSON(localStorage.getItem("settings")); 22 | }else{ 23 | this.fromJSON(default_config); 24 | } 25 | } 26 | 27 | fromJSON(settings_object){ 28 | let storedSettings = JSON.parse(settings_object); 29 | Object.assign(this, storedSettings); 30 | } 31 | 32 | save() { 33 | localStorage.setItem("settings", JSON.stringify(this)); 34 | } 35 | } 36 | 37 | export let settings = new Settings(); -------------------------------------------------------------------------------- /public/js/modules/status.js: -------------------------------------------------------------------------------- 1 | export class Status { 2 | constructor(icon_element, message_element) { 3 | this.icon = icon_element; 4 | this.message = message_element; 5 | 6 | this._pendingStatus = null; 7 | this._pendingMessage = null; 8 | this._lastStatus = null; 9 | this._lastMessage = null; 10 | 11 | this._updateInterval = setInterval(() => { 12 | if (!this.icon == null || !this.icon.isConnected || this.message == null || !this.message.isConnected) { 13 | clearInterval(this._updateInterval); 14 | return; 15 | } 16 | 17 | if (this._pendingStatus !== this._lastStatus || this._pendingMessage !== this._lastMessage) { 18 | this._applyStatus(this._pendingStatus, this._pendingMessage); 19 | this._lastStatus = this._pendingStatus; 20 | this._lastMessage = this._pendingMessage; 21 | } 22 | }, 200); 23 | } 24 | 25 | _applyStatus(status, message) { 26 | // Reset classes 27 | this.icon.classList.remove("icon-error", "icon-warn"); 28 | this.message.classList.remove("status-error", "status-warn"); 29 | 30 | // Apply new state 31 | switch (status) { 32 | case "ok": 33 | this.message.innerText = "Status: " + (message || "Ok"); 34 | break; 35 | case "warn": 36 | this.icon.classList.add("icon-warn"); 37 | this.message.classList.add("status-warn"); 38 | this.message.innerText = "Status: " + message; 39 | break; 40 | case "error": 41 | this.icon.classList.add("icon-error"); 42 | this.message.classList.add("status-error"); 43 | this.message.innerText = "Status: " + message; 44 | break; 45 | } 46 | } 47 | 48 | async setOK(message) { 49 | this._pendingStatus = "ok"; 50 | this._pendingMessage = message; 51 | } 52 | 53 | async setWarn(message) { 54 | this._pendingStatus = "warn"; 55 | this._pendingMessage = message; 56 | } 57 | 58 | async setError(message) { 59 | this._pendingStatus = "error"; 60 | this._pendingMessage = message; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /public/templates/add/add_icon.html: -------------------------------------------------------------------------------- 1 |
2 | + 3 |
-------------------------------------------------------------------------------- /public/templates/add/add_script.js: -------------------------------------------------------------------------------- 1 | let rosbridgeModule = await import(`${base_url}/js/modules/rosbridge.js`); 2 | 3 | let rosbridge = rosbridgeModule.rosbridge; 4 | 5 | const typeButton = document.getElementById('add_set_type'); 6 | const topicButton = document.getElementById('add_set_topics'); 7 | 8 | const topicDiv = document.getElementById('add_topics_container'); 9 | const typeDiv = document.getElementById('add_types_container'); 10 | 11 | let types = {}; 12 | 13 | //gather the cards 14 | const widgets = typeDiv.children; 15 | for (let i = 0; i < widgets.length; i++) { 16 | let topics = widgets[i].dataset.topic; 17 | if(topics !== undefined){ 18 | topics.split(",").forEach(topic => { 19 | if(topic !== undefined){ 20 | if(topic in types){ 21 | types[topic].push(widgets[i]); 22 | }else{ 23 | types[topic] = [widgets[i]]; 24 | } 25 | } 26 | }); 27 | } 28 | } 29 | 30 | //tabs swapping 31 | typeButton.addEventListener("click", (event) => { 32 | topicButton.classList.remove("active_tab"); 33 | typeButton.classList.add("active_tab"); 34 | 35 | typeDiv.style.display = "block"; 36 | topicDiv.style.display = "none"; 37 | }); 38 | 39 | topicButton.addEventListener("click", (event) => { 40 | update_topics(); 41 | typeButton.classList.remove("active_tab"); 42 | topicButton.classList.add("active_tab"); 43 | 44 | typeDiv.style.display = "none"; 45 | topicDiv.style.display = "block"; 46 | }); 47 | 48 | // rebuild topic list 49 | async function update_topics(){ 50 | let result = await rosbridge.get_all_topics(); 51 | 52 | topicDiv.innerHTML = ""; 53 | for (let i = 0; i < result.types.length; i++) { 54 | let type = result.types[i]; 55 | if(type in types){ 56 | types[type].forEach(element => { 57 | let newnode = element.cloneNode(true); 58 | let title = newnode.querySelector('.card_title'); 59 | let desc = newnode.querySelector('.card_desc'); 60 | 61 | newnode.setAttribute('onclick', newnode.getAttribute("onclick").replace(",\'\')",",\'"+result.topics[i]+"\')")); 62 | 63 | desc.innerText = title.innerText + " ["+type + "]"; 64 | title.innerText = result.topics[i]; 65 | topicDiv.appendChild(newnode); 66 | }); 67 | } 68 | } 69 | } 70 | 71 | 72 | update_topics(); 73 | 74 | console.log("Add Widgets Loaded."); -------------------------------------------------------------------------------- /public/templates/altimeter/altimeter_icon.html: -------------------------------------------------------------------------------- 1 |
2 | ? 3 |
-------------------------------------------------------------------------------- /public/templates/altimeter/altimeter_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/altimeter/altimeter_view.html: -------------------------------------------------------------------------------- 1 | ? 2 | 3 | -------------------------------------------------------------------------------- /public/templates/area/area_icon.html: -------------------------------------------------------------------------------- 1 |
2 | model 3 |
-------------------------------------------------------------------------------- /public/templates/area/area_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/area/area_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/battery/battery_icon.html: -------------------------------------------------------------------------------- 1 |
2 | ? 3 |
-------------------------------------------------------------------------------- /public/templates/battery/battery_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/button/button_icon.html: -------------------------------------------------------------------------------- 1 |
2 | ? 3 |

Text

4 |
-------------------------------------------------------------------------------- /public/templates/button/button_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/compressedimage/compressedimage_icon.html: -------------------------------------------------------------------------------- 1 |
2 | model 3 |
-------------------------------------------------------------------------------- /public/templates/compressedimage/compressedimage_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/compressedimage/compressedimage_view.html: -------------------------------------------------------------------------------- 1 | {uniqueID}_compresedimg -------------------------------------------------------------------------------- /public/templates/folder/folder_icon.html: -------------------------------------------------------------------------------- 1 |
2 | ? 3 | 4 | 5 |
-------------------------------------------------------------------------------- /public/templates/folder/folder_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/grid/grid_icon.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /public/templates/grid/grid_modal.html: -------------------------------------------------------------------------------- 1 | 64 | -------------------------------------------------------------------------------- /public/templates/grid/grid_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/gridcells/gridcells_icon.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /public/templates/gridcells/gridcells_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/gridcells/gridcells_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/initialpose/initialpose_icon.html: -------------------------------------------------------------------------------- 1 |
2 | model 3 |
-------------------------------------------------------------------------------- /public/templates/initialpose/initialpose_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/initialpose/initialpose_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/inspector/inspector_icon.html: -------------------------------------------------------------------------------- 1 |
2 | ? 3 |
-------------------------------------------------------------------------------- /public/templates/inspector/inspector_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/map/map_icon.html: -------------------------------------------------------------------------------- 1 |
2 | model 3 |
-------------------------------------------------------------------------------- /public/templates/map/map_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/map/map_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/markerarray/markerarray_icon.html: -------------------------------------------------------------------------------- 1 |
2 | model 3 |
-------------------------------------------------------------------------------- /public/templates/markerarray/markerarray_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/markerarray/markerarray_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/nodemgr/nodemgr_icon.html: -------------------------------------------------------------------------------- 1 |
2 | ? 3 |
-------------------------------------------------------------------------------- /public/templates/nodemgr/nodemgr_modal.html: -------------------------------------------------------------------------------- 1 | 59 | 60 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /public/templates/odom/odom_icon.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /public/templates/odom/odom_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/odom/odom_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/path/path_icon.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /public/templates/path/path_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/path/path_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/pointcloud/pointcloud_icon.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /public/templates/pointcloud/pointcloud_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/pointcloud/pointcloud_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/posearray/posearray_icon.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /public/templates/posearray/posearray_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/posearray/posearray_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/posewithcovariancestamped/posewithcovariancestamped_icon.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /public/templates/posewithcovariancestamped/posewithcovariancestamped_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/posewithcovariancestamped/posewithcovariancestamped_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/range/range_icon.html: -------------------------------------------------------------------------------- 1 |
2 | model 3 |
-------------------------------------------------------------------------------- /public/templates/range/range_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/range/range_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/reconfigure/reconfigure_icon.html: -------------------------------------------------------------------------------- 1 |
2 | Reconfigure 3 |
-------------------------------------------------------------------------------- /public/templates/reconfigure/reconfigure_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/robotmodel/robotmodel_icon.html: -------------------------------------------------------------------------------- 1 |
2 | model 3 |
-------------------------------------------------------------------------------- /public/templates/robotmodel/robotmodel_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/robotmodel/robotmodel_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/rosbag/rosbag_icon.html: -------------------------------------------------------------------------------- 1 |
2 | ? 3 |
-------------------------------------------------------------------------------- /public/templates/rosbag/rosbag_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/rosbridge/rosbridge_icon.html: -------------------------------------------------------------------------------- 1 |
2 | Rosbridge 3 |
4 | 5 | -------------------------------------------------------------------------------- /public/templates/rosbridge/rosbridge_modal.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /public/templates/rosbridge/rosbridge_script.js: -------------------------------------------------------------------------------- 1 | let rosbridgeModule = await import(`${base_url}/js/modules/rosbridge.js`); 2 | let utilModule = await import(`${base_url}/js/modules/util.js`); 3 | let StatusModule = await import(`${base_url}/js/modules/status.js`); 4 | 5 | let rosbridge = rosbridgeModule.rosbridge; 6 | let imageToDataURL = utilModule.imageToDataURL; 7 | let Status = StatusModule.Status; 8 | 9 | let status = new Status( 10 | document.getElementById("{uniqueID}_icon"), 11 | document.getElementById("{uniqueID}_status") 12 | ); 13 | 14 | let url = document.getElementById("{uniqueID}_url"); 15 | let icon = document.getElementById("{uniqueID}_icon").getElementsByTagName('img')[0]; 16 | 17 | let button_reload = document.getElementById("{uniqueID}_reload"); 18 | button_reload.addEventListener("click", (event) => { 19 | location.reload(false); 20 | }); 21 | 22 | // can't show images about reconnecting without preloading them before we lose connection 23 | let img_reconnect = await imageToDataURL('assets/rosbridge_reconnect.svg'); 24 | let img_connect = await imageToDataURL('assets/rosbridge_connected.svg'); 25 | let img_disconnect = await imageToDataURL('assets/rosbridge_disconnected.svg'); 26 | 27 | function update_gui(){ 28 | url.innerText = "Bridge URL: ws://"+rosbridge.url + ":"+rosbridge.port; 29 | 30 | switch (rosbridge.status) { 31 | case "Reconnecting...": 32 | icon.src = img_reconnect; 33 | status.setError(rosbridge.status); 34 | break; 35 | case "Connecting...": 36 | icon.src = img_connect; 37 | status.setWarn(rosbridge.status); 38 | break; 39 | case 'Connection lost.': 40 | case 'Failed to connect.': 41 | icon.src = img_disconnect; 42 | status.setError(rosbridge.status); 43 | break; 44 | default: 45 | icon.src = img_connect; 46 | status.setOK(rosbridge.status); 47 | } 48 | } 49 | 50 | window.addEventListener("rosbridge_change", function(event){ 51 | update_gui(); 52 | }); 53 | 54 | update_gui(); -------------------------------------------------------------------------------- /public/templates/satelite/satelite_icon.html: -------------------------------------------------------------------------------- 1 |
2 | model 3 |
-------------------------------------------------------------------------------- /public/templates/satelite/satelite_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/satelite/satelite_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/scan/scan_icon.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /public/templates/scan/scan_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/scan/scan_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/settings/settings_icon.html: -------------------------------------------------------------------------------- 1 |
2 | Settings 3 |
-------------------------------------------------------------------------------- /public/templates/settings/settings_modal.html: -------------------------------------------------------------------------------- 1 | 43 | -------------------------------------------------------------------------------- /public/templates/simplegoal/simplegoal_icon.html: -------------------------------------------------------------------------------- 1 |
2 | model 3 |
-------------------------------------------------------------------------------- /public/templates/simplegoal/simplegoal_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/simplegoal/simplegoal_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/speedometer/speedometer_icon.html: -------------------------------------------------------------------------------- 1 |
2 | ? 3 | ? 4 |

0.000

5 |

m/s

6 |
-------------------------------------------------------------------------------- /public/templates/speedometer/speedometer_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/teleop/teleop_icon.html: -------------------------------------------------------------------------------- 1 |
2 | Teleop 3 |
-------------------------------------------------------------------------------- /public/templates/teleop/teleop_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/teleop/teleop_view.html: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /public/templates/temperature/temperature_icon.html: -------------------------------------------------------------------------------- 1 |
2 | ? 3 |
-------------------------------------------------------------------------------- /public/templates/temperature/temperature_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/tf/tf_icon.html: -------------------------------------------------------------------------------- 1 |
2 | tf 3 |
-------------------------------------------------------------------------------- /public/templates/tf/tf_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/tf/tf_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/waypoints/waypoints_icon.html: -------------------------------------------------------------------------------- 1 |
2 | model 3 |

4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /public/templates/waypoints/waypoints_modal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/templates/waypoints/waypoints_view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scripts/test/_test_button.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import rospy 4 | from std_srvs.srv import Empty, EmptyResponse 5 | from std_srvs.srv import Trigger, TriggerResponse 6 | from std_srvs.srv import SetBool, SetBoolResponse 7 | from std_msgs.msg import Bool 8 | 9 | class TestServiceNode: 10 | def __init__(self): 11 | rospy.init_node('test_service_node') 12 | 13 | # Initialize toggle states 14 | self.empty_state = False 15 | self.trigger_state = False 16 | self.setbool_state = False 17 | 18 | # Publishers with latch=True 19 | self.empty_pub = rospy.Publisher('/empty_triggered', Bool, latch=True, queue_size=1) 20 | self.trigger_pub = rospy.Publisher('/trigger_triggered', Bool, latch=True, queue_size=1) 21 | self.setbool_pub = rospy.Publisher('/setbool_triggered', Bool, latch=True, queue_size=1) 22 | 23 | # Initial publish so topics have a latched message 24 | self.empty_pub.publish(self.empty_state) 25 | self.trigger_pub.publish(self.trigger_state) 26 | self.setbool_pub.publish(self.setbool_state) 27 | 28 | # Service servers 29 | self.empty_srv = rospy.Service('/test_empty', Empty, self.handle_empty) 30 | self.trigger_srv = rospy.Service('/test_trigger', Trigger, self.handle_trigger) 31 | self.setbool_srv = rospy.Service('/test_setbool', SetBool, self.handle_setbool) 32 | 33 | rospy.loginfo("Test service node ready.") 34 | rospy.spin() 35 | 36 | def handle_empty(self, req): 37 | self.empty_state = not self.empty_state 38 | self.empty_pub.publish(self.empty_state) 39 | rospy.loginfo("Empty service triggered, state: %s", self.empty_state) 40 | return EmptyResponse() 41 | 42 | def handle_trigger(self, req): 43 | self.trigger_state = not self.trigger_state 44 | self.trigger_pub.publish(self.trigger_state) 45 | rospy.loginfo("Trigger service triggered, state: %s", self.trigger_state) 46 | return TriggerResponse(success=True, message="Trigger service called") 47 | 48 | def handle_setbool(self, req): 49 | self.setbool_state = req.data 50 | self.setbool_pub.publish(self.setbool_state) 51 | rospy.loginfo("SetBool service triggered, state: %s", self.setbool_state) 52 | return SetBoolResponse(success=True, message="SetBool service called") 53 | 54 | if __name__ == '__main__': 55 | try: 56 | TestServiceNode() 57 | except rospy.ROSInterruptException: 58 | pass 59 | 60 | -------------------------------------------------------------------------------- /scripts/topic_handler.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import rospy 4 | import time 5 | import threading 6 | 7 | from rospy.exceptions import ROSTimeMovedBackwardsException 8 | from tf2_msgs.msg import TFMessage 9 | 10 | class TopicHandler: 11 | 12 | def __init__(self): 13 | rospy.init_node('vizanti_topic_handler') 14 | 15 | self.updated = False 16 | self.lock = threading.Lock() 17 | self.transforms = {} 18 | 19 | self.transform_timeout = {} 20 | self.timeout_prescaler = 0 21 | 22 | self.tf_sub = rospy.Subscriber('/tf', TFMessage, self.tf_callback) 23 | self.tf_pub = rospy.Publisher('/vizanti/tf_consolidated', TFMessage, queue_size=1, latch=True) 24 | 25 | rospy.loginfo("TF handler ready.") 26 | 27 | def clear_old_tfs(self): 28 | with self.lock: 29 | for key in list(self.transforms.keys()): 30 | if time.time() - self.transform_timeout[key] > 10.0: 31 | parent = self.transforms[key].header.frame_id 32 | del self.transforms[key] 33 | del self.transform_timeout[key] 34 | self.updated = True 35 | rospy.logwarn("Deleted old TF link: "+str(parent)+" -> "+str(key)) 36 | 37 | def publish(self): 38 | # 150 /30 hz = once per 5 seconds 39 | self.timeout_prescaler = (self.timeout_prescaler + 1) % 150 40 | if self.timeout_prescaler == 0: 41 | self.clear_old_tfs() 42 | 43 | if not self.updated: 44 | return 45 | 46 | msg = TFMessage() 47 | with self.lock: 48 | msg.transforms = list(self.transforms.values()) 49 | self.updated = False 50 | 51 | self.tf_pub.publish(msg) 52 | 53 | def tf_callback(self, msg): 54 | with self.lock: 55 | for transform in msg.transforms: 56 | self.transforms[transform.child_frame_id] = transform 57 | self.transform_timeout[transform.child_frame_id] = time.time() 58 | self.updated = True 59 | 60 | 61 | odr = TopicHandler() 62 | rate = rospy.Rate(30) 63 | while not rospy.is_shutdown(): 64 | try: 65 | odr.publish() 66 | rate.sleep() 67 | except ROSTimeMovedBackwardsException as e: 68 | print(e) -------------------------------------------------------------------------------- /srv/GetNodeParameters.srv: -------------------------------------------------------------------------------- 1 | string node 2 | --- 3 | string parameters -------------------------------------------------------------------------------- /srv/ListExecutables.srv: -------------------------------------------------------------------------------- 1 | string package 2 | --- 3 | string[] executables 4 | -------------------------------------------------------------------------------- /srv/ListPackages.srv: -------------------------------------------------------------------------------- 1 | --- 2 | string[] packages 3 | -------------------------------------------------------------------------------- /srv/LoadMap.srv: -------------------------------------------------------------------------------- 1 | string file_path 2 | string topic 3 | --- 4 | bool success 5 | string message -------------------------------------------------------------------------------- /srv/ManageNode.srv: -------------------------------------------------------------------------------- 1 | string node 2 | --- 3 | bool success 4 | string message -------------------------------------------------------------------------------- /srv/RecordRosbag.srv: -------------------------------------------------------------------------------- 1 | string[] topics 2 | bool start 3 | string path 4 | --- 5 | bool success 6 | string message 7 | -------------------------------------------------------------------------------- /srv/SaveMap.srv: -------------------------------------------------------------------------------- 1 | string file_path 2 | string topic 3 | --- 4 | bool success 5 | string message --------------------------------------------------------------------------------