apriltag localization
A simple web interface for ROS can be fully practiced after the following tutorials. The rest of the content will be based on these tutorials and give instruction on how to construct this specific webpage for apriltag localization along with what can be improved and be done.
The system's foundation is rosbridge_suite package. It provides a simple method to setup a server on the robot and perform communication through a predefined protocol with a web client under a local network.
Ref: rosbridge_suite
Server:
Client & Server Communication:
โโโโโโโโpython -m SimpleHTTPServer
Head(Libraries): roslibjs, mjpegcanvas, bootstrap, vue.js
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Control Panel</title>
<script type="text/javascript" src="http://static.robotwebtools.org/roslibjs/current/roslib.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/eventemitter2@5.0.1/lib/eventemitter2.min.js"></script>
<script type="text/javascript" src="https://static.robotwebtools.org/mjpegcanvasjs/current/mjpegcanvas.min.js"></script>
</head>
Body:
User can redirect to different pages with navigation bar. The link of the button can be set with href in attribute tag. Note that with SimpleHTTPServer, only a single page can be created. If multiple pages needed to be setup, you can use FLASK to setup multiple web ip addresses.
โโโโ <div>
โโโโ <nav class="navbar navbar-expand-lg navbar-dark bg-secondary text-white">
โโโโ <a class="navbar-brand" href="#">NCRL</a>
โโโโ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
โโโโ <span class="navbar-toggler-icon"></span>
โโโโ </button>
โโโโ <div class="collapse navbar-collapse" id="navbarSupportedContent">
โโโโ <ul class="navbar-nav mr-auto">
โโโโ <li class="nav-item active">
โโโโ <a class="nav-link" href="http://127.0.0.1:5000/">Home<span class="sr-only">(current)</span></a>
โโโโ </div>
โโโโ </nav>
โโโโ </div>
jumbotron class can create a block with background, bg-(color) and text-(color) can change background and text color respectively. As for the supported color, you can check bootstrap4 tutorials on this website.
โโโโ<div style="padding-top:55px; margin-bottom:20px; padding-bottom:35px;" class="jumbotron jumbotron-fluid bg-info text-white">
โโโโ <h1 style="padding-bottom:20px;" class="text-center display-3"> NCRL Apriltag Localization </h1>
โโโโ <p class="text-center display-8">This is a web control interface for NCRL Apriltag Localization Project.</p>
โโโโ</div>
Layout can be created by setting rows and columns. The total number of columns in a single row is 12.
โโโโ<div class="col-2 jumbotron" style="padding-bottom:2rem; padding-top:1rem; padding-right:1rem; padding-left:1rem; margin-right:1rem;">
โโโโ <h3>Connection status</h3>
โโโโ <p class="text-muted" v-if="!connected && !failure">Not Connected</p>
โโโโ <p class="text-danger" v-if="failure">Error</p>
โโโโ <p class="text-success" v-if="connected">Connected</p>
โโโโ <label for="uav_server">UAV_server: </label><br/>
โโโโ <input id="uav_server" type="text" v-model="ws_address"/><br/>
โโโโ <button class="btn btn-danger" style="margin-top:10px; margin-bottom:10px;" @click="disconnect" v-if="connected">Disconnect</button>
โโโโ <button class="btn btn-success" style="margin-top:10px; margin-bottom:10px;" @click="connect" v-if="!connected">Connect</button>
โโโโ</div>
If the corresponding variable in javascriptis true, then the html line will be available. Otherwise, it'll be commented.
When the button is pressed, then the function in method in javascript will be triggered.
When a value is given to an input tag, the value will also be assigned to the corresponding variable in javascript.
Load main.js in GUI.html's body
โโโโ<script type="text/javascript" src="main.js"></script>
Creat a vue object in main.js
โโโโvar app = new Vue({
โโโโ el:'#[id]',
โโโโ data: {
โโโโ test_var: 'test',
โโโโ },
โโโโ methods: {
โโโโ test: function(){
โโโโ console.log(this.test_var)
โโโโ }
โโโโ },
โโโโ updated(){
โโโโ },
โโโโ})
El correspond to the id of the division you want the vue object to link to. In our case, it is linked to the 'control_gui' div. Data is the section where you can declare class variables. In methods, you can define functions that can be triggered from the html file. In updated, the lines will be executed once the html(webpage) has any modification. For instance, to implement the function of enabling a button when the input is given, the underlying code should be written in updated. There are other built-in for Vue.js to use beside el, data, methods and updated that you can find in tutorials.
Streaming video
showCamera: function(){
console.log('set camera method')
this.cameraViewer = new MJPEGCANVAS.Viewer({
divID: 'mjpeg',
host: '0.0.0.0',
width: 640,
height: 480,
topic: '/iris1/camera_forward/color/image_raw',
port: 8080,
})
// Create a control signal publisher: take off 1, return 2, stop 0
this.control_pub = new ROSLIB.Topic({
ros: this.ros,
name: '/control_phase',
messageType: 'std_msgs/Int8'
});
this.control_signal = new ROSLIB.Message({
data: 0
})
this.control_pub.publish(this.control_signal)
this.location_sub = new ROSLIB.Topic({
ros: this.ros,
name: '/location',
messageType: 'std_msgs/Int8'
})
this.location_sub.subscribe(function(message){
document.getElementById("uav_location").innerHTML = message.data;
})
Function in subscribe cannot modify class variable in Vue??
sudo apt-get install ros-melodic-rosbridge-server
sudo apt-get install ros-melodic-web-video-server
<launch>
<include file="$(find rosbridge_server)/launch/rosbridge_websocket.launch">
<arg name="port" value="9090"/>
</include>
<node name="web_video_server1" pkg="web_video_server" type="web_video_server">
<param name="port" type="int" value="8080" />
<param name="address" type="string" value="0.0.0.0" />
<param name="server_threads" type="int" value="1" />
<param name="ros_threads" type="string" value="2" />
<param name="width" type="int" value="1080" />
<param name="height" type="int" value="720" />
<param name="quality" type="int" value="90" />
</node>
</launch>
take off: 1, return: 2, stop: 0
Tag ID
Launch
Connection
https://drive.google.com/file/d/1k9Bsl7ri-q1ngy1nkoERPu9QAObmdXtr/view?usp=sharing
Control Panel
Take off will be enabled
Return & Land will be enabled
Kill will be enabled (not implemented yet)
Land will be enabled
Take off will be enabled
Not implemented yet, NCRL controller doesn't support height command
Not implemented yet
Not implemented yet
Land & Return will be enabled
Start will be enabled once the input destination is typed
Green: not in the middle of mission
Red: In the middle of a mission (Not suggested to send command(control panel is not protected))