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"
+	>
+	&nbsp
+</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"
+				>
+				&nbsp
+			</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"
+	>
+	&nbsp
+</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"
+				>
+				&nbsp
+			</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"
+				>
+				&nbsp
+			</div>
+		</td>
+		<td class="centered-table-button-cell">
+			<div
+				style="text-align: center;"
+				id="labelSetDeaultSetpointStudent"
+				>
+				&nbsp
+			</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"
+			>
+			&nbsp
+		</td>
+		<td
+			style="text-align: center;"
+			id="labelControlRadioConnect"
+			>
+			&nbsp
+		</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"
+			>
+			&nbsp
+		</td>
+		<td
+			style="text-align: center;"
+			id="labelControlLand"
+			>
+			&nbsp
+		</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