From 4e14f6ee5f1de7a24a636661c1689c46f2dd024b Mon Sep 17 00:00:00 2001 From: Fernando Herrero <fherrero@iri.upc.edu> Date: Mon, 25 Oct 2021 16:58:14 +0200 Subject: [PATCH] Devel --- .gitmodules | 3 + config/goals.yaml | 18 +++ html/data/goals0.yaml | 18 +++ html/data/goals1.yaml | 18 +++ html/data/goals2.yaml | 18 +++ html/images/carnet.png | Bin 0 -> 16578 bytes html/index.html | 346 +++++++++++++++++++++++++++++++++++++---- html/js-yaml | 1 + html/map.html | 4 +- html/style.css | 2 +- html/timer.js | 58 ++++--- 11 files changed, 427 insertions(+), 59 deletions(-) create mode 100644 .gitmodules create mode 100644 config/goals.yaml create mode 100644 html/data/goals0.yaml create mode 100644 html/data/goals1.yaml create mode 100644 html/data/goals2.yaml create mode 100644 html/images/carnet.png create mode 160000 html/js-yaml diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..57cdbad --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "html/js-yaml"] + path = html/js-yaml + url = https://github.com/nodeca/js-yaml.git diff --git a/config/goals.yaml b/config/goals.yaml new file mode 100644 index 0000000..30b1c15 --- /dev/null +++ b/config/goals.yaml @@ -0,0 +1,18 @@ +goals: + - id: goal1 + x: 8.2 + y: 6.0 + yaw: 1.5709 + type: 0 + + - id: goal2 + x: -1.3 + y: 6.0 + yaw: -1.5709 + type: 1 + + - id: goal3 + x: -0.2 + y: -0.2 + yaw: 0.0 + type: 2 diff --git a/html/data/goals0.yaml b/html/data/goals0.yaml new file mode 100644 index 0000000..d4a1753 --- /dev/null +++ b/html/data/goals0.yaml @@ -0,0 +1,18 @@ +goals: + - id: goal1 + x: 1.0 + y: 0.22 + yaw: 0.0 + type: 0 + + - id: goal2 + x: 2.0 + y: 0.22 + yaw: 0.0 + type: 1 + + - id: goal3 + x: 3.0 + y: -0.22 + yaw: 3.14159 + type: 2 diff --git a/html/data/goals1.yaml b/html/data/goals1.yaml new file mode 100644 index 0000000..d4a1753 --- /dev/null +++ b/html/data/goals1.yaml @@ -0,0 +1,18 @@ +goals: + - id: goal1 + x: 1.0 + y: 0.22 + yaw: 0.0 + type: 0 + + - id: goal2 + x: 2.0 + y: 0.22 + yaw: 0.0 + type: 1 + + - id: goal3 + x: 3.0 + y: -0.22 + yaw: 3.14159 + type: 2 diff --git a/html/data/goals2.yaml b/html/data/goals2.yaml new file mode 100644 index 0000000..d4a1753 --- /dev/null +++ b/html/data/goals2.yaml @@ -0,0 +1,18 @@ +goals: + - id: goal1 + x: 1.0 + y: 0.22 + yaw: 0.0 + type: 0 + + - id: goal2 + x: 2.0 + y: 0.22 + yaw: 0.0 + type: 1 + + - id: goal3 + x: 3.0 + y: -0.22 + yaw: 3.14159 + type: 2 diff --git a/html/images/carnet.png b/html/images/carnet.png new file mode 100644 index 0000000000000000000000000000000000000000..9c7b37270a99b2fafd5b3193e87502d16d580e8f GIT binary patch literal 16578 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 literal 0 HcmV?d00001 diff --git a/html/index.html b/html/index.html index c300af0..ad61240 100644 --- a/html/index.html +++ b/html/index.html @@ -16,30 +16,59 @@ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script> <script src="timer.js"></script> + <script src="./js-yaml/dist/js-yaml.min.js"></script> <link rel="stylesheet" href="style.css"> <script> - document.title="index"; + document.title="ADC GUI"; var ip; ip = document.domain; //ip = window.location.hostname //ip = prompt("Enter server ip address", "192.168.100.219"); + ////////////////////////////////////// + ///ROS var ros = new ROSLIB.Ros(); ros.connect('ws://'+ip+':9090'); + + var goals_param = new ROSLIB.Param({ + ros : ros, + name : '/goals' + }); + + var adc_jury_service_client = new ROSLIB.Service({ + ros : ros, + name : '/jury_mode', + serviceType : 'iri_adc_msgs/jury_mode' + }); + + var srv_request = new ROSLIB.ServiceRequest({ + enable : false + }); + + var adc_jury_client = new ROSLIB.ActionClient({ + ros : ros, + serverName : '/adc_jury', + actionName : 'iri_adc_msgs/adc_juryAction' + }); + + var goal_array_msg = new ROSLIB.Message( + { + }); var team; var challenge; var feedback_text=""; + var last_feedback_line=""; var i=0; - - - //console.log("team=",team); - //localStorage.setItem('team', team); - - //console.log("set team var"); - //console.log("get team: "+localStorage.getItem('team')); + var service_answered=false; + var service_ok=false; + var received_feedback=false; + var feedback_timer; + var jury_mode_running=false; + var action_running=false; + var goals_loaded=false; function update_team() { @@ -53,18 +82,240 @@ localStorage.setItem('challenge', challenge); } - function add_feedback() + function send_goal() { - feedback_new_line='This is a feedback text example '+i; - feedback_text = feedback_new_line + '\ ' + feedback_text ; - i=i+1; + //load_goals_from_yaml(); //TODO: sync load. Now is async and done on input.onchange and at the beginning + + init_goal_msg(); + + action_goal.send(); + + document.getElementById("action_info").innerHTML = "Goal sent. Expecting feedback..."; + document.getElementById("action_info").style.backgroundColor = 'white' ; + + feedback_watchdog_timer(); + //action_running=true; //true when received feedback? + } + + function init_goal_msg() + { + action_goal = new ROSLIB.Goal( + { + actionClient : adc_jury_client, + goalMessage : goal_array_msg + } + ); + + action_goal.on('feedback', function(msg) + { + received_feedback=true; + action_running=true; + document.getElementById("action_info").innerHTML = "Feedback received!"; + document.getElementById("action_info").style.backgroundColor = 'green' ; + var feedback_new_line= msg.status; + add_feedback_line(feedback_new_line); + }); + + action_goal.on('result', function(result) + { + if(action_running) + { + finish_action(); + } + }); + + } + + function finish_action() + { + if(timer_running) + startStop(); + document.getElementById("action_info").innerHTML = "Action finished"; + document.getElementById("action_info").style.backgroundColor = 'white' ; + action_running=false; + clearTimeout(feedback_timer); + add_feedback_line("Finished"); + } + + function cancel_goal() + { + action_goal.cancel(); + document.getElementById("action_info").innerHTML = "Goal cancelled"; + document.getElementById("action_info").style.backgroundColor = 'white' ; + } + + function jury_mode() + { + if(!jury_mode_running) + jury_mode_enable(); + else + jury_mode_disable(); + } + + function jury_mode_enable() + { + document.getElementById("service_info").innerHTML = "Called service, waiting response..."; + document.getElementById("service_info").style.backgroundColor = 'yellow' ; + document.getElementById('jury_mode_button').disabled=true; + srv_request.enable=true; + adc_jury_service_client.callService(srv_request, + function(result) + { + service_answered=true; + service_ok=true; + jury_mode_answered(); + }, + function(result) + { + service_answered=true; + service_ok=false; + jury_mode_answered(); + }); + } + + function jury_mode_disable() + { + document.getElementById("service_info").innerHTML = "Called service server, waiting response..."; + document.getElementById("service_info").style.backgroundColor = 'yellow' ; + document.getElementById('jury_mode_button').disabled=true; + srv_request.enable=false; + adc_jury_service_client.callService(srv_request, + function(result) + { + service_answered=true; + service_ok=true; + jury_mode_answered(); + }, + function(result) + { + service_answered=true; + service_ok=false; + jury_mode_answered(); + }); + } + + function jury_mode_answered() + { + document.getElementById('jury_mode_button').disabled=false; + if(service_ok) + { + service_ok=false; + document.getElementById("service_info").innerHTML = "Service responded"; + document.getElementById("service_info").style.backgroundColor = 'green' ; + if(!jury_mode_running) + { + add_feedback_line("Jury mode enabled"); + jury_mode_running = true; + document.getElementById("jury_mode_button").innerHTML = "DISABLE"; + document.getElementById('jury_mode_button').style.backgroundColor="Red"; + if(document.getElementById("startStop").innerHTML=="START") + document.getElementById('startStop').disabled=true; + } + else + { + add_feedback_line("Jury mode disabled"); + jury_mode_running = false; + document.getElementById("jury_mode_button").innerHTML = "ENABLE"; + document.getElementById('jury_mode_button').style.backgroundColor="RoyalBlue"; + if(document.getElementById("startStop").innerHTML=="START") + document.getElementById('startStop').disabled=false; + } + } + else + { + document.getElementById("service_info").innerHTML = "ERROR: couldn't contact service server!!!"; + document.getElementById("service_info").style.backgroundColor = 'red' ; + console.log("ERROR: couldn't contact service server!!!"); + } + } + + // function add_fake_feedback() + // { + // feedback_new_line=document.getElementById("fake_feedback_text").value+" "+i; + // i=i+1; + // add_feedback_line(feedback_new_line); + // } + + function add_feedback_line(text) + { + if(text!=last_feedback_line) + { +// var currentTime = new Date(); +// var secs = Math.floor(currentTime.getTime()/1000); +// var nsecs = Math.round(1000000000*(currentTime.getTime()/1000-secs)); +// var time = "["+secs+","+nsecs+"]: "; + var time = "[" + time_string + "]: "; + + feedback_text = time + text + '
' + feedback_text ; + document.getElementById("feedback_text").innerHTML = feedback_text; + } + last_feedback_line=text; + } + + function clear_feedback() + { + feedback_text=""; + last_feedback_line=""; + i=0; document.getElementById("feedback_text").innerHTML = feedback_text; } + + function feedback_watchdog_timer() + { + feedback_timer = setTimeout( + function() + { + if(action_running) + { + if(received_feedback) + { + received_feedback=false; + document.getElementById("action_info").innerHTML = "Feedback received!"; + document.getElementById("action_info").style.backgroundColor = 'green' ; + feedback_watchdog_timer(); + } + else + { + //clearTimeout(feedback_timer); + console.log("ERROR: feedback not received!"); + document.getElementById("action_info").innerHTML = "ERROR: feedback NOT received!"; + document.getElementById("action_info").style.backgroundColor = 'red' ; + //TODO: what to do then? + feedback_watchdog_timer(); + } + } + },2000); + } + + function load_goals_from_yaml() + { + goals_file = document.getElementById("goals_file").value; + var goals_from_yaml; + + $.get(goals_file).done(function (data) + //$.get( goals_file, function( data ) + { + goals_from_yaml = jsyaml.load( data ); + + //TODO: check if loaded succesfully or not + //console.log("Loaded goals"); + + goal_array_msg = new ROSLIB.Message( + { + goals: goals_from_yaml + }); + + goals_loaded=true; + + }); + } $(document).ready ( function () { + load_goals_from_yaml(); + if ("team" in localStorage) { team = localStorage.getItem('team'); @@ -73,6 +324,7 @@ else { team=1; + localStorage.setItem('team', team); } if ("challenge" in localStorage) @@ -83,22 +335,22 @@ else { challenge=1; + localStorage.setItem('challenge', challenge); } - - } ); </script> </head> + <body> <style>body { padding-top: 60px;}</style> <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top"> - <a class="navbar-brand" href="https://www.iri.upc.edu"> - <img src="images/iri.png" width="30" height="30" class="d-inline-block align-top" alt=""> - IRI + <a class="navbar-brand" href="https://autonomous-driving-challenge.com/"> + <img src="images/carnet.png" width="30" height="30" class="d-inline-block align-top" alt=""> + ADC </a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> @@ -109,37 +361,65 @@ <li class="nav-item active"> <a class="nav-link" href="index.html"><b>Home</b></a> </li> + <!-- <li class="nav-item"> <a class="nav-link" href="map.html">Map<a/> </li> - </li> + --> </ul> </div> </nav> <main role="main" class="container"> + Team:          <input type="number" id="team_input" min="1" max="6" step="1" style="width: 2em" value="1" onchange="update_team()"> <br> - Challenge: <input type="number" id="challenge_input" min="1" max="5" step="1" style="width: 2em" value="1" onchange="update_challenge()"> + Challenge: <input type="number" id="challenge_input" min="0" max="5" step="1" style="width: 2em" value="1" onchange="update_challenge()"> + + <hr> + <b>Goals file:</b> (will be automatic for each chosen challenge # (goals#.yaml)) <br> - Timer: + + <input type="text" id="goals_file" value="./data/goals0.yaml" onchange="load_goals_from_yaml()"/> <br> - <p id = "output" class = "text-left">00:00:00</p> + <!--<button class="btn btn-primary" id = "load_goals_button" onclick = "load_goals_from_yaml()">Load goals</button>--> + + <hr> + + <b>Attempt</b> + <br> + <div id = "controls" class = "text-left"> - <button class="btn btn-primary" id = "startPause" onclick = "startPause()">START</button> - <button class="btn btn-danger" onclick = "reset()">RESET</button> + <button class="btn btn-success" id = "startStop" style="width:49.25%; height: 50px" onclick = "this.blur();startStop()">START</button> + <br> + <span id="action_info" > </span> + <!--<button class="btn btn-danger" id = "resetButton" style="width:49.25%; height: 50px; background-color: red" onclick = "this.blur();reset()">RESET</button>--> </div> - Feedback: - <div style="overflow-y: auto; height:75px; border-style:solid"> - <!-- Feedback text example1<br> - Feedback text example2<br> - Feedback text example3<br> - Feedback text example4<br> - Feedback text example5<br> - Feedback text example6<br>--> - <span id="feedback_text">Received feedback messages will be shown here</span> + <br> + <p id = "output" class = "text-left">00:00:00</p> + + + <hr> + + <b>Jury Mode</b> + <div id = "controls2" class = "text-left"> + <button class="btn btn-primary" id = "jury_mode_button" style="width:49.25%; height: 50px" onclick = "this.blur();jury_mode()">ENABLE</button> </div> - <button class="btn btn-primary" id = "add_feedback" onclick = "add_feedback()">Add fake feedback</button> + <span id="service_info" > </span> + + <hr> + <b>Feedback</b> + <br> + <textarea readonly id="feedback_text" style="resize: vertical; width:100%; border-style:solid;" wrap='off' rows="3" cols="auto">Received feedback messages will be shown here. Each message starting a new line</textarea> + <br> + <button class="btn btn-danger" id = "clear_feedback" onclick = "this.blur();clear_feedback()">Clear feedback</button> + <br> + <!-- + Debug: + <br><button class="btn btn-primary" id = "add_feedback" onclick = "add_fake_feedback()">Add fake feedback</button> + <input type="text" id="fake_feedback_text" size="50" value="This is a fake feedback text example"/> + <hr> + --> </main> diff --git a/html/js-yaml b/html/js-yaml new file mode 160000 index 0000000..49baadd --- /dev/null +++ b/html/js-yaml @@ -0,0 +1 @@ +Subproject commit 49baadd52af887d2991e2c39a6639baa56d6c71b diff --git a/html/map.html b/html/map.html index 79bc7a3..5d37899 100644 --- a/html/map.html +++ b/html/map.html @@ -77,8 +77,8 @@ <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top"> <a class="navbar-brand" href="https://www.iri.upc.edu"> - <img src="images/iri.png" width="30" height="30" class="d-inline-block align-top" alt=""> - IRI + <img src="images/carnet.png" width="30" height="30" class="d-inline-block align-top" alt=""> + ADC </a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> diff --git a/html/style.css b/html/style.css index e47b2bf..e3c7fd0 100644 --- a/html/style.css +++ b/html/style.css @@ -6,7 +6,7 @@ } #output { - font-size: 2.0em; + font-size: 3.0em; width: auto; height: auto; background-color: white; diff --git a/html/timer.js b/html/timer.js index 4939fba..30b78e2 100644 --- a/html/timer.js +++ b/html/timer.js @@ -1,27 +1,37 @@ var time = 0; -var running = 0; +var timer_running = false; +var timer_timeout; +var time_string=""; -function startPause() { - if (running == 0) { - running = 1; - increment(); - document.getElementById("startPause").innerHTML = "PAUSE"; - } else { - running = 0; - document.getElementById("startPause").innerHTML = "RESUME"; - } +function startStop() +{ + if (!timer_running) + { + time=0; + timer_running = true; + increment(); + document.getElementById("startStop").innerHTML = "STOP"; + document.getElementById('startStop').style.backgroundColor="red"; + send_goal(); + } + else + { + timer_running = false; + document.getElementById("startStop").innerHTML = "START"; + document.getElementById('startStop').style.backgroundColor="green"; + cancel_goal(); + } } -function reset(){ - running = 0; - time = 0; - document.getElementById("startPause").innerHTML = "START"; - document.getElementById("output").innerHTML = "00:00:00"; -} - -function increment() { - if (running == 1) { - setTimeout(function() { +function increment() +{ + if (timer_running) + { + timer_timeout = setTimeout( + function() + { + if(timer_running) + { time++; var mins = Math.floor(time/10/60); var secs = Math.floor(time/10 % 60); @@ -32,8 +42,10 @@ function increment() { if (secs < 10) { secs = "0" + secs; } - document.getElementById("output").innerHTML = mins + ":" + secs + ":" + "0" + tenths; + time_string = mins + ":" + secs + ":" + "0" + tenths; + document.getElementById("output").innerHTML = time_string ; increment(); - },100); - } + } + },100); + } } -- GitLab