diff --git a/web_interface/html/agent.php b/web_interface/html/agent.php new file mode 100644 index 0000000000000000000000000000000000000000..deee41d2b8afe19661fb2c4b4fc960d5adfc4c2f --- /dev/null +++ b/web_interface/html/agent.php @@ -0,0 +1,76 @@ +<?php + include("page_header.html"); +?> + +<div class="full-window-fixed"> +</div> + +<div class="max-width-full-heigth-fixed"> + + <div class="top-bar-container"> + <table class="top-bar-buttons-table"> + <tr> + <td class="top-bar-motorsoff-button-cell"> + <button + class="button-push red motorsoff" + id="buttonMotorsOffForAgent" + onclick="sendRosMessage_outputLabelID('motorsoff', '')" + > + MOTORS-OFF + <div class="div-for-button-highlight-on-touchscreen red"></div> + </button> + </td> + <td class="top-bar-info-button-cell"> + <button class="button-push blue info" onclick="checkForRosAgent()"> + i + <div class="div-for-button-highlight-on-touchscreen blue"></div> + </button> + </td> + </tr> + </table> + + <div class="top-bar-title padbelow"> + Agent (IP <?php echo $_SERVER['REMOTE_ADDR']; ?>) + </div> + </div> + + + <div class="main-tabs"> + <input name="tabs" type="radio" id="main-tab-1" checked="checked" class="main-tab-input"/> + <label for="main-tab-1" class="main-tab-label">Code</label> + <div class="main-tab-panel"> + <?php + include("agent_tab_code.html"); + ?> + </div> + + <input name="tabs" type="radio" id="main-tab-2" class="main-tab-input"/> + <label for="main-tab-2" class="main-tab-label">Compile</label> + <div class="main-tab-panel"> + <?php + include("agent_tab_compile.html"); + ?> + </div> + + <input name="tabs" type="radio" id="main-tab-3" class="main-tab-input"/> + <label for="main-tab-3" class="main-tab-label">Launch</label> + <div class="main-tab-panel"> + <?php + include("agent_tab_launch.html"); + ?> + </div> + + <input name="tabs" type="radio" id="main-tab-4" class="main-tab-input"/> + <label for="main-tab-4" class="main-tab-label">Control</label> + <div class="main-tab-panel thin-padding"> + <?php + include("agent_tab_control.php"); + ?> + </div> + </div> +</div> + + +<?php + include("page_footer.html"); +?> \ No newline at end of file diff --git a/web_interface/html/agent_control_tab_default.html b/web_interface/html/agent_control_tab_default.html new file mode 100644 index 0000000000000000000000000000000000000000..5f92bf87fca9407c5528b48cdf7727e96c6a3978 --- /dev/null +++ b/web_interface/html/agent_control_tab_default.html @@ -0,0 +1,206 @@ +<br> + +<button + class="button-push navy fullwidth" + id="buttonControlEnableDefault" + onclick="sendRosMessage_outputLabelID('enabledefault', 'labelControlEnableDefault')" + > + enable + <div class="div-for-button-highlight-on-touchscreen navy"></div> +</button> +<div + style="text-align: center; display: block;" + id="labelControlEnableDefault" + > +   +</div> + +<hr class="hr-basic navy"> + +<h2 style="text-align: center;"> + Adjust Setpoint +</h2> + +<table style="margin-left: auto; margin-right: auto;"> + <tr> + <td class="setpoint-label-cell"> + x [m] + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonDecrementControlDefaultSetpointX" + onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointX', -1.0 )" + > + - + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="setpoint-input-field-cell"> + <input + class="setpoint-input-field" + id="inputControlDefaultSetpointX" + type="text" + name="x" + value="0.0" + step="0.1" + pattern="^[-+]?\d*(\.)?(\d?)*" + inputmode="none" + > + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonIncrementControlDefaultSetpointX" + onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointX', 1.0 )" + > + + + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + <tr> + <td class="setpoint-label-cell"> + y [m] + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonDecrementControlDefaultSetpointY" + onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointY', -1.0 )" + > + - + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="setpoint-input-field-cell"> + <input + class="setpoint-input-field" + id="inputControlDefaultSetpointY" + type="text" + name="y" + value="0.0" + step="0.1" + pattern="^[-+]?\d*(\.)?(\d?)*" + inputmode="none" + > + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonIncrementControlDefaultSetpointY" + onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointY', 1.0 )" + > + + + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + <tr> + <td class="setpoint-label-cell"> + z [m] + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonDecrementControlDefaultSetpointZ" + onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointZ', -1.0 )" + > + - + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="setpoint-input-field-cell"> + <input + class="setpoint-input-field" + id="inputControlDefaultSetpointZ" + type="text" + name="z" + value="0.4" + step="0.1" + pattern="^[-+]?\d*(\.)?(\d?)*" + inputmode="none" + > + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonIncrementControlDefaultSetpointZ" + onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointZ', 1.0 )" + > + + + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + <tr> + <td class="setpoint-label-cell"> + yaw [deg] + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonDecrementControlDefaultSetpointYaw" + onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointYaw', -1.0 )" + > + - + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="setpoint-input-field-cell"> + <input + class="setpoint-input-field" + id="inputControlDefaultSetpointYaw" + type="text" + name="yaw" + value="0" + step="5" + pattern="^[-+]?\d*(\.)?(\d?)*" + inputmode="none" + > + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonIncrementControlDefaultSetpointYaw" + onclick="incrementInputFieldWithGivenID('inputControlDefaultSetpointYaw', 1.0 )" + > + + + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + <tr> + <td></td> + <td></td> + <td> + <button + class="button-push navy fullwidth" + id="buttonControlDefaultSetSetpoint" + onclick="setSetpointViaRosMessage_outputLabelID('default', 'inputControlDefaultSetpoint', 'labelControlDefaultSetSetpoint' )" + > + set + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td></td> + </tr> + <tr> + <td></td> + <td></td> + <td> + <div + style="text-align: center;" + id="labelControlDefaultSetSetpoint" + > +   + </div> + </td> + <td></td> + </tr> +</table> + +<hr class="hr-basic navy"> + + +<br><br><br><br><br> \ No newline at end of file diff --git a/web_interface/html/agent_control_tab_student.html b/web_interface/html/agent_control_tab_student.html new file mode 100644 index 0000000000000000000000000000000000000000..9265271c9cd4be900fa993a825f6ad61d78374d4 --- /dev/null +++ b/web_interface/html/agent_control_tab_student.html @@ -0,0 +1,250 @@ +<br> + +<button + class="button-push navy fullwidth" + id="buttonControlEnableStudent" + onclick="sendRosMessage_outputLabelID('enablestudent', 'labelControlEnableStudent')" + > + enable + <div class="div-for-button-highlight-on-touchscreen navy"></div> +</button> +<div + style="text-align: center; display: block;" + id="labelControlEnableStudent" + > +   +</div> + +<hr class="hr-basic navy"> + +<h2 style="text-align: center;"> + Adjust Setpoint +</h2> + +<table style="margin-left: auto; margin-right: auto;"> + <tr> + <td class="setpoint-label-cell"> + x [m] + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonDecrementControlStudentSetpointX" + onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointX', -1.0 )" + > + - + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="setpoint-input-field-cell"> + <input + class="setpoint-input-field" + id="inputControlStudentSetpointX" + type="text" + name="x" + value="0" + step="0.1" + pattern="^[-+]?\d*(\.)?(\d?)*" + inputmode="none" + > + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonIncrementControlStudentSetpointX" + onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointX', 1.0 )" + > + + + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + <tr> + <td class="setpoint-label-cell"> + y [m] + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonDecrementControlStudentSetpointY" + onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointY', -1.0 )" + > + - + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="setpoint-input-field-cell"> + <input + class="setpoint-input-field" + id="inputControlStudentSetpointY" + type="text" + name="y" + value="0" + step="0.1" + pattern="^[-+]?\d*(\.)?(\d?)*" + inputmode="none" + > + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonIncrementControlStudentSetpointY" + onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointY', 1.0 )" + > + + + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + <tr> + <td class="setpoint-label-cell"> + z [m] + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonDecrementControlStudentSetpointZ" + onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointZ', -1.0 )" + > + - + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="setpoint-input-field-cell"> + <input + class="setpoint-input-field" + id="inputControlStudentSetpointZ" + type="text" + name="z" + value="0.4" + step="0.1" + pattern="^[-+]?\d*(\.)?(\d?)*" + inputmode="none" + > + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonIncrementControlStudentSetpointZ" + onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointZ', 1.0 )" + > + + + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + <tr> + <td class="setpoint-label-cell"> + yaw [deg] + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonDecrementControlStudentSetpointYaw" + onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointYaw', -1.0 )" + > + - + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="setpoint-input-field-cell"> + <input + class="setpoint-input-field" + id="inputControlStudentSetpointYaw" + type="text" + name="yaw" + value="0" + step="5" + pattern="^[-+]?\d*(\.)?(\d?)*" + inputmode="none" + > + </td> + <td class="setpoint-increment-cell"> + <button + class="button-push navy slim short10" + id="buttonIncrementControlStudentSetpointYaw" + onclick="incrementInputFieldWithGivenID('inputControlStudentSetpointYaw', 1.0 )" + > + + + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + <tr> + <td></td> + <td></td> + <td> + <button + class="button-push navy fullwidth" + id="buttonControlStudentSetSetpoint" + onclick="setSetpointViaRosMessage_outputLabelID('student', 'inputControlStudentSetpoint', 'labelControlStudentSetSetpoint' )" + > + set + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td></td> + </tr> + <tr> + <td></td> + <td></td> + <td> + <div + style="text-align: center;" + id="labelControlStudentSetSetpoint" + > +   + </div> + </td> + <td></td> + </tr> +</table> + +<br> + +<table class="centered-table"> + <tr> + <td class="centered-table-button-cell"> + <button + class="button-push navy" + id="buttonGetSetpointStudent" + onclick="getSetpointViaRosServiceCall_outputLabelID('student', 'labelGetSetpointStudent')" + > + get current + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="centered-table-button-cell"> + <button + class="button-push navy" + id="buttonSetDefaultSetpointStudent" + onclick="putDefaultSetpointForGivenBaseID('inputControlStudentSetpoint')" + > + put default + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + <tr> + <td class="centered-table-button-cell"> + <div + style="text-align: center;" + id="labelGetSetpointStudent" + > +   + </div> + </td> + <td class="centered-table-button-cell"> + <div + style="text-align: center;" + id="labelSetDeaultSetpointStudent" + > +   + </div> + </td> + </tr> +</table> + +<hr class="hr-basic navy"> + +<br><br><br><br><br> \ No newline at end of file diff --git a/web_interface/html/agent_tab_code.html b/web_interface/html/agent_tab_code.html new file mode 100644 index 0000000000000000000000000000000000000000..fdceac46c3b02e0aa99a8ab4c149d0ca8f4c1693 --- /dev/null +++ b/web_interface/html/agent_tab_code.html @@ -0,0 +1,11 @@ +<body> + <div class="body-container"> + <main style="text-align:left;"> + + <br> + + Coming soon... + + </main> + </div> +</body> \ No newline at end of file diff --git a/web_interface/html/agent_tab_compile.html b/web_interface/html/agent_tab_compile.html new file mode 100644 index 0000000000000000000000000000000000000000..f2f1bc60174f2d3f77e26970ef694024bbeeb4be --- /dev/null +++ b/web_interface/html/agent_tab_compile.html @@ -0,0 +1,112 @@ +<body> + <div class="body-container"> + <main style="text-align:left;"> + + <br> + + <table class="git-table"> + <tr> + <td class="git-button-cell left"> + <button + class="button-push navy fullwidth" + id="buttonGitStatus" + onclick="callGit_outputLabelID_shouldAppend_shouldConfirm('status', 'terminalOutput', true, false)" + > + git status + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="git-button-cell right"> + <button + class="button-push navy fullwidth" + id="buttonGitPull" + onclick="callGit_outputLabelID_shouldAppend_shouldConfirm('pull', 'terminalOutput', true, false)" + > + git pull + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + <tr> + <td class="git-button-cell left"> + <button + class="button-push navy fullwidth" + id="buttonGitDiff" + onclick="callGit_outputLabelID_shouldAppend_shouldConfirm('diff', 'terminalOutput', true, false)" + > + git diff + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="git-button-cell right"> + <button + class="button-push navy fullwidth" + id="buttonCatkinMake" + onclick="callGit_outputLabelID_shouldAppend_shouldConfirm('catkin_make', 'terminalOutput', false, false)" + > + catkin make + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + <!-- ALTERNATIVE FOR THIS BUTTON --> + <!-- onclick="callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons('catkin_make', 'terminalOutput' , null, null)" --> + </td> + </tr> + </table> + + <div class="git-checkout-label">git checkout</div> + <table class="git-table"> + <tr> + <td class="git-button-cell left"> + <button + class="button-push red fullwidth" + id="buttonGitCheckoutAll" + onclick="callGit_outputLabelID_shouldAppend_shouldConfirm('checkoutall', 'terminalOutput', true, true)" + > + all + <div class="div-for-button-highlight-on-touchscreen red"></div> + </button> + </td> + <td class="git-button-cell right"> + <button + class="button-push red fullwidth" + id="buttonGitCheckoutMaster" + onclick="callGit_outputLabelID_shouldAppend_shouldConfirm('checkoutmaster', 'terminalOutput', true, true)" + > + master + <div class="div-for-button-highlight-on-touchscreen red"></div> + </button> + </td> + </tr> + </table> + + <br><br> + + + + <table class="terminal-label-table"> + <tr> + <td class="terminal-label-cell"> + <div class="terminal-label">TERMINAL OUTPUT</div> + </td> + <td> + <button + class="button-push navy monospace short" + id="buttonGitCheckout" + onclick="clearLabelWithGivenID('terminalOutput')" + > + clear + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + </table> + + <div class="terminal-background"> + <div class="terminal-contents" id="terminalOutput"></div> + </div> + + <br> + + </main> + </div> +</body> \ No newline at end of file diff --git a/web_interface/html/agent_tab_control.php b/web_interface/html/agent_tab_control.php new file mode 100644 index 0000000000000000000000000000000000000000..51095d44918a59067b6cba2235cdba42fba11156 --- /dev/null +++ b/web_interface/html/agent_tab_control.php @@ -0,0 +1,95 @@ +<table class="git-table"> + <tr> + <td class="git-button-cell left"> + <button + class="button-push navy fullwidth" + id="buttonControlRadioDisconnect" + onclick="sendRosMessage_outputLabelID('disconnect', 'labelControlRadioDisconnect')" + > + disconnect + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="git-button-cell left"> + <button + class="button-push navy fullwidth" + id="buttonControlRadioConnect" + onclick="sendRosMessage_outputLabelID('connect', 'labelControlRadioConnect')" + > + connect + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + <tr> + <td + style="text-align: center;" + id="labelControlRadioDisconnect" + > +   + </td> + <td + style="text-align: center;" + id="labelControlRadioConnect" + > +   + </td> + </tr> + <tr> + <td class="git-button-cell left"> + <button + class="button-push navy fullwidth" + id="buttonControlTakeoff" + onclick="sendRosMessage_outputLabelID('takeoff', 'labelControlTakeOff')" + > + take-off + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="git-button-cell left"> + <button + class="button-push navy fullwidth" + id="buttonControlLand" + onclick="sendRosMessage_outputLabelID('land', 'labelControlLand')" + > + land + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + </tr> + <tr> + <td + style="text-align: center;" + id="labelControlTakeOff" + > +   + </td> + <td + style="text-align: center;" + id="labelControlLand" + > +   + </td> + </tr> +</table> + +<br> + +<div class="control-tabs"> + <input name="control-tabs" type="radio" id="control-tab-1" checked="checked" class="control-tab-input"/> + <label for="control-tab-1" class="control-tab-label">Default</label> + <div class="control-tab-panel"> + <?php + include("agent_control_tab_default.html"); + ?> + </div> + + <input name="control-tabs" type="radio" id="control-tab-2" class="control-tab-input"/> + <label for="control-tab-2" class="control-tab-label">Student</label> + <div class="control-tab-panel"> + <?php + include("agent_control_tab_student.html"); + ?> + </div> + +</div> \ No newline at end of file diff --git a/web_interface/html/agent_tab_launch.html b/web_interface/html/agent_tab_launch.html new file mode 100644 index 0000000000000000000000000000000000000000..117fd361f56fbef0a5fcc5b11a353b326ff9e66e --- /dev/null +++ b/web_interface/html/agent_tab_launch.html @@ -0,0 +1,99 @@ +<body> + <div class="body-container"> + <main style="text-align:left;"> + + <br> + + <table class="ros-table"> + + <tr> + <td class="ros-button-cell"> + <button + class="button-push navy fullwidth" + id="buttonRosMasterStatus" + onclick="callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons('checkForRosMaster', 'rosMasterStatus', null, null)" + > + Check for ROS Master + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="ros-info-cell"> + <div id="rosMasterStatus"></div> + </td> + </tr> + + <tr> + <td class="ros-button-cell"> + <button + class="button-push navy fullwidth" + id="buttonRosAgentStatus" + onclick="callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons('checkForRosAgent', 'rosAgentStatus', null, ['buttonRosMasterStatus','buttonRosNodeList'])" + > + Check for ROS Agent + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="ros-info-cell"> + <div id="rosAgentStatus"></div> + </td> + </tr> + + <tr> + <td class="ros-button-cell"> + <button + class="button-push navy fullwidth" + id="buttonLaunchRosAgent" + onclick="callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons('launchRosAgent', 'rosLaunchAgentStatus', 'killAgentStatus', ['buttonRosMasterStatus','buttonRosAgentStatus','buttonRosNodeList'])" + > + Launch ROS Agent + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td class="ros-info-cell"> + <div id="rosLaunchAgentStatus"></div> + </td> + </tr> + + <tr> + <td class="ros-button-cell"> + <button + class="button-push red fullwidth" + id="buttonKillRosAgent" + onclick="callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons('killRosAgent', 'killAgentStatus', 'rosLaunchAgentStatus', ['buttonRosMasterStatus','buttonRosAgentStatus','buttonRosNodeList'])" + > + Kill ROS Agent + <div class="div-for-button-highlight-on-touchscreen red"></div> + </button> + </td> + <td class="ros-info-cell"> + <div id="killAgentStatus"></div> + </td> + </tr> + + <tr> + <td class="ros-button-cell"> + <button + class="button-push navy fullwidth" + id ="buttonRosNodeList" + onclick="callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons('rosnodeList', 'rosnodeList', null, null)" + > + List ROS Nodes + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + </td> + <td></td> + </tr> + + </table> + + <table class="ros-table"> + <tr> + <td class="ros-info-cell"> + <div id="rosnodeList"></div> + </td> + </tr> + </table> + + </main> + </div> +</body> \ No newline at end of file diff --git a/web_interface/html/bashscripts/catkin_make.sh b/web_interface/html/bashscripts/catkin_make.sh new file mode 100755 index 0000000000000000000000000000000000000000..96e9494ba1d7b485ca9998655113c87f3f617cff --- /dev/null +++ b/web_interface/html/bashscripts/catkin_make.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# +# Make the ROS commands available +# NOTE: these paths should NOT use ~ +source /opt/ros/melodic/setup.bash +#source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh +# +# Change directory to the dfall-system repository +cd /home/www-share/dfall/dfall-system/dfall_ws +# +# Call catkin_make +catkin_make \ No newline at end of file diff --git a/web_interface/html/bashscripts/catkin_make_clean.sh b/web_interface/html/bashscripts/catkin_make_clean.sh new file mode 100755 index 0000000000000000000000000000000000000000..1d6935cb9ccbd360d4e8604ebf6397d8e32e24cd --- /dev/null +++ b/web_interface/html/bashscripts/catkin_make_clean.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# +# Make the ROS commands available +# NOTE: these paths should NOT use ~ +source /opt/ros/melodic/setup.bash +#source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh +# +# Change directory to the dfall-system repository +cd /home/www-share/dfall/dfall-system/dfall_ws +# +# Call catkin_make +catkin_make clean \ No newline at end of file diff --git a/web_interface/html/bashscripts/checkForRosAgent.sh b/web_interface/html/bashscripts/checkForRosAgent.sh new file mode 100755 index 0000000000000000000000000000000000000000..27ef70f78d51d505eda246a3990eaeb2397d4c9e --- /dev/null +++ b/web_interface/html/bashscripts/checkForRosAgent.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# Make the ROS commands available +# NOTE: these paths should NOT use ~ +source /opt/ros/melodic/setup.bash +#source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh +# +# Check that the ROS Master exists +# > Note: the -q options converts the +# grep output to a true/false +if rosnode list | grep -q /rosout; then + # Check if the agent exists + if rosnode list | grep -q "$(printf "/dfall/agent%03d" $DFALL_DEFAULT_AGENT_ID)"; then + echo "Agent $DFALL_DEFAULT_AGENT_ID exists" + else + echo "Agent $DFALL_DEFAULT_AGENT_ID not found" + fi +else + echo "ROS Master not found" +fi diff --git a/web_interface/html/bashscripts/checkForRosMaster.sh b/web_interface/html/bashscripts/checkForRosMaster.sh new file mode 100755 index 0000000000000000000000000000000000000000..285240e74a28b08a95342273317cd6e5cf7f0b2e --- /dev/null +++ b/web_interface/html/bashscripts/checkForRosMaster.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# +# Make the ROS commands available +# NOTE: these paths should NOT use ~ +source /opt/ros/melodic/setup.bash +# +# Perform the check +# > Note: the -q options converts the +# grep output to a true/false +if rosnode list | grep -q /rosout; then + echo "ROS Master exists" +else + echo "ROS Master not found" +fi diff --git a/web_interface/html/bashscripts/gitCheckoutAll.sh b/web_interface/html/bashscripts/gitCheckoutAll.sh new file mode 100755 index 0000000000000000000000000000000000000000..013f312c4ad88d824d2704de30804f7e159b322c --- /dev/null +++ b/web_interface/html/bashscripts/gitCheckoutAll.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# +# Change directory to the dfall-system repository +cd /home/www-share/dfall/dfall-system/ +# +# Call git +git checkout . \ No newline at end of file diff --git a/web_interface/html/bashscripts/gitCheckoutMaster.sh b/web_interface/html/bashscripts/gitCheckoutMaster.sh new file mode 100755 index 0000000000000000000000000000000000000000..b0320528b7a7d9f4016d8b9bdc762a5547f95966 --- /dev/null +++ b/web_interface/html/bashscripts/gitCheckoutMaster.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# +# Change directory to the dfall-system repository +cd /home/www-share/dfall/dfall-system/ +# +# Call git +git checkout master \ No newline at end of file diff --git a/web_interface/html/bashscripts/gitDiff.sh b/web_interface/html/bashscripts/gitDiff.sh new file mode 100755 index 0000000000000000000000000000000000000000..bb2873913a4623f1b6405c16851dbb1acce0d6bd --- /dev/null +++ b/web_interface/html/bashscripts/gitDiff.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# +# Change directory to the dfall-system repository +cd /home/www-share/dfall/dfall-system/ +# +# Call git +git diff \ No newline at end of file diff --git a/web_interface/html/bashscripts/gitPull.sh b/web_interface/html/bashscripts/gitPull.sh new file mode 100755 index 0000000000000000000000000000000000000000..8849eb92815478f51126729ef5e9f90942b25820 --- /dev/null +++ b/web_interface/html/bashscripts/gitPull.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# +# Change directory to the dfall-system repository +cd /home/www-share/dfall/dfall-system/ +# +# Call git +sudo -u www-data git pull \ No newline at end of file diff --git a/web_interface/html/bashscripts/gitStatus.sh b/web_interface/html/bashscripts/gitStatus.sh new file mode 100755 index 0000000000000000000000000000000000000000..5e60e9beb6d2a5f2c5c7624e4d70506a97ba96a3 --- /dev/null +++ b/web_interface/html/bashscripts/gitStatus.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# +# Change directory to the dfall-system repository +cd /home/www-share/dfall/dfall-system/ +# +# Call git +git status \ No newline at end of file diff --git a/web_interface/html/bashscripts/killRosAgent.sh b/web_interface/html/bashscripts/killRosAgent.sh new file mode 100755 index 0000000000000000000000000000000000000000..27fa7de668523391af564af44e4f843778fa4f07 --- /dev/null +++ b/web_interface/html/bashscripts/killRosAgent.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# +# Make the ROS commands available +# NOTE: these paths should NOT use ~ +source /opt/ros/melodic/setup.bash +#source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh +# +# Check that the ROS Master exists +# > Note: the -q options converts the +# grep output to a true/false +if rosnode list | grep -q /rosout; then + # Check that if the agent is already + # launched + if rosnode list | grep -q "$(printf "/dfall/agent%03d" $DFALL_DEFAULT_AGENT_ID)"; then + # Kill all nodes starting with + # /dfall/agentXXX/ + rosnode list | grep "$(printf "/dfall/agent%03d" $DFALL_DEFAULT_AGENT_ID)" | xargs rosnode kill > /dev/null + echo "Agent $DFALL_DEFAULT_AGENT_ID killed" + else + echo "Agent $DFALL_DEFAULT_AGENT_ID not found" + fi +else + echo "ROS Master not found" +fi diff --git a/web_interface/html/bashscripts/launchRosAgent.sh b/web_interface/html/bashscripts/launchRosAgent.sh new file mode 100755 index 0000000000000000000000000000000000000000..b8fec36a81a33e17161aa109dfed14924fe810b3 --- /dev/null +++ b/web_interface/html/bashscripts/launchRosAgent.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# +# Make the ROS commands available +# NOTE: these paths should NOT use ~ +source /opt/ros/melodic/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh +# +# Set the ROS log location +export ROS_LOG_DIR=/var/www/html/.ros/log +# +# Mount the dfall workspace folder +#sudo mount --bind /home/pbeuchat/gitrep/dfall/dfall-system/dfall_ws /var/www/html/dfall_ws +# +# Check that the ROS Master exists +# > Note: the -q options converts the +# grep output to a true/false +if rosnode list | grep -q /rosout; then + # Check that if the agent is already + # launched + if rosnode list | grep -q "$(printf "/dfall/agent%03d" $DFALL_DEFAULT_AGENT_ID)"; then + echo "Agent $DFALL_DEFAULT_AGENT_ID is already running" + else + nohup roslaunch dfall_pkg agent.launch withGUI:=false emulateRadio:=true > /dev/null 2>&1 & + echo "Agent $DFALL_DEFAULT_AGENT_ID successfully launched" + fi +else + echo "ROS Master not found" +fi diff --git a/web_interface/html/bashscripts/rosCrazyRadioCommand_forAgent.sh b/web_interface/html/bashscripts/rosCrazyRadioCommand_forAgent.sh new file mode 100755 index 0000000000000000000000000000000000000000..ed6c359cd9c4d2c517f9d8bae809f6a5ec12831e --- /dev/null +++ b/web_interface/html/bashscripts/rosCrazyRadioCommand_forAgent.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# +# Check that exactly one command is supplied +if [ "$#" -ne 1 ]; then + echo "failed" + exit 1 +fi +# +# Check that the command supplied is valid +if [ "$1" != "0" ] && [ "$1" != "1" ]; then + echo "failed" + exit 1 +fi +# +# Put the command into a variable for make things more readable +command=$1 +# +# Make the ROS commands available +# NOTE: these paths should NOT use ~ +source /opt/ros/melodic/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh +# +# Check that the ROS Master exists +# > Note: the -q options converts the +# grep output to a true/false +if rosnode list | grep -q /rosout; then + # Convert the agent ID to a zero padded string + agentnamespace=$(printf "agent%03d" $DFALL_DEFAULT_AGENT_ID) + # Send the message + if [ "$command" == "0" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/crazyRadioCommand dfall_pkg/IntWithHeader '{data: 0, shouldCheckForAgentID: False}')" + fi + if [ "$command" == "1" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/crazyRadioCommand dfall_pkg/IntWithHeader '{data: 1, shouldCheckForAgentID: False}')" + fi + # + # Return that the message was sent + echo "sent" +else + echo "ROS Master not found" +fi diff --git a/web_interface/html/bashscripts/rosFlyingStateCommand_forAgent.sh b/web_interface/html/bashscripts/rosFlyingStateCommand_forAgent.sh new file mode 100755 index 0000000000000000000000000000000000000000..7564ca5b9e7642e6017211fd1969de701b1bfcc7 --- /dev/null +++ b/web_interface/html/bashscripts/rosFlyingStateCommand_forAgent.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# +# Check that exactly one command is supplied +if [ "$#" -ne 1 ]; then + echo "failed" + exit 1 +fi +# +# Check that the command supplied is valid +if [ "$1" != "1" ] && [ "$1" != "2" ] && [ "$1" != "3" ] && [ "$1" != "4" ] && [ "$1" != "5" ] && [ "$1" != "6" ] && [ "$1" != "7" ] && [ "$1" != "8" ] && [ "$1" != "11" ] && [ "$1" != "12" ] && [ "$1" != "13" ]; then + echo "failed" + exit 1 +fi +# +# Put the command into a variable for make things more readable +command=$1 +# +# Make the ROS commands available +# NOTE: these paths should NOT use ~ +source /opt/ros/melodic/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh +# +# Check that the ROS Master exists +# > Note: the -q options converts the +# grep output to a true/false +if rosnode list | grep -q /rosout; then + # Convert the agent ID to a zero padded string + agentnamespace=$(printf "agent%03d" $DFALL_DEFAULT_AGENT_ID) + # Send the message + if [ "$command" == "1" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 1, shouldCheckForAgentID: False}')" + fi + if [ "$command" == "2" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 2, shouldCheckForAgentID: False}')" + fi + if [ "$command" == "3" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 3, shouldCheckForAgentID: False}')" + fi + if [ "$command" == "4" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 4, shouldCheckForAgentID: False}')" + fi + if [ "$command" == "5" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 5, shouldCheckForAgentID: False}')" + fi + if [ "$command" == "6" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 6, shouldCheckForAgentID: False}')" + fi + if [ "$command" == "7" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 7, shouldCheckForAgentID: False}')" + fi + if [ "$command" == "8" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 8, shouldCheckForAgentID: False}')" + fi + if [ "$command" == "11" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 11, shouldCheckForAgentID: False}')" + fi + if [ "$command" == "12" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 12, shouldCheckForAgentID: False}')" + fi + if [ "$command" == "13" ]; then + temp="$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/FlyingAgentClient/Command dfall_pkg/IntWithHeader '{data: 13, shouldCheckForAgentID: False}')" + fi + # + # Return that the message was sent + echo "sent" +else + echo "ROS Master not found" +fi diff --git a/web_interface/html/bashscripts/rosGetCurrentSetpoint_forAgent.sh b/web_interface/html/bashscripts/rosGetCurrentSetpoint_forAgent.sh new file mode 100755 index 0000000000000000000000000000000000000000..e7ce23f355c0d6ef16cf9ee3cb4d2e3bd9f5260f --- /dev/null +++ b/web_interface/html/bashscripts/rosGetCurrentSetpoint_forAgent.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# +# Check that exactly one command is supplied +if [ "$#" -ne 1 ]; then + echo "failed" + exit 1 +fi +# +# Check that the command supplied is valid +if [ "$1" != "default" ] && [ "$1" != "student" ]; then + echo "failed" + exit 1 +fi +# +# Put the command into a variable for make things more readable +command=$1 +# +# Make the ROS commands available +# NOTE: these paths should NOT use ~ +source /opt/ros/melodic/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh +# +# Check that the ROS Master exists +# > Note: the -q options converts the +# grep output to a true/false +if rosnode list | grep -q /rosout; then + # Convert the agent ID to a zero padded string + agentnamespace=$(printf "agent%03d" $DFALL_DEFAULT_AGENT_ID) + # Send the message + if [ "$command" == "default" ]; then + temp="$(rosservice call /$ROS_NAMESPACE/$agentnamespace/DefaultControllerService/GetCurrentSetpoint 0)" + fi + if [ "$command" == "student" ]; then + temp="$(rosservice call /$ROS_NAMESPACE/$agentnamespace/StudentControllerService/GetCurrentSetpoint 0)" + fi + # + # Return that the message was sent + echo "$temp" +else + echo "ROS Master not found" +fi diff --git a/web_interface/html/bashscripts/rosSetNewSetpoint_forAgent.sh b/web_interface/html/bashscripts/rosSetNewSetpoint_forAgent.sh new file mode 100755 index 0000000000000000000000000000000000000000..e81dffdff9173a85de82c644cc84755a0af9ed1e --- /dev/null +++ b/web_interface/html/bashscripts/rosSetNewSetpoint_forAgent.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Check that exactly five commands are supplied +if [ "$#" -ne 5 ]; then + echo "failed" + exit 1 +fi +# +# Check that the first command supplied is valid +if [ "$1" != "default" ] && [ "$1" != "student" ]; then + echo "failed" + exit 1 +fi +# +# Put the commands into variables for make things more readable +command=$1 +xnew=$2 +ynew=$3 +znew=$4 +yawnew=$5 +# +# Make the ROS commands available +# NOTE: these paths should NOT use ~ +source /opt/ros/melodic/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/devel/setup.bash +source /home/www-share/dfall/dfall-system/dfall_ws/src/dfall_pkg/launch/Config.sh +# +# Check that the ROS Master exists +# > Note: the -q options converts the +# grep output to a true/false +if rosnode list | grep -q /rosout; then + # Convert the agent ID to a zero padded string + agentnamespace=$(printf "agent%03d" $DFALL_DEFAULT_AGENT_ID) + # Send the message + if [ "$command" == "default" ]; then + "$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/DefaultControllerService/RequestSetpointChange dfall_pkg/SetpointWithHeader "{x: $xnew, y: $ynew, z: $znew, yaw: $yawnew, shouldCheckForAgentID: False}")" + fi + if [ "$command" == "student" ]; then + "$(rostopic pub -1 /$ROS_NAMESPACE/$agentnamespace/StudentControllerService/RequestSetpointChange dfall_pkg/SetpointWithHeader "{x: $xnew, y: $ynew, z: $znew, yaw: $yawnew, shouldCheckForAgentID: False}")" + fi + # + # Return that the message was sent + echo "sent" + +else + echo "ROS Master not found" +fi + +# DEBUGGING: For testing directly in terminal +# rostopic pub -1 /dfall/agent001/DefaultControllerService/RequestSetpointChange dfall_pkg/SetpointWithHeader {x: 0.0, y: 0.0, z: 0.1, yaw: 0, shouldCheckForAgentID: False} \ No newline at end of file diff --git a/web_interface/html/bashscripts/roscore.sh b/web_interface/html/bashscripts/roscore.sh new file mode 100755 index 0000000000000000000000000000000000000000..36be7a3807b3208d28012c7b89fefeb7977649fe --- /dev/null +++ b/web_interface/html/bashscripts/roscore.sh @@ -0,0 +1,5 @@ +#!/bin/bash +echo "Now attempting roscore" +source /opt/ros/melodic/setup.bash +roscore +echo "...attemp complete." diff --git a/web_interface/html/bashscripts/rosnodeList.sh b/web_interface/html/bashscripts/rosnodeList.sh new file mode 100755 index 0000000000000000000000000000000000000000..bec3e55d01fa9712e20548db963a00ec5c828e9a --- /dev/null +++ b/web_interface/html/bashscripts/rosnodeList.sh @@ -0,0 +1,3 @@ +#!/bin/bash +source /opt/ros/melodic/setup.bash +rosnode list \ No newline at end of file diff --git a/web_interface/html/callBashScript.php b/web_interface/html/callBashScript.php new file mode 100644 index 0000000000000000000000000000000000000000..a89f9031b6558eb93c6bcbadabf79dc6280156cc --- /dev/null +++ b/web_interface/html/callBashScript.php @@ -0,0 +1,87 @@ +<?php + // Get the bash script name + $scriptname = $_GET['scriptname']; + + // ONLY EXECUTE NAMES WITH AN EXACT MATHC + + + // For the GIT tab + if ($scriptname == "gitStatus") { + $temp = shell_exec("./bashscripts/gitStatus.sh"); + $output = "<pre>$temp</pre>"; + } + elseif ($scriptname == "gitPull") { + $temp = shell_exec("./bashscripts/gitPull.sh"); + $output = "<pre>$temp</pre>"; + } + elseif ($scriptname == "gitDiff") { + $temp = shell_exec("./bashscripts/gitDiff.sh"); + $output = "<pre>$temp</pre>"; + } + elseif ($scriptname == "gitCheckoutAll") { + $temp = shell_exec("./bashscripts/gitCheckoutAll.sh"); + $output = "<pre>$temp</pre>"; + } + elseif ($scriptname == "gitCheckoutMaster") { + $temp = shell_exec("./bashscripts/gitCheckoutMaster.sh"); + $output = "<pre>$temp</pre>"; + } + elseif ($scriptname == "catkin_make") { + $temp = shell_exec("./bashscripts/catkin_make.sh"); + $output = "<pre>$temp</pre>"; + } + // For the LAUNCH tab + elseif ($scriptname == "checkForRosMaster") { + $output = shell_exec("./bashscripts/checkForRosMaster.sh"); + } + elseif ($scriptname == "checkForRosAgent") { + $output = shell_exec("./bashscripts/checkForRosAgent.sh"); + } + elseif ($scriptname == "checkForRosAgent") { + $output = shell_exec("./bashscripts/checkForRosAgent.sh"); + } + elseif ($scriptname == "launchRosAgent") { + $output = shell_exec("./bashscripts/launchRosAgent.sh"); + } + elseif ($scriptname == "killRosAgent") { + $output = shell_exec("./bashscripts/killRosAgent.sh"); + } + elseif ($scriptname == "rosnodeList") { + $temp = shell_exec("./bashscripts/rosnodeList.sh"); + $output = "<pre>$temp</pre>"; + } + // For the CONTROL tab: + // { RADIO CONNECTION, TAKE-OFF, LAND, MOTORS-OFF, LOAD CONTROLLER } + elseif ($scriptname == "rosConnect") { + $output = shell_exec("./bashscripts/rosCrazyRadioCommand_forAgent.sh 0"); + } + elseif ($scriptname == "rosDisconnect") { + $output = shell_exec("./bashscripts/rosCrazyRadioCommand_forAgent.sh 1"); + } + elseif ($scriptname == "rosTakeoff") { + $output = shell_exec("./bashscripts/rosFlyingStateCommand_forAgent.sh 11"); + } + elseif ($scriptname == "rosLand") { + $output = shell_exec("./bashscripts/rosFlyingStateCommand_forAgent.sh 12"); + } + elseif ($scriptname == "rosMotorsoff") { + $output = shell_exec("./bashscripts/rosFlyingStateCommand_forAgent.sh 13"); + } + elseif ($scriptname == "rosEnabledefault") { + $output = shell_exec("./bashscripts/rosFlyingStateCommand_forAgent.sh 1"); + } + elseif ($scriptname == "rosEnablestudent") { + $output = shell_exec("./bashscripts/rosFlyingStateCommand_forAgent.sh 3"); + } + // For the CONTROL tab: + // GET SETPOINT + elseif ($scriptname == "rosGetSetpointDefault") { + $output = shell_exec("./bashscripts/rosGetCurrentSetpoint_forAgent.sh default"); + } + elseif ($scriptname == "rosGetSetpointStudent") { + $output = shell_exec("./bashscripts/rosGetCurrentSetpoint_forAgent.sh student"); + } + + + echo "$output"; +?> diff --git a/web_interface/html/callBashScript_setNewSetpoint.php b/web_interface/html/callBashScript_setNewSetpoint.php new file mode 100644 index 0000000000000000000000000000000000000000..4d52c0c1f0dc0640df34478d43faae7bfbf41263 --- /dev/null +++ b/web_interface/html/callBashScript_setNewSetpoint.php @@ -0,0 +1,26 @@ +<?php + // GET THE BASH SCRIPT NAME + $scriptname = $_GET['scriptname']; + + // GET THE (x,y,z,yaw) VALUES OF THE NEW SETPOINT + $x_new = $_GET['x']; + $y_new = $_GET['y']; + $z_new = $_GET['z']; + $yaw_new = $_GET['yaw']; + + + + // ONLY EXECUTE NAMES WITH AN EXACT MATHC + + // For the CONTROL tab: + // GET SETPOINT + if ($scriptname == "rosSetSetpointDefault") { + $output = shell_exec("./bashscripts/rosSetNewSetpoint_forAgent.sh default $x_new $y_new $z_new $yaw_new"); + } + elseif ($scriptname == "rosSetSetpointStudent") { + $output = shell_exec("./bashscripts/rosSetNewSetpoint_forAgent.sh student $x_new $y_new $z_new $yaw_new"); + } + + + echo "$output"; +?> diff --git a/web_interface/html/checkForRosAgent.php b/web_interface/html/checkForRosAgent.php new file mode 100644 index 0000000000000000000000000000000000000000..df0985966207e723a7d6c4972e81fdac52620cc4 --- /dev/null +++ b/web_interface/html/checkForRosAgent.php @@ -0,0 +1,4 @@ +<?php + $output = shell_exec("./checkForRosAgent.sh"); + echo "$output"; +?> diff --git a/web_interface/html/checkForRosMaster.php b/web_interface/html/checkForRosMaster.php new file mode 100644 index 0000000000000000000000000000000000000000..db6b26f8aaac3bce7180f58664f5f2be59430077 --- /dev/null +++ b/web_interface/html/checkForRosMaster.php @@ -0,0 +1,11 @@ +<?php + $output = shell_exec("./checkForRosMaster.sh"); + if ($output == 1) + { + echo "exists"; + } + else + { + echo "not found"; + } +?> diff --git a/web_interface/html/css/body.css b/web_interface/html/css/body.css new file mode 100644 index 0000000000000000000000000000000000000000..021b02f565784c7234f6f53c110dcd96715dcfca --- /dev/null +++ b/web_interface/html/css/body.css @@ -0,0 +1,112 @@ +/* RESTRICT PAGE WIDTH TO A MAXIMUM */ +.body-container +{ + position: relative; + margin-top: 0px; + margin-bottom: 0px; + margin-left: 0px; + margin-right: 0px; + max-width: 800px; + padding: 0px; +} + + +/* MAIN STYLE */ +.body-container > main +{ + color: black; + font-family: 'Lato', Arial, sans-serif; + font-weight: 400; + margin-top: 0px; + margin-bottom: 0px; + margin-left: 0px; + margin-right: 0px; + padding-top: 0.2em; + padding-bottom: 1em; + padding-left: 30px; + padding-right: 30px; + text-align: left; + background: rgba(0,0,0,0.0); +} + +.body-container > main a +{ + color: #a5d0ff; + text-decoration: none; + outline: none; +} + +.body-container > main a:hover +{ + color: #60abff; +} + +.body-container > main h1 +{ + font-size: 3.2em; + line-height: 1.3; + margin: 0px; + font-weight: 350; +} + +.body-container > main h2 +{ + font-size: 1.4em; + line-height: 1.3; + margin: 0px; + padding-top: 0.1em; + padding-bottom: 0.2em; + padding-left: 20px; + padding-right: 20px; + font-weight: 400; +} + +.body-container > main span +{ + display: block; + font-size: 55%; + color: black; + padding: 0 0 0.6em 0.1em; +} + +.hr-basic +{ + background-color: white; + width: 100%; + height: 2px; + border: 0px solid black; +} + +.hr-basic.navy +{ + background-color: #34495E; +} + + +/* SETTINGS FOR WHEN THE SCREEN IS SMALL */ +/* IMPORTANT NOTES: + The <meta> tag in the <head> of the page is + very important for determining the behaviour + this media trigger, i.e., the tag: + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + For example, with this tag the iPhone SE has + a "max-width"=320 and the same font sizes work + (approximately) on both a computer/laptop + browser and a smartphone browser. Whereas, + without this tag the iPhone SE has a + "mx-width"=768 and the sizes are much too small + when viewed on a smartphone. +*/ +@media screen and (max-width: 420px) +{ + .body-container > main + { + padding-top: 0.2em; + padding-bottom: 1em; + padding-left: 0px; + padding-right: 0px; + font-size: 100%; + text-align: left; + //background: rgba(0,255,0,1.0); + } +} diff --git a/web_interface/html/css/buttons.css b/web_interface/html/css/buttons.css new file mode 100644 index 0000000000000000000000000000000000000000..b64a03fab2be3a81058859fac3a9b13e8ac38833 --- /dev/null +++ b/web_interface/html/css/buttons.css @@ -0,0 +1,380 @@ +.setpoint-label-cell +{ + margin: 0; + padding-top: 2px; + padding-bottom: 2px; + font-size: 1.4em; + font-weight: bold; + text-align: center; + +} + +.setpoint-increment-cell +{ + margin: 0; + padding-top: 5px; + padding-bottom: 5px; +} + +.setpoint-input-field-cell +{ + margin: 0; + padding-top: 5px; + padding-bottom: 5px; +} + +.setpoint-input-field +{ + width:7em; + margin: 0; + padding-top: 5px; + padding-bottom: 5px; + font-size: 1.4em; + font-family: monospace; + text-align: right; +} + +.button-push +{ + position: relative; + background-color: #ddd; + border: 1px solid #bbb; + border-radius: 6px; + color: #555; + text-shadow: 0 1px 0 rgba(0,0,0,.2); + margin: 0px; + padding-left: 30px; + padding-right: 30px; + padding-top: 15px; + padding-bottom: 15px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 1.4em; + cursor: grabbing; + + overflow: hidden; +} + + +.button-push:hover +{ + background-color: #eee; +} + +.button-push:active +{ + background: #e9e9e9; + top: 1px; + text-shadow: none; + box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset; + + +} + +.button-push > .div-for-button-highlight-on-touchscreen +{ + content: "test"; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + padding-bottom: 0; + border-radius: 0px; + background-color: #000; + transform: scale(1.0); + opacity: 0.0; +} + + +.div-for-button-highlight-on-touchscreen.red{ background-color: #000;} +.div-for-button-highlight-on-touchscreen.green{ background-color: #000;} +.div-for-button-highlight-on-touchscreen.blue{ background-color: #000;} +.div-for-button-highlight-on-touchscreen.navy{ background-color: #eee;} + + +/* THE FOLLOWING ACTUALLY ADDS THE ANIMATION */ +/* +.button-push:focus:not(:active) > .div-for-button-highlight-on-touchscreen +{ + animation: click-animation 0.6s linear; + animation-fill-mode: backwards; +} +*/ + +@keyframes click-animation { + 0% { + opacity: 0.2; + transform: scale(1.0); + } + 50% { + opacity: 0.50; + transform: scale(1.0); + } + 70% { + opacity: 0.5; + transform: scale(1.0); + } + 100% { + opacity: 0; + transform: scale(1.0); + } +} + + + + + + + + + +/* SET THE DISPLAY STYLE TO BLOCK */ +.button-push.fullwidth +{ + display: block; + width: 100%; +} + +/* SET THE FONT TO A FIXED WIDTH FONT */ +.button-push.monospace +{ + font-family: monospace; +} + +/* SET THE TOP AND BOTTOM SPACING TO BE SMALL */ +.button-push.short +{ + padding-top: 3px; + padding-bottom: 3px; +} +.button-push.short5 +{ + padding-top: 5px; + padding-bottom: 5px; +} +.button-push.short10 +{ + padding-top: 5px; + padding-bottom: 5px; +} + +/* SET THE LEFT AND RIGHT SPACING TO BE SMALL */ +.button-push.slim +{ + padding-left: 10px; + padding-right: 10px; +} + +/* SET SIZING FOR THE MOTORS-OFF BUTTON */ +.button-push.motorsoff +{ + display: block; + width: 100%; + text-align: center; + font-weight: 600; +} + +/* SET SIZING FOR THE MOTORS-OFF BUTTON */ +.button-push.info +{ + display: inline + width: 100%; + text-align: center; + font-weight: bolder; + font-size: 24px!important; + padding: 8px 20px; + vertical-align: middle; + overflow: hidden; + text-decoration: none; + white-space:nowrap; + border-radius: 50%; +} + + + + + +/* SET THE APPEARANCE FOR WHEN DISABLED */ +.button-push[disabled], .button-push[disabled]:hover, .button-push[disabled]:active +{ + border-color: #eaeaea; + background: #fafafa; + cursor: default; + position: static; + color: #999; + /* Usually, !important should be avoided but here it's really needed :) */ + /* + -moz-box-shadow: none !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + text-shadow: none !important; + */ + +} + + +/* SET COLOURS FOR RED BUTTON */ +.button-push.red +{ + background-color: #f44336; + border-color: #c43c35; + color: white; +} + +.button-push.red:hover +{ + background-color: #ee5f5b; +} + +.button-push.red:active +{ + background: #c43c35; +} + +.red[disabled], .red[disabled]:hover, .red[disabled]:active +{ + border-color: #C43C35; + background: #C43C35; + color: #FFD3D3; +} + + +/* SET COLOURS FOR GREEN BUTTON */ +.button-push.green +{ + background-color: #57a957; + border-color: #57a957; + color: white; +} + +.button-push.green:hover +{ + background-color: #62c462; +} + +.button-push.green:active +{ + background: #57a957; +} + +.green[disabled], .green[disabled]:hover, .green[disabled]:active +{ + border-color: #57A957; + background: #57A957; + color: #D2FFD2; +} + + +/* SET COLOURS FOR BLUE BUTTON */ +.button-push.blue +{ + background-color: #269CE9; + border-color: #269CE9; + color: white; +} + +.button-push.blue:hover +{ + background-color: #70B9E8; +} + +.button-push.blue:active +{ + background: #269CE9; +} + +.blue[disabled], .blue[disabled]:hover, .blue[disabled]:active +{ + border-color: #269CE9; + background: #269CE9; + color: #93D5FF; +} + +/* SET COLOURS FOR NAVY BUTTON */ +.button-push.navy +{ + background-color: #34495E; + border-color: #34495E; + color: white; +} + +.button-push.navy:hover +{ + background-color: #748DA6; +} + +.button-push.navy:active +{ + background: #34495E; +} + +.navy[disabled], .navy[disabled]:hover, .navy[disabled]:active +{ + border-color: #34495E; + background: #34495E; + color: #93D5FF; +} + + + + +/* SETTINGS FOR WHEN THE SCREEN IS SMALL */ +@media screen and (max-width: 420px) +{ + .button-push + { + padding-left: 10px; + padding-right: 10px; + padding-top: 10px; + padding-bottom: 10px; + font-size: 1.2em; + } + + .button-push.info + { + font-size: 28px!important; + padding: 8px 20px; + } + + /* MAKE THE HOVER COLOUR THE SAME AS THE NORMAL COLOUR */ + .button-push:hover{ background-color: #ddd; } + .button-push.red:hover{ background-color: #f44336;} + .button-push.green:hover{ background-color: #57a957;} + .button-push.blue:hover{ background-color: #269CE9;} + .button-push.navy:hover{ background-color: #34495E;} + + /* SET THE DISABLED HOVER COLOUR */ + /* NEEDED AGAIN DESPITE BEING DONE ABOVE */ + .red[disabled]:hover + { + border-color: #C43C35; + background: #C43C35; + color: #FFD3D3; + } + .green[disabled]:hover + { + border-color: #57A957; + background: #57A957; + color: #D2FFD2; + } + .blue[disabled]:hover + { + border-color: #269CE9; + background: #269CE9; + color: #93D5FF; + } + .navy[disabled]:hover + { + border-color: #34495E; + background: #34495E; + color: #93D5FF; + } + + .button-push:hover:not(:active) > .div-for-button-highlight-on-touchscreen + { + animation: click-animation 0.7s ease-out; + } + +} diff --git a/web_interface/html/css/buttons_from_some_website.css b/web_interface/html/css/buttons_from_some_website.css new file mode 100644 index 0000000000000000000000000000000000000000..54e8dbe95480bf955682afaa6778da9559ec3aaa --- /dev/null +++ b/web_interface/html/css/buttons_from_some_website.css @@ -0,0 +1,250 @@ +/* + TAKEN FROM: + https://codepen.io/ben_jammin/pen/syaCq +*/ + +/* +body{ + background:url(http://subtlepatterns.subtlepatterns.netdna-cdn.com/patterns/wild_oliva.png); +} +*/ + +.centered { + margin:50px auto; + text-align:center; +} + +.button::-moz-focus-inner{ + border: 0; + padding: 0; +} + +.button{ + display: inline-block; + *display: inline; + zoom: 1; + padding: 6px 20px; + margin: 0; + cursor: pointer; + border: 1px solid #bbb; + overflow: visible; + font: bold 13px arial, helvetica, sans-serif; + text-decoration: none; + white-space: nowrap; + color: #555; + + background-color: #ddd; + background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,1)), to(rgba(255,255,255,0))); + background-image: -webkit-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0)); + background-image: -moz-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0)); + background-image: -ms-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0)); + background-image: -o-linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0)); + background-image: linear-gradient(top, rgba(255,255,255,1), rgba(255,255,255,0)); + + -webkit-transition: background-color .2s ease-out; + -moz-transition: background-color .2s ease-out; + -ms-transition: background-color .2s ease-out; + -o-transition: background-color .2s ease-out; + transition: background-color .2s ease-out; + background-clip: padding-box; /* Fix bleeding */ + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, .3), 0 2px 2px -1px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .3) inset; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, .3), 0 2px 2px -1px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .3) inset; + box-shadow: 0 1px 0 rgba(0, 0, 0, .3), 0 2px 2px -1px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .3) inset; + text-shadow: 0 1px 0 rgba(255,255,255, .9); + + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.button:hover{ + background-color: #eee; + color: #555; +} + +.button:active{ + background: #e9e9e9; + position: relative; + top: 1px; + text-shadow: none; + -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset; + box-shadow: 0 1px 1px rgba(0, 0, 0, .3) inset; +} + +.button[disabled], .button[disabled]:hover, .button[disabled]:active{ + border-color: #eaeaea; + background: #fafafa; + cursor: default; + position: static; + color: #999; + /* Usually, !important should be avoided but here it's really needed :) */ + -moz-box-shadow: none !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + text-shadow: none !important; +} + +/* Smaller buttons styles */ + +.button.small{ + padding: 4px 12px; +} + +/* Larger buttons styles */ + +.button.large{ + padding: 12px 30px; + text-transform: uppercase; +} + +.button.large:active{ + top: 2px; +} + +/* Colored buttons styles */ + +.button.green, .button.red, .button.blue { + color: #fff; + text-shadow: 0 1px 0 rgba(0,0,0,.2); + + background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.3)), to(rgba(255,255,255,0))); + background-image: -webkit-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0)); + background-image: -moz-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0)); + background-image: -ms-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0)); + background-image: -o-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0)); + background-image: linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0)); +} + +/* */ + +.button.green{ + background-color: #57a957; + border-color: #57a957; +} + +.button.green:hover{ + background-color: #62c462; +} + +.button.green:active{ + background: #57a957; +} + +/* */ + +.button.red{ + background-color: #ca3535; + border-color: #c43c35; +} + +.button.red:hover{ + background-color: #ee5f5b; +} + +.button.red:active{ + background: #c43c35; +} + +/* */ + +.button.blue{ + background-color: #269CE9; + border-color: #269CE9; +} + +.button.blue:hover{ + background-color: #70B9E8; +} + +.button.blue:active{ + background: #269CE9; +} + +/* */ + +.green[disabled], .green[disabled]:hover, .green[disabled]:active{ + border-color: #57A957; + background: #57A957; + color: #D2FFD2; +} + +.red[disabled], .red[disabled]:hover, .red[disabled]:active{ + border-color: #C43C35; + background: #C43C35; + color: #FFD3D3; +} + +.blue[disabled], .blue[disabled]:hover, .blue[disabled]:active{ + border-color: #269CE9; + background: #269CE9; + color: #93D5FF; +} + +/* Group buttons */ + +.button-group, +.button-group li{ + display: inline-block; + *display: inline; + zoom: 1; +} + +.button-group{ + font-size: 0; /* Inline block elements gap - fix */ + margin: 0; + padding: 0; + background: rgba(0, 0, 0, .1); + border-bottom: 1px solid rgba(0, 0, 0, .1); + padding: 7px; + -moz-border-radius: 7px; + -webkit-border-radius: 7px; + border-radius: 7px; +} + +.button-group li{ + margin-right: -1px; /* Overlap each right button border */ +} + +.button-group .button{ + font-size: 13px; /* Set the font size, different from inherited 0 */ + -moz-border-radius: 0; + -webkit-border-radius: 0; + border-radius: 0; +} + +.button-group .button:active{ + -moz-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset; + -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset; + box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset; +} + +.button-group li:first-child .button{ + -moz-border-radius: 3px 0 0 3px; + -webkit-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} + +.button-group li:first-child .button:active{ + -moz-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset; + -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset; + box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, -5px 0 5px -3px rgba(0, 0, 0, .2) inset; +} + +.button-group li:last-child .button{ + -moz-border-radius: 0 3px 3px 0; + -webkit-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} + +.button-group li:last-child .button:active{ + -moz-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset; + -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset; + box-shadow: 0 0 1px rgba(0, 0, 0, .2) inset, 5px 0 5px -3px rgba(0, 0, 0, .2) inset; +} \ No newline at end of file diff --git a/web_interface/html/css/default.css b/web_interface/html/css/default.css new file mode 100644 index 0000000000000000000000000000000000000000..036f5f4219b938d58b38f083aef8b0d4da57b95b --- /dev/null +++ b/web_interface/html/css/default.css @@ -0,0 +1,8 @@ +/* IMPORT THE FONT */ +@import url(https://fonts.googleapis.com/css?family=Lato:300,400,700); + +/* SET THE BACKGROUND COLOUR */ +body +{ + background: #34495e; +} \ No newline at end of file diff --git a/web_interface/html/css/layout.css b/web_interface/html/css/layout.css new file mode 100644 index 0000000000000000000000000000000000000000..a4430fbe02b143fb4b1d9aad461656f56c5fb0e3 --- /dev/null +++ b/web_interface/html/css/layout.css @@ -0,0 +1,312 @@ +.full-window-fixed +{ + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background: #34495E; + width: 100%; + margin: 0; + padding: 0; +} + +.max-width-full-heigth-fixed +{ + color: #fff; + font-family: 'Lato', Arial, sans-serif; + position: fixed; + top: 0; + bottom: 0; + left: 0px; + right: 0px; + margin-top: 0px; + margin-bottom: 0px; + margin-left: auto; + margin-right: auto; + max-width: 800px; + padding: 0px; + background: rgba(0,0,0,0.10); +} + +.top-bar-container +{ + color: #fff; + font-family: 'Lato', Arial, sans-serif; + position: relative; + margin-top: 0px; + margin-bottom: 0px; + margin-left: 0px; + margin-right: 0px; + max-width: 800px; + padding: 0px; + background: none; +} + +.top-bar-buttons-table +{ + position: relative; + width: 100%; + border: none; + border-spacing: 0px; + padding-top: 10px; + padding-bottom: 10px; + padding-left: 20px; + padding-right: 20px; + background: none; +} + +.top-bar-motorsoff-button-cell +{ + padding-right: 10px; +} + +.top-bar-info-button-cell +{ + width: 20px; +} + +.top-bar-title +{ + position: relative; + width: 100%; + text-align: center; + font-size: 2.0em; + font-weight: 600; + padding-top: 0px; + padding-bottom: 0px; + padding-left: 0px; + padding-right: 0px; + background: none; + white-space: nowrap; + overflow-x: hidden; +} +.top-bar-title.padbelow +{ + padding-bottom: 10px; +} + +.top-bar-subtitle +{ + position: relative; + width: 100%; + text-align: center; + font-size: 1.2em; + font-weight: 400; + padding-top: 0px; + padding-bottom: 0px; + padding-left: 0px; + padding-right: 0px; + background: none; + white-space: nowrap; + overflow-x: hidden; +} + +.top-bar-subtitle.padbelow +{ + padding-bottom: 10px; +} + + +.ros-table +{ + position: relative; + width: 100%; + table-layout: fixed; + border-spacing: 0px; + padding-top: 0px; + padding-bottom: 0px; + padding-left: 0px; + padding-right: 0px; + background: none; + //border: 1px solid black; +} + +.ros-button-cell +{ + width: 50%; + padding-top: 5px; + padding-bottom: 5px; + padding-left: 0px; + padding-right: 0px; + //border: 1px solid black; +} + +.ros-info-cell +{ + padding-left: 10px; + padding-right: 10px; + text-align: left; + //border: 1px solid black; +} + +.git-table +{ + position: relative; + width: 100%; + table-layout: fixed; + border-spacing: 0px; + margin: 0px; + padding-top: 0px; + padding-bottom: 0px; + padding-left: 0px; + padding-right: 0px; + background: none; + //border: 1px solid black; +} + +.git-button-cell +{ + width: 50%; + margin: 0px; + padding-top: 5px; + padding-bottom: 5px; + padding-left: 5px; + padding-right: 5px; + //border: 1px solid black; +} + +.git-button-cell.left +{ + padding-left: 0px; +} + +.git-button-cell.right +{ + padding-right: 0px; +} + + +.git-checkout-label +{ + color: #f44336; + font-family: monospace; + font-size: 1.4em; + font-weight: bold; + text-align: center; + margin-top: 10px; +} + + +.terminal-label-table +{ + position: relative; + table-layout: fixed; + border-spacing: 0px; + margin-left: auto; + margin-right: auto; + margin-bottom: 3px; + padding: 0px; + background: none; + //border: 1px solid black; +} + +.terminal-label-cell +{ + padding-right: 5px; +} + +.terminal-label +{ + color: #34495E; + font-family: monospace; + font-size: 1.4em; + font-weight: bold; + text-align: center; +} + +.terminal-background +{ + position: relative; + width: 100%; + color: white; + background-color: #34495E; + margin: 0px; + padding-top: 10px; + padding-bottom: 10px; + padding-left: 0px; + padding-right: 0px; + border-radius: 5px; + overflow-x: auto; +} + +.terminal-contents +{ + position: relative; + color: white; + background-color: none; + margin-top: 0px; + margin-bottom: 0px; + margin-left: 5px; + margin-right: 5px; + padding: 0px; +} + +.terminal-highligh-paragraph +{ + color: white; + background-color: #269CE9; + text-align: center; +} + +.centered-table +{ + position: relative; + //table-layout: fixed; + border-spacing: 0px; + padding-top: 0px; + padding-bottom: 0px; + padding-left: 0px; + padding-right: 0px; + margin-left: auto; + margin-right: auto; + background: none; + //border: 1px solid black; +} + +.centered-table-button-cell +{ + margin: 0px; + padding-top: 5px; + padding-bottom: 5px; + padding-left: 5px; + padding-right: 5px; + //border: 1px solid black; +} + + +/* SETTINGS FOR WHEN THE SCREEN IS SMALL */ +@media screen and (max-width: 420px) +{ + .top-bar-title + { + font-size: 1.5em; + } + + .top-bar-title.padbelow + { + padding-bottom: 5px; + } + + .top-bar-subtitle + { + font-size: 1.0em; + } + + .top-bar-subtitle.padbelow + { + padding-bottom: 5px; + } + + .ros-button-cell + { + width: 60%; + } + + .terminal-background + { + width: 86%; + margin-left: 7%; + } + +} \ No newline at end of file diff --git a/web_interface/html/css/tabs_control.css b/web_interface/html/css/tabs_control.css new file mode 100644 index 0000000000000000000000000000000000000000..e02f56e944e701e22a3cbfd33411e983aa4a2fa0 --- /dev/null +++ b/web_interface/html/css/tabs_control.css @@ -0,0 +1,119 @@ +.control-tabs +{ + display: flex; + flex-wrap: wrap; + background: #efefef; + border: 1pt solid #34495E; + box-shadow: 0 48px 80px -32px rgba(0,0,0,0.3); + //top: 0px; + //bottom: 0px; + margin: 0px; +} + +.control-tab-input { + position: absolute; + opacity: 0; +} + +.control-tab-label +{ + width: auto; + padding-left: 30px; + padding-right: 30px; + padding-top: 20px; + padding-bottom: 20px; + background: #e5e5e5; + cursor: pointer; + font-weight: bold; + font-size: 18px; + color: #7f7f7f; + transition: background 0.0s, color 0.0s; +} + +.control-tab-label:hover +{ + background: #d8d8d8; +} + +.control-tab-label:active +{ + background: #ccc; +} + +.control-tab-input:focus + .control-tab-label +{ + /*box-shadow: inset 0px 0px 0px 3px #2aa1c0*/; + z-index: 1; +} + +.control-tab-input:checked + .control-tab-label +{ + background: #fff; + color: #000; +} + +.control-tab-panel +{ + order: 99; + display: none; + position: relative; + margin-top: 0px; + margin-bottom: 0px; + margin-left: 0px; + margin-right: 0px; + width:100%; + padding-left: 20px; + padding-right: 20px; + padding-top: 10px; + padding-bottom: 10px; + background: #fff; + color:black; + overflow: hidden; + overflow-y: scroll; +} + +/* Make the respective panel visible when its tab-input is checked */ +.control-tab-input:checked + .control-tab-label + .control-tab-panel +{ + display: block; +} + + + + +/* SETTINGS FOR WHEN THE SCREEN IS SMALL */ +@media screen and (max-width: 600px) +{ + /* Make it an accordian */ + .control-tab-label + { + width: 50%; + padding-left: 0px; + padding-right: 0px; + padding-top: 20px; + padding-bottom: 20px; + text-align: center; + } +} + +/* SETTINGS FOR WHEN THE SCREEN IS SMALL */ +@media screen and (max-width: 420px) +{ + /* Make it an accordian */ + .control-tab-label + { + width: 50%; + padding-left: 0px; + padding-right: 0px; + padding-top: 15px; + padding-bottom: 15px; + text-align: center; + } + + .control-tab-panel + { + padding-left: 10px; + padding-right: 10px; + } + +} \ No newline at end of file diff --git a/web_interface/html/css/tabs_home.css b/web_interface/html/css/tabs_home.css new file mode 100644 index 0000000000000000000000000000000000000000..0521ec250201be97c8052ba2ec61d3d73947c1b4 --- /dev/null +++ b/web_interface/html/css/tabs_home.css @@ -0,0 +1,135 @@ +.home-tabs +{ + display: flex; + flex-wrap: wrap; + background: #efefef; + //box-shadow: 0 48px 80px -32px rgba(0,0,0,0.3); + top: 0px; + bottom: 0px; + margin: 0px; +} + +.home-tab-input { + position: absolute; + opacity: 0; +} + +.home-tab-label +{ + width: auto; + padding-left: 30px; + padding-right: 30px; + padding-top: 20px; + padding-bottom: 20px; + background: #e5e5e5; + cursor: pointer; + font-weight: bold; + font-size: 18px; + color: #7f7f7f; + transition: background 0.0s, color 0.0s; +} + +.home-tab-label:hover +{ + background: #d8d8d8; +} + +.home-tab-label:active +{ + background: #ccc; +} + +.home-tab-input:focus + .home-tab-label +{ + /*box-shadow: inset 0px 0px 0px 3px #2aa1c0*/; + z-index: 1; +} + +.home-tab-input:checked + .home-tab-label +{ + background: #fff; + color: #000; +} + +.home-tab-panel +{ + order: 99; + display: none; + position: absolute; + top: 0; + bottom: 0; + left: 0px; + right: 0px; + top: 235px; + bottom: 0px; + margin-top: 0px; + margin-bottom: 0px; + margin-left: 0px; + margin-right: 0px; + max-width: 800px; + padding-left: 20px; + padding-right: 20px; + padding-top: 10px; + padding-bottom: 10px; + background: #fff; + color:black; + overflow: hidden; + overflow-y: auto; +} + +.home-tab-panel.thin-padding +{ + padding-left: 10px; + padding-right: 10px; +} + +/* Make the respective panel visible when its tab-input is checked */ +.home-tab-input:checked + .home-tab-label + .home-tab-panel +{ + display: block; +} + + + + +/* SETTINGS FOR WHEN THE SCREEN IS SMALL */ +@media screen and (max-width: 600px) +{ + /* Make it an accordian */ + .home-tab-label + { + width: 25%; + padding-left: 0px; + padding-right: 0px; + padding-top: 20px; + padding-bottom: 20px; + text-align: center; + } +} + +/* SETTINGS FOR WHEN THE SCREEN IS SMALL */ +@media screen and (max-width: 420px) +{ + /* Make it an accordian */ + .home-tab-label + { + width: 50%; + padding-left: 0px; + padding-right: 0px; + padding-top: 10px; + padding-bottom: 10px; + text-align: center; + } + + .home-tab-panel + { + top: 185px; + } + + .home-tab-panel.thin-padding + { + padding-left: 5px; + padding-right: 5px; + } + +} \ No newline at end of file diff --git a/web_interface/html/css/tabs_main.css b/web_interface/html/css/tabs_main.css new file mode 100644 index 0000000000000000000000000000000000000000..3be20ea54bacb7e767fb3c654d6911524111220f --- /dev/null +++ b/web_interface/html/css/tabs_main.css @@ -0,0 +1,135 @@ +.main-tabs +{ + display: flex; + flex-wrap: wrap; + background: #efefef; + //box-shadow: 0 48px 80px -32px rgba(0,0,0,0.3); + top: 0px; + bottom: 0px; + margin: 0px; +} + +.main-tab-input { + position: absolute; + opacity: 0; +} + +.main-tab-label +{ + width: auto; + padding-left: 30px; + padding-right: 30px; + padding-top: 20px; + padding-bottom: 20px; + background: #e5e5e5; + cursor: pointer; + font-weight: bold; + font-size: 18px; + color: #7f7f7f; + transition: background 0.0s, color 0.0s; +} + +.main-tab-label:hover +{ + background: #d8d8d8; +} + +.main-tab-label:active +{ + background: #ccc; +} + +.main-tab-input:focus + .main-tab-label +{ + /*box-shadow: inset 0px 0px 0px 3px #2aa1c0*/; + z-index: 1; +} + +.main-tab-input:checked + .main-tab-label +{ + background: #fff; + color: #000; +} + +.main-tab-panel +{ + order: 99; + display: none; + position: absolute; + top: 0; + bottom: 0; + left: 0px; + right: 0px; + top: 189px; + bottom: 0px; + margin-top: 0px; + margin-bottom: 0px; + margin-left: 0px; + margin-right: 0px; + max-width: 800px; + padding-left: 20px; + padding-right: 20px; + padding-top: 10px; + padding-bottom: 10px; + background: #fff; + color:black; + overflow: hidden; + overflow-y: auto; +} + +.main-tab-panel.thin-padding +{ + padding-left: 10px; + padding-right: 10px; +} + +/* Make the respective panel visible when its tab-input is checked */ +.main-tab-input:checked + .main-tab-label + .main-tab-panel +{ + display: block; +} + + + + +/* SETTINGS FOR WHEN THE SCREEN IS SMALL */ +@media screen and (max-width: 600px) +{ + /* Make it an accordian */ + .main-tab-label + { + width: 25%; + padding-left: 0px; + padding-right: 0px; + padding-top: 20px; + padding-bottom: 20px; + text-align: center; + } +} + +/* SETTINGS FOR WHEN THE SCREEN IS SMALL */ +@media screen and (max-width: 420px) +{ + /* Make it an accordian */ + .main-tab-label + { + width: 25%; + padding-left: 0px; + padding-right: 0px; + padding-top: 10px; + padding-bottom: 10px; + text-align: center; + } + + .main-tab-panel + { + top: 147px; + } + + .main-tab-panel.thin-padding + { + padding-left: 5px; + padding-right: 5px; + } + +} \ No newline at end of file diff --git a/web_interface/html/home_tab_about.html b/web_interface/html/home_tab_about.html new file mode 100644 index 0000000000000000000000000000000000000000..fdceac46c3b02e0aa99a8ab4c149d0ca8f4c1693 --- /dev/null +++ b/web_interface/html/home_tab_about.html @@ -0,0 +1,11 @@ +<body> + <div class="body-container"> + <main style="text-align:left;"> + + <br> + + Coming soon... + + </main> + </div> +</body> \ No newline at end of file diff --git a/web_interface/html/home_tab_enter.html b/web_interface/html/home_tab_enter.html new file mode 100644 index 0000000000000000000000000000000000000000..9cbf127f892620c7e8849930f5fdd07de1e54251 --- /dev/null +++ b/web_interface/html/home_tab_enter.html @@ -0,0 +1,33 @@ +<body> + <div class="body-container"> + <main style="text-align:left;"> + + <br> + + <button class="button-push navy" onclick="window.location.href='agent.php'"> + Enter as Agent + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + + <br> + + <p> + The agent interface allows you to transfer and compile code, launch the ROS nodes, and control the agent. + </p> + + <br><br><br> + + <button class="button-push navy" onclick="window.location.href='coord.php'"> + Enter as Coordinator + <div class="div-for-button-highlight-on-touchscreen navy"></div> + </button> + + <br> + + <p> + The coordinator interface allows you to compile code, launch the ROS nodes, and control multiple agents simultaneously. + </p> + + </main> + </div> +</body> \ No newline at end of file diff --git a/web_interface/html/index.php b/web_interface/html/index.php new file mode 100644 index 0000000000000000000000000000000000000000..80216f485e17899c2ca4c2fa058d1ffdc569b76b --- /dev/null +++ b/web_interface/html/index.php @@ -0,0 +1,60 @@ +<?php + include("page_header.html"); +?> + +<div class="full-window-fixed"> +</div> + +<div class="max-width-full-heigth-fixed"> + + <div class="top-bar-container"> + <table class="top-bar-buttons-table"> + <tr> + <td class="top-bar-motorsoff-button-cell"> + <button class="button-push red motorsoff" disabled onclick="checkForRosAgent()"> + MOTORS-OFF + </button> + </td> + <td class="top-bar-info-button-cell"> + <button class="button-push blue info" onclick="checkForRosAgent()"> + i + <div class="div-for-button-highlight-on-touchscreen blue"></div> + </button> + </td> + </tr> + </table> + + <div class="top-bar-title"> + Browser Interface + </div> + <div class="top-bar-subtitle"> + for the D-FaLL System + </div> + <div class="top-bar-subtitle padbelow"> + Connected to IP <?php echo $_SERVER['REMOTE_ADDR']; ?> + </div> + </div> + + <div class="home-tabs"> + <input name="tabs" type="radio" id="home-tab-1" checked="checked" class="home-tab-input"/> + <label for="home-tab-1" class="home-tab-label">Enter</label> + <div class="home-tab-panel"> + <?php + include("home_tab_enter.html"); + ?> + </div> + + <input name="tabs" type="radio" id="home-tab-2" class="home-tab-input"/> + <label for="home-tab-2" class="home-tab-label">About</label> + <div class="home-tab-panel"> + <?php + include("home_tab_about.html"); + ?> + </div> + </div> +</div> + + +<?php + include("page_footer.html"); +?> \ No newline at end of file diff --git a/web_interface/html/js/callbashscript.js b/web_interface/html/js/callbashscript.js new file mode 100644 index 0000000000000000000000000000000000000000..d4a563fd00b616af2335de63f62d92a827083b2b --- /dev/null +++ b/web_interface/html/js/callbashscript.js @@ -0,0 +1,169 @@ +function callBashScript_outputLabelID_clearOtherLabels_clickOtherButtons(bashscript, labelID, otherLabels, otherbuttons) +{ + // Create a variable for sending an AJAX request + var xmlhttp = new XMLHttpRequest(); + // Add the function to be run when the response is recieved + xmlhttp.onreadystatechange = function() + { + if (this.readyState == 4 && this.status == 200) + { + // Construct the return string + var base_string = ""; + document.getElementById(labelID).innerHTML = base_string + this.responseText; + // Click the "other buttons" as requested + if (otherbuttons) + { + if ( typeof(otherbuttons) == "string" ) + { + document.getElementById(otherbuttons).click(); + } + else if (otherbuttons.constructor === Array) + { + for (otherButtonID of otherbuttons) + { + if (otherButtonID) + { + if ( typeof(otherButtonID) == "string" ) + { + document.getElementById(otherButtonID).click(); + } + } + } + } + } + + } + else + { + var display_message = getDisplayMessageForXMLHttpRequest(this); + document.getElementById(labelID).innerHTML = display_message; + } + }; + xmlhttp.open("GET", "callBashScript.php?scriptname=" + bashscript, true); + xmlhttp.send(); + + // Clear the other labels as requested + if (otherLabels) + { + if ( typeof(otherLabels) == "string" ) + { + document.getElementById(otherLabels).innerHTML = ""; + } + else if (otherLabels.constructor === Array) + { + for (otherLabelID of otherbuttons) + { + if (otherLabelID) + { + if ( typeof(otherLabelID) == "string" ) + { + document.getElementById(otherLabelID).innerHTML = ""; + } + } + } + } + } +} + + + +function getDisplayMessageForXMLHttpRequest(xmlhttp) +{ + var base_string = ""; + if (xmlhttp.readyState != 4) + { + base_string = base_string + "loading..."; + } + else + { + if (xmlhttp.status != 204) + { + base_string = base_string + "Error " + xmlhttp.status + ": no content."; + } + else if (xmlhttp.status != 403) + { + base_string = base_string + "Error " + xmlhttp.status + ": request forbidden."; + } + else if (xmlhttp.status != 404) + { + base_string = base_string + "Error " + xmlhttp.status + ": page not found."; + } + else if (xmlhttp.status != 500) + { + base_string = base_string + "Error " + xmlhttp.status + ": internal server error."; + } + else if (xmlhttp.status != 501) + { + base_string = base_string + "Error " + xmlhttp.status + ": no implemented."; + } + else if (xmlhttp.status != 502) + { + base_string = base_string + "Error " + xmlhttp.status + ": bd gateway."; + } + else if (xmlhttp.status != 503) + { + base_string = base_string + "Error " + xmlhttp.status + ": service unavailable."; + } + else if (xmlhttp.status != 504) + { + base_string = base_string + "Error " + xmlhttp.status + ": gateway timeout."; + } + else + { + base_string = base_string + "Error " + xmlhttp.status; + } + + } + // Finally return the string + return base_string; +} + + +function getErrorMessageForXMLHttpRequest(xmlhttp) +{ + var base_string = ""; + if (xmlhttp.readyState != 4 && xmlhttp.status != 200) + { + base_string = base_string + "readyState = " + xmlhttp.readyState + " and status = " + xmlhttp.status; + } + else if (xmlhttp.readyState != 4) + { + base_string = base_string + "status is good but readyState = " + xmlhttp.readyState; + } + else if (xmlhttp.status != 200) + { + base_string = base_string + "ready state is good but status = " + xmlhttp.status; + } + // Finally return the string + return base_string; +} + +/* +The "XMLHttpRequest" variable has the following: +> CALLBACK FUNCTION: onreadystatechange + Defines a function to be called when the readyState property changes + +> PROPERTY: readyState + Holds the status of the XMLHttpRequest. + 0: request not initialized + 1: server connection established + 2: request received + 3: processing request + 4: request finished and response is ready + +> PROPERTY status + 200: "OK" + 403: "Forbidden" + 404: "Page not found" + For a complete list go to the Http Messages Reference + +> PROPERTY statusText + Returns the status-text (e.g. "OK" or "Not Found") + +> PROPERTY responseText + Returns the server response as a JavaScript string + +For more details see: +https://www.w3schools.com/xml/ajax_xmlhttprequest_response.asp +https://www.w3schools.com/tags/ref_httpmessages.asp +*/ diff --git a/web_interface/html/js/callgit.js b/web_interface/html/js/callgit.js new file mode 100644 index 0000000000000000000000000000000000000000..a23174c6fb7de4f60457a8f633b6488043acd1bb --- /dev/null +++ b/web_interface/html/js/callgit.js @@ -0,0 +1,127 @@ +function callGit_outputLabelID_shouldAppend_shouldConfirm(gitCommand, labelID, shouldAppend, shouldConfirm) +{ + // Convert the "gitCommand" to a heding string + var heading_string = "<p class=\"terminal-highligh-paragraph\">"; + var scriptname_for_php = ""; + var confirm_alert_text = ""; + if (gitCommand == "status") + { + heading_string = heading_string + "GIT STATUS"; + scriptname_for_php = scriptname_for_php + "gitStatus"; + confirm_alert_text = confirm_alert_text + "This will check the status of the repository."; + } + else if (gitCommand == "pull") + { + heading_string = heading_string + "GIT PULL"; + scriptname_for_php = scriptname_for_php + "gitPull"; + confirm_alert_text = confirm_alert_text + "This will pull the latest changes, and may fail if there are any conflicts."; + } + else if (gitCommand == "diff") + { + heading_string = heading_string + "GIT DIFF"; + scriptname_for_php = scriptname_for_php + "gitDiff"; + confirm_alert_text = confirm_alert_text + "This will show the difference between the current status and the previous commit."; + } + else if (gitCommand == "checkout") + { + heading_string = heading_string + "GIT CHECKOUT ."; + scriptname_for_php = scriptname_for_php + "gitCheckout"; + confirm_alert_text = confirm_alert_text + "This remove any changes and those changes can NOT be recovered."; + } + else if (gitCommand == "checkoutall") + { + heading_string = heading_string + "GIT CHECKOUT ."; + scriptname_for_php = scriptname_for_php + "gitCheckoutAll"; + confirm_alert_text = confirm_alert_text + "This remove any changes and those changes can NOT be recovered."; + } + else if (gitCommand == "checkoutmaster") + { + heading_string = heading_string + "GIT CHECKOUT MASTER"; + scriptname_for_php = scriptname_for_php + "gitCheckoutMaster"; + confirm_alert_text = confirm_alert_text + "This switches branch and the web interface does not offer the functionality to switch back."; + } + else if (gitCommand == "catkin_make") + { + heading_string = heading_string + "CATKIN_MAKE"; + scriptname_for_php = scriptname_for_php + "catkin_make"; + confirm_alert_text = confirm_alert_text + "This compiles the dfall-system code."; + } + // Add the end paragraph tag to the heading string + heading_string = heading_string + "</p>"; + + // Check the "shouldAppend" input argument + if ( typeof(shouldAppend) !== "boolean" ) + { + shouldAppend = true; + } + + // Check the "shouldConfirm" input argument + if ( typeof(shouldConfirm) !== "boolean" ) + { + shouldConfirm = true; + } + + // If required, confirm the user wants to perform this action + if (shouldConfirm) + { + var alert_response_bool = confirm(confirm_alert_text); + if (alert_response_bool == false) + { + // If false then the user pressed Cancel + return; + } + } + + // Create a variable for sending an AJAX request + var xmlhttp = new XMLHttpRequest(); + // Add the function to be run when the response is recieved + xmlhttp.onreadystatechange = function() + { + if (this.readyState == 4 && this.status == 200) + { + // Construct and display the appropriate information + var base_string = ""; + if (shouldAppend) + { + // Take a copy of the current contents + var current_contents = document.getElementById(labelID).innerHTML; + // Append the new contents to the start + document.getElementById(labelID).innerHTML = base_string + heading_string + "<br>" + this.responseText + "<br><br>" + current_contents; + } + else + { + document.getElementById(labelID).innerHTML = base_string + heading_string + "<br>" + this.responseText; + } + + } + else + { + // Construct and display the appropriate information + var base_string = ""; + var display_message = getDisplayMessageForXMLHttpRequest(this); + if (shouldAppend) + { + if (this.readyState == 4) + { + // Take a copy of the current contents + var current_contents = document.getElementById(labelID).innerHTML; + // Append the new contents to the start + document.getElementById(labelID).innerHTML = base_string + heading_string + "<br>" + display_message + "<br><br>" + current_contents; + } + } + else + { + if (this.readyState == 4) + { + document.getElementById(labelID).innerHTML = base_string + heading_string + "<br>" + display_message; + } + else + { + document.getElementById(labelID).innerHTML = base_string + display_message; + } + } + } + }; + xmlhttp.open("GET", "callBashScript.php?scriptname=" + scriptname_for_php, true); + xmlhttp.send(); +} \ No newline at end of file diff --git a/web_interface/html/js/general.js b/web_interface/html/js/general.js new file mode 100644 index 0000000000000000000000000000000000000000..033fa60d309eb7a709f1a600160fdfc68358e324 --- /dev/null +++ b/web_interface/html/js/general.js @@ -0,0 +1,46 @@ +function clearLabelWithGivenID(labelID) +{ + document.getElementById(labelID).innerHTML = ""; +} + +function roundToDecimalPlaces(value,decimals) +{ + return Number(Math.round(value+'e'+decimals)+'e-'+decimals); +} + +function incrementInputFieldWithGivenID(inputID,multiplier) +{ + //document.getElementById(inputID).value = 2.0; + + // Get the value of the input field + var current_value = parseFloat( document.getElementById(inputID).value ); + + // Get the increment of the input field + var increment_amount = document.getElementById(inputID).step; + + // Check that the value is a number + if (isNaN(current_value)) + { + current_value = 0.0; + } + + // Compute the new value + var new_value = roundToDecimalPlaces( current_value + multiplier * increment_amount , 3 ); + + // Put the new value into the field + document.getElementById(inputID).value = new_value; +} + +function putDefaultSetpointForGivenBaseID(inputBaseID) +{ + // Construct the ID for the (x,y,z,yaw) input fields + var inputID_forX = inputBaseID + "X"; + var inputID_forY = inputBaseID + "Y"; + var inputID_forZ = inputBaseID + "Z"; + var inputID_forYaw = inputBaseID + "Yaw"; + // Set the default values + document.getElementById(inputID_forX).value = 0.0; + document.getElementById(inputID_forY).value = 0.0; + document.getElementById(inputID_forZ).value = 0.4; + document.getElementById(inputID_forYaw).value = 0.0; +} \ No newline at end of file diff --git a/web_interface/html/js/getSetpointViaRosServiceCall.js b/web_interface/html/js/getSetpointViaRosServiceCall.js new file mode 100644 index 0000000000000000000000000000000000000000..baef75df8ac98fe23a4927d38fe2ec6d20b80994 --- /dev/null +++ b/web_interface/html/js/getSetpointViaRosServiceCall.js @@ -0,0 +1,71 @@ +function getSetpointViaRosServiceCall_outputLabelID(controllerName, labelID) +{ + // Convert the "controllerName" to a heading string + var scriptname_for_php = ""; + if (controllerName == "default") + { + scriptname_for_php = scriptname_for_php + "rosGetSetpointDefault"; + } + else if (controllerName == "student") + { + scriptname_for_php = scriptname_for_php + "rosGetSetpointStudent"; + } + + // Set the label to be sending + if(labelID){document.getElementById(labelID).innerHTML = "requesting...";} + + // Create a variable for sending an AJAX request + var xmlhttp = new XMLHttpRequest(); + // Add the function to be run when the response is recieved + xmlhttp.onreadystatechange = function() + { + if (this.readyState == 4 && this.status == 200) + { + // Get the response into a string + var response_as_string = this.responseText; + //var response_as_struct = JSON.parse(response_as_string); + + // Check that the string is not empty + if (response_as_string) + { + // NOTE: use https://regex101.com/ to get an explaination + // of the regular expressions used + + // Get the x value + //var regex_for_x = new RegExp("(x: )([-+]?\d*\.?\d*)"); + var regex_for_x = /(x: )([-+]?\d*\.?\d*)/; + var found_for_x = response_as_string.match(regex_for_x); + var x_value_as_float = parseFloat( found_for_x[2] ); + var x_value_as_string = x_value_as_float.toFixed(3); + + // Construct and display the appropriate information + var base_string = "received x= "; + //if(labelID){document.getElementById(labelID).innerHTML = base_string + response_as_string;} + if(labelID){document.getElementById(labelID).innerHTML = base_string + x_value_as_string;} + } + else + { + // Construct and display the appropriate information + var base_string = "received empty response"; + if(labelID){document.getElementById(labelID).innerHTML = base_string;} + } + + } + else + { + // Construct and display the appropriate information + var base_string = ""; + var display_message = getDisplayMessageForXMLHttpRequest(this); + if (this.readyState == 4) + { + if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;} + } + else + { + //if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;} + } + } + }; + xmlhttp.open("GET", "callBashScript.php?scriptname=" + scriptname_for_php, true); + xmlhttp.send(); +} \ No newline at end of file diff --git a/web_interface/html/js/sendRosMessage.js b/web_interface/html/js/sendRosMessage.js new file mode 100644 index 0000000000000000000000000000000000000000..cabbe8cd70bb54fd558344abff3b2320c1bc15df --- /dev/null +++ b/web_interface/html/js/sendRosMessage.js @@ -0,0 +1,68 @@ +function sendRosMessage_outputLabelID(rosMessage, labelID) +{ + // Convert the "rosMessage" to a heading string + var scriptname_for_php = ""; + if (rosMessage == "connect") + { + scriptname_for_php = scriptname_for_php + "rosConnect"; + } + else if (rosMessage == "disconnect") + { + scriptname_for_php = scriptname_for_php + "rosDisconnect"; + } + else if (rosMessage == "takeoff") + { + scriptname_for_php = scriptname_for_php + "rosTakeoff"; + } + else if (rosMessage == "land") + { + scriptname_for_php = scriptname_for_php + "rosLand"; + } + else if (rosMessage == "motorsoff") + { + scriptname_for_php = scriptname_for_php + "rosMotorsoff"; + } + else if (rosMessage == "enabledefault") + { + scriptname_for_php = scriptname_for_php + "rosEnabledefault"; + } + else if (rosMessage == "enablestudent") + { + scriptname_for_php = scriptname_for_php + "rosEnablestudent"; + } + + + // Set the label to be sending + if(labelID){document.getElementById(labelID).innerHTML = "sending...";} + + // Create a variable for sending an AJAX request + var xmlhttp = new XMLHttpRequest(); + // Add the function to be run when the response is recieved + xmlhttp.onreadystatechange = function() + { + if (this.readyState == 4 && this.status == 200) + { + // Construct and display the appropriate information + var base_string = ""; + if(labelID){document.getElementById(labelID).innerHTML = base_string + this.responseText;} + //if(labelID){document.getElementById(labelID).innerHTML = base_string + "sent";} + + } + else + { + // Construct and display the appropriate information + var base_string = ""; + var display_message = getDisplayMessageForXMLHttpRequest(this); + if (this.readyState == 4) + { + if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;} + } + else + { + //if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;} + } + } + }; + xmlhttp.open("GET", "callBashScript.php?scriptname=" + scriptname_for_php, true); + xmlhttp.send(); +} \ No newline at end of file diff --git a/web_interface/html/js/setSetpointViaRosMessage.js b/web_interface/html/js/setSetpointViaRosMessage.js new file mode 100644 index 0000000000000000000000000000000000000000..fce3c8055e2b1cfe59a612409c0852a1aa749145 --- /dev/null +++ b/web_interface/html/js/setSetpointViaRosMessage.js @@ -0,0 +1,58 @@ +function setSetpointViaRosMessage_outputLabelID(controllerName, inputBaseID, labelID) +{ + // Convert the "controllerName" to a heading string + var scriptname_for_php = ""; + if (controllerName == "default") + { + scriptname_for_php = scriptname_for_php + "rosSetSetpointDefault"; + } + else if (controllerName == "student") + { + scriptname_for_php = scriptname_for_php + "rosSetSetpointStudent"; + } + + // Get the (x,y,z,yaw) values of the new setpoint + var inputID_forX = inputBaseID + "X"; + var inputID_forY = inputBaseID + "Y"; + var inputID_forZ = inputBaseID + "Z"; + var inputID_forYaw = inputBaseID + "Yaw"; + x_new = document.getElementById(inputID_forX).value; + y_new = document.getElementById(inputID_forY).value; + z_new = document.getElementById(inputID_forZ).value; + yaw_new = document.getElementById(inputID_forYaw).value / 57.29578; + + + // Set the label to be sending + if(labelID){document.getElementById(labelID).innerHTML = "sending...";} + + // Create a variable for sending an AJAX request + var xmlhttp = new XMLHttpRequest(); + // Add the function to be run when the response is recieved + xmlhttp.onreadystatechange = function() + { + if (this.readyState == 4 && this.status == 200) + { + // Construct and display the appropriate information + var base_string = ""; + if(labelID){document.getElementById(labelID).innerHTML = base_string + this.responseText;} + //if(labelID){document.getElementById(labelID).innerHTML = base_string + "sent";} + + } + else + { + // Construct and display the appropriate information + var base_string = ""; + var display_message = getDisplayMessageForXMLHttpRequest(this); + if (this.readyState == 4) + { + if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;} + } + else + { + //if(labelID){document.getElementById(labelID).innerHTML = base_string + display_message;} + } + } + }; + xmlhttp.open("GET", "callBashScript_setNewSetpoint.php?scriptname=" + scriptname_for_php + "&x=" + x_new + "&y=" + y_new + "&z=" + z_new + "&yaw=" + yaw_new, true); + xmlhttp.send(); +} \ No newline at end of file diff --git a/web_interface/html/js/temp.js b/web_interface/html/js/temp.js new file mode 100644 index 0000000000000000000000000000000000000000..3f1a6f4df990a87c46f65bb7eb6a033833dd646b --- /dev/null +++ b/web_interface/html/js/temp.js @@ -0,0 +1,156 @@ +function checkForRosMaster() +{ + // Create a variable for sending an AJAX request + var xmlhttp = new XMLHttpRequest(); + // Add the function to be run when the response is recieved + xmlhttp.onreadystatechange = function() + { + if (this.readyState == 4 && this.status == 200) + { + //var base_string = "Connection success, "; + var base_string = ""; + document.getElementById("rosMasterStatus").innerHTML = base_string + "ROS Master " + this.responseText; + } + else + { + var base_string = "Connection error"; + var error_message = getErrorMessageForXMLHttpRequest(this); + document.getElementById("rosMasterStatus").innerHTML = base_string + ", " + error_message; + // + // Alternatively, just put "loading..." + //document.getElementById("rosMasterStatus").innerHTML = "loading..."; + } + }; + xmlhttp.open("GET", "checkForRosMaster.php", true); + xmlhttp.send(); +} + + + +function checkForRosAgent() +{ + // Create a variable for sending an AJAX request + var xmlhttp = new XMLHttpRequest(); + // Add the function to be run when the response is recieved + xmlhttp.onreadystatechange = function() + { + if (this.readyState == 4 && this.status == 200) + { + //var base_string = "Connection success, "; + var base_string = ""; + document.getElementById("rosAgentStatus").innerHTML = base_string + this.responseText; + } + else + { + //var base_string = "Connection error"; + //var error_message = getErrorMessageForXMLHttpRequest(this); + //document.getElementById("rosAgentStatus").innerHTML = base_string + ", " + error_message; + // + // Alternatively, just put "loading..." + document.getElementById("rosAgentStatus").innerHTML = "loading..."; + } + }; + xmlhttp.open("GET", "checkForRosAgent.php", true); + xmlhttp.send(); +} + + + + +function launchRosAgent() +{ + // Create a variable for sending an AJAX request + var xmlhttp = new XMLHttpRequest(); + // Add the function to be run when the response is recieved + xmlhttp.onreadystatechange = function() + { + if (this.readyState == 4 && this.status == 200) + { + //var base_string = "Connection success, "; + var base_string = ""; + document.getElementById("rosLaunchAgentStatus").innerHTML = base_string + this.responseText; + // Call the function to check for and + // update the "ROS Agent Status" field + checkForRosAgent(); + } + else + { + //var base_string = "Connection error"; + //var error_message = getErrorMessageForXMLHttpRequest(this); + //document.getElementById("rosLaunchAgentStatus").innerHTML = base_string + ", " + error_message; + // + // Alternatively, just put "loading..." + document.getElementById("rosLaunchAgentStatus").innerHTML = "loading..."; + } + }; + xmlhttp.open("GET", "launchRosAgent.php", true); + xmlhttp.send(); +} + + + + + + +function killRosAgent() +{ + // Create a variable for sending an AJAX request + var xmlhttp = new XMLHttpRequest(); + // Add the function to be run when the response is recieved + xmlhttp.onreadystatechange = function() + { + if (this.readyState == 4 && this.status == 200) + { + //var base_string = "Connection success, "; + var base_string = ""; + document.getElementById("killAgentStatus").innerHTML = base_string + this.responseText; + // Call the function to check for and + // update the "ROS Agent Status" field + checkForRosAgent(); + // Call the function to update the list + // of ROS nodes + rosnodeList() + } + else + { + //var base_string = "Connection error"; + //var error_message = getErrorMessageForXMLHttpRequest(this); + //document.getElementById("killAgentStatus").innerHTML = base_string + ", " + error_message; + // + // Alternatively, just put "loading..." + document.getElementById("killAgentStatus").innerHTML = "loading..."; + } + }; + xmlhttp.open("GET", "killRosAgent.php", true); + xmlhttp.send(); +} + + + + +function rosnodeList() +{ + // Create a variable for sending an AJAX request + var xmlhttp = new XMLHttpRequest(); + // Add the function to be run when the response is recieved + xmlhttp.onreadystatechange = function() + { + if (this.readyState == 4 && this.status == 200) + { + //var base_string = "Connection success, "; + var base_string = ""; + document.getElementById("rosnodeList").innerHTML = base_string + this.responseText; + } + else + { + //var base_string = "Connection error"; + //var error_message = getErrorMessageForXMLHttpRequest(this); + //document.getElementById("rosnodeList").innerHTML = base_string + ", " + error_message; + // + // Alternatively, just put "loading..." + document.getElementById("rosnodeList").innerHTML = "loading..."; + } + }; + xmlhttp.open("GET", "rosnodeList.php", true); + xmlhttp.send(); +} diff --git a/web_interface/html/killRosAgent.php b/web_interface/html/killRosAgent.php new file mode 100644 index 0000000000000000000000000000000000000000..4d727404030fb6f1780a5cd411e9036950ef479e --- /dev/null +++ b/web_interface/html/killRosAgent.php @@ -0,0 +1,4 @@ +<?php + $output = shell_exec("./killRosAgent.sh"); + echo "$output"; +?> diff --git a/web_interface/html/launchRosAgent.php b/web_interface/html/launchRosAgent.php new file mode 100644 index 0000000000000000000000000000000000000000..8b39f485a2e3756945a6906ef12c0271b9243099 --- /dev/null +++ b/web_interface/html/launchRosAgent.php @@ -0,0 +1,4 @@ +<?php + $output = shell_exec("./launchRosAgent.sh"); + echo "<pre>$output</pre>"; +?> diff --git a/web_interface/html/page_footer.html b/web_interface/html/page_footer.html new file mode 100644 index 0000000000000000000000000000000000000000..62d09b8221fb59ebb772816f5ff6f9976095615a --- /dev/null +++ b/web_interface/html/page_footer.html @@ -0,0 +1 @@ +</html> \ No newline at end of file diff --git a/web_interface/html/page_header.html b/web_interface/html/page_header.html new file mode 100644 index 0000000000000000000000000000000000000000..ad83bdcf4e4ed9654577c808104ec62de2ce187d --- /dev/null +++ b/web_interface/html/page_header.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html lang="en"> + +<head> + + <!-- Some technical meta data --> + <meta charset="UTF-8" /> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + + <!-- META DATA ABOUT ME AND MY PAGE --> + <title>D-FaLL Web Interface</title> + + <meta name="description" content="Web interface for controlling the D-FaLL-System" /> + + <meta name="author" content="Paul N. Beuchat"> + + <meta name="keywords" content="ethz, D-ITET, IfA, dfall, D-FaLL" /> + + <!-- Link the CSS files --> + <link rel="stylesheet" type="text/css" href="css/default.css?ver=0.1" /> + <link rel="stylesheet" type="text/css" href="css/layout.css?ver=0.1" /> + <link rel="stylesheet" type="text/css" href="css/body.css?ver=0.1" /> + <link rel="stylesheet" type="text/css" href="css/buttons.css?ver=0.1" /> + + <link rel="stylesheet" type="text/css" href="css/tabs_main.css?ver=0.1" /> + <link rel="stylesheet" type="text/css" href="css/tabs_home.css?ver=0.1" /> + <link rel="stylesheet" type="text/css" href="css/tabs_control.css?ver=0.1" /> + + + <!-- Link the JavaScript files --> + <script src="js/general.js?ver=0.1"></script> + <script src="js/callbashscript.js?ver=0.1"></script> + <script src="js/callgit.js?ver=0.1"></script> + <script src="js/sendRosMessage.js?ver=0.1"></script> + <script src="js/setSetpointViaRosMessage.js?ver=0.1"></script> + <script src="js/getSetpointViaRosServiceCall.js?ver=0.1"></script> + +</head> \ No newline at end of file diff --git a/web_interface/html/phpinfo.php b/web_interface/html/phpinfo.php new file mode 100644 index 0000000000000000000000000000000000000000..54bd1bc952e8c41d31c41cd53d4345b8e58ed466 --- /dev/null +++ b/web_interface/html/phpinfo.php @@ -0,0 +1 @@ +<?php echo 'Simple test for now'; ?> diff --git a/web_interface/html/rosnodeList.php b/web_interface/html/rosnodeList.php new file mode 100644 index 0000000000000000000000000000000000000000..c0e0db444d6dcf9934b016d9bc9a2c193e4f06f3 --- /dev/null +++ b/web_interface/html/rosnodeList.php @@ -0,0 +1,4 @@ +<?php + $output = shell_exec("./rosnodeList.sh"); + echo "<pre>$output</pre>"; +?> diff --git a/web_interface/html/temp.html b/web_interface/html/temp.html new file mode 100644 index 0000000000000000000000000000000000000000..35a7651986794ee20dedc5b6b320559ab65934ff --- /dev/null +++ b/web_interface/html/temp.html @@ -0,0 +1,69 @@ + <?php echo "hello world"; ?> + + <?php echo '<br>'; ?> + + <?php echo date('Y-m-d H:i:s'); ?> + + <?php echo '<br>'; ?> + + <!-- <?php phpinfo(); ?> --> + + + <?php + // outputs the username that owns the running php/httpd process + // (on a system with the "whoami" executable in the path) + echo exec('whoami'); + ?> + + <?php echo '<br>'; ?> + + + + <?php + $output = shell_exec("ls -lart"); + echo "<pre>$output</pre>"; + ?> + + <?php echo '<br>'; ?> + + <!-- + <?php + $output = shell_exec("./rosnode_list.sh"); + echo "<pre>$output</pre>"; + ?> + --> + + <?php echo '<br>'; ?> + + <!--$output = shell_exec("./roscore.sh");--> + <!--$output = shell_exec("nohup ./roscore.sh > /dev/null &");--> + + <?php echo '<br>'; ?> + + <!-- + <?php + $output = shell_exec("./rosnode_list.sh"); + echo "<pre>$output</pre>"; + ?> + --> + + <?php echo '<br>'; ?> + + <!-- + <?php + $output = shell_exec("source /opt/ros/melodic/setup.bash"); + echo "<pre>$output</pre>"; + $outputtwo = shell_exec("rosnode list"); + echo "<pre>$outputtwo</pre>"; + ?> + --> + + <?php echo '<br>'; ?> + + <!-- + <?php + exec("dir", $output, $return); + echo "Dir returned $return, and output:\n"; + var_dump($output); + ?> + --> diff --git a/web_interface/install_dfall_server_WIP.sh b/web_interface/install_dfall_server_WIP.sh new file mode 100644 index 0000000000000000000000000000000000000000..09e47cfb7eb366752a5be6e836c1dbd7a9f95d22 --- /dev/null +++ b/web_interface/install_dfall_server_WIP.sh @@ -0,0 +1,30 @@ +# Install the apache web server +sudo apt install apache2 + +# Install php +sudo apt install php + +# Clone the repository +# NOTE: very important here is that the repository +# is cloned as the www-data user +sudo -u www-data git clone https://... + +# Add the necessary line to the "/etc/sudoers" file +# that allows the "www-data" user to execute +# "git pull" commands +www-data ALL=(www-data) /usr/bin/git pull + + + + +# ============================================ # +# USEFUL COMMANDS +# +# The apache web server can be +# {stop,start,restart,reload} +# using the "systemctl" command as follows: +# +#sudo systemctl stop apache2.service +#sudo systemctl start apache2.service +#sudo systemctl restart apache2.service +#sudo systemctl reload apache2.service \ No newline at end of file