Now that the backend and feature implementation stuff was almost done, it was time to brush up the exercise with a few user related issues and focusing on the execution from the docker container via

  • Implemented the upload of model/video an independent event from executing an exercise mode - As of now there was no separate option to upload the model/video alone without executing a mode, in other words, the model and video were uploaded together at the time of mode execution. This was strange as modes like live benchmarking and live inference wouldn’t need the video to be uploaded and also because uploading the model and video again and again after clicking the play button doesn’t make sense. Although, unneeded multiple uploads were not a problem during the non-docker execution, the uploads during the docker execution took some time, so it was essential to make the uploading of model and video separate events from executing an exercise mode.

  • Worked on the base Deep Learning server template for the exercise - All the Robotics exercise had a base template for the docker execution via Since the functionality of the DL exercises were quite different, it was essential to make a base web-template for them.

  • Worked on the main exercise template used during the docker execution - In general the exercises within the Robotics Academy had 2 different templates, one for the non-docker execution and the other for the docker execution. Previously, we had mainly worked on the non-docker execution template. Now, working on the docker template was easy as we had previously already made the base DL template, and only the GUI features not implemented in the base template were to be added. These mainly included the model selector, file selector, and the upload buttons.

  • Fixed exercise connection issue

  • Added the new noVNC console to the web template

  • Implemented more specific activation/deactivation of buttons based on wether the required files have been fully uploaded or not - As of now the inference buttons used to get enabled straight after clicking upload, not taking into consideration as to wether the required files have been fully uploaded and saved in the backend. Also, the video infer button used to get enabled straight after clicking model upload, not taking into consideration wether the video file also has been uploaded or not. It was thus essential to activate the respective mode’s inference button only when all the required files have been successfully received and saved in the backend. Not doing so was sometimes causing problems during the docker execution of the exercise as clicking the inference button and starting an inference process thread while the files are still being uploaded would sometimes cause the process thread to close straight after starting. All this was done by sending an acknowledge message from the backend ones the required files have been saved.

# Backend
# Acknowledge message for successful model upload
self.server.send_message(self.client, "#modl")

# Acknowledge message for successful video upload
self.server.send_message(self.client, "#vido")
// Frontend processing of the acknowledgement
var stop_button = document.getElementById("stop");
var live_button = document.getElementById("Live_Infer");
var benchmark_button = document.getElementById("benchmark");
var video_button = document.getElementById("Video_Infer");
var visualizer_button = document.getElementById("visualizer");
stop_button.disabled = live_button.disabled =  benchmark_button.disabled = video_button.disabled = visualizer_button.disabled = true; = = = = = "0.4"; = = = = = "not-allowed";
var model_uploaded = false;
var video_uploaded = false;

function declare_code(){
	websocket_code = new WebSocket("ws://" + websocket_address + ":1905/");

	websocket_code.onmessage = function(event){
		var source_code =;
		operation = source_code.substring(0, 5);

		if(operation == "#modl"){
			document.getElementById("output_heading").textContent = "";
			model_uploaded = true;
			live_button.disabled = benchmark_button.disabled = visualizer_button.disabled = false; = = = "1.0"; = = = "default";
			if(video_uploaded == true){
				video_button.disabled = false; = "1.0"; = "default";
		if(operation == "#vido"){
			document.getElementById("output_heading").textContent = "";
			video_uploaded = true;
			if(model_uploaded == true){
				video_button.disabled = false; = "1.0"; = "default";