var questions = [ { question: "What sounds most interesting?", answers: [ { text: "Building a robot", type: "embedded" }, { text: "Programming AI", type: "ai" }, { text: "Designing electronics", type: "embedded" }, { text: "Solving real-world problems", type: "rescue" } ] }, { question: "Which robot would you rather build?", answers: [ { text: "Delivery robot", type: "autonomous" }, { text: "Rescue robot", type: "rescue" }, { text: "Drone", type: "drone" }, { text: "Humanoid robot", type: "ai" } ] }, { question: "What would you rather learn?", answers: [ { text: "ROS2", type: "autonomous" }, { text: "Computer Vision", type: "vision" }, { text: "Embedded Systems", type: "embedded" }, { text: "Machine Learning", type: "ai" } ] }, { question: "Favourite sci-fi robot?", answers: [ { text: "R2-D2", type: "embedded" }, { text: "WALL-E", type: "rescue" }, { text: "TARS", type: "ai" }, { text: "Data", type: "ai" } ] }, { question: "You have £100 and a weekend. What do you build?", answers: [ { text: "Robot car", type: "autonomous" }, { text: "Smart home system", type: "embedded" }, { text: "AI assistant", type: "ai" }, { text: "Drone", type: "drone" } ] } ]; var results = { ai: { title: "AI Researcher", description: "You enjoy solving complex problems using machine learning and intelligent systems." }, rescue: { title: "Rescue Robotics Engineer", description: "You enjoy designing robots that can help people in dangerous environments." }, embedded: { title: "Embedded Systems Engineer", description: "You enjoy working with hardware, sensors and electronics." }, autonomous: { title: "Autonomous Systems Engineer", description: "You enjoy building robots that can think and act independently." }, vision: { title: "Computer Vision Specialist", description: "You enjoy teaching robots how to see and understand the world." }, drone: { title: "Drone Specialist", description: "You enjoy flying robots, navigation and remote systems." } }; var currentQuestion = 0; var scores = {}; /* ========================================================== SCREEN CONTROL ========================================================== */ function showScreen(screenId) { var screens = document.getElementsByClassName("screen"); for (var i = 0; i < screens.length; i++) { screens[i].className = "screen"; } document.getElementById(screenId).className = "screen active"; } /* ========================================================== QUIZ ========================================================== */ function startQuiz() { currentQuestion = 0; scores = {}; showScreen("quiz-screen"); showQuestion(); } function showQuestion() { var question = questions[currentQuestion]; document.getElementById("question-count").innerHTML = "Question " + (currentQuestion + 1) + " of " + questions.length; document.getElementById("question-text").innerHTML = question.question; var answersDiv = document.getElementById("answers"); answersDiv.innerHTML = ""; for ( var i = 0; i < question.answers.length; i++ ) { var answer = question.answers[i]; var button = document.createElement("button"); button.className = "answer-button"; button.innerHTML = answer.text; button.setAttribute( "data-type", answer.type ); button.onclick = function () { selectAnswer( this.getAttribute("data-type") ); }; answersDiv.appendChild(button); } } function selectAnswer(type) { scores[type] = scores[type] ? scores[type] + 1 : 1; currentQuestion++; if ( currentQuestion < questions.length ) { showQuestion(); } else { showResult(); } } function showResult() { var topType = null; var topScore = -1; for (var type in scores) { if ( scores[type] > topScore ) { topType = type; topScore = scores[type]; } } var result = results[topType]; document.getElementById( "result-title" ).innerHTML = "You are a " + result.title + "!"; document.getElementById( "result-description" ).innerHTML = result.description; showScreen( "result-screen" ); sendResultToPepper( "You are a " + result.title + ". " + result.description ); } /* ========================================================== SEND QUIZ RESULT TO PEPPER ========================================================== */ function sendResultToPepper(message) { if ( typeof QiSession === "undefined" ) { return; } QiSession(function (session) { session .service("ALMemory") .then(function (memory) { memory.raiseEvent( "PepperFreshers/Result", message ); }); }); } /* ========================================================== MEDIA VARIABLES ========================================================== */ var localDanceAudio = null; var localVideo = null; var photoOpportunityTimer = null; /* ========================================================== IMPORTANT: DETECT WHETHER THE PAGE IS RUNNING ON PEPPER THIS FUNCTION WAS MISSING FROM THE BROKEN PROJECT. Dance, Refreshers and Photo Opportunity all depend on it. ========================================================== */ function isPepperTablet() { return ( typeof QiSession !== "undefined" ); } /* ========================================================== PLAYING SCREEN ========================================================== */ function setPlayingScreen( message, returnScreen ) { var playingScreen = document.getElementById( "dance-playing-screen" ); var messageEl = document.getElementById( "playing-message" ); var backButton = document.getElementById( "playing-back-button" ); var preview = document.getElementById( "local-preview" ); if (playingScreen) { playingScreen.className = "screen"; } if (messageEl) { messageEl.innerHTML = message; } if (backButton) { backButton.onclick = function () { stopLocalMedia(); showScreen( returnScreen ); }; } if (preview) { preview.innerHTML = ""; } showScreen( "dance-playing-screen" ); } /* ========================================================== PHOTO OPPORTUNITY TIMER ========================================================== */ function stopPhotoOpportunityLoop() { if ( photoOpportunityTimer ) { clearTimeout( photoOpportunityTimer ); photoOpportunityTimer = null; } } /* ========================================================== STOP TABLET MEDIA ========================================================== */ function stopLocalMedia() { stopPhotoOpportunityLoop(); if (localDanceAudio) { localDanceAudio.pause(); localDanceAudio.currentTime = 0; localDanceAudio = null; } if (localVideo) { localVideo.pause(); localVideo.currentTime = 0; localVideo = null; } } /* ========================================================== LOCAL DANCE AUDIO Primarily useful when testing the tablet interface outside Pepper. On Pepper the Choregraphe behaviour handles the actual dance/music. ========================================================== */ function playLocalDanceAudio( danceName ) { var audioFile = ""; if ( danceName === "dance_knights" ) { audioFile = "../behavior_1/kishitachinoodori.ogg"; } if ( danceName === "walk_this_way" ) { audioFile = "../behavior_1/walk_this_way.ogg"; } if ( danceName === "02_Hungary" || danceName === "hungarian" || danceName === "hungary" ) { audioFile = "../behavior_1/02_Hungary.ogg"; } if ( audioFile === "" ) { console.log( "No local audio found for:", danceName ); return; } stopLocalMedia(); localDanceAudio = new Audio( audioFile ); localDanceAudio.onended = function () { localDanceAudio = null; showScreen( "pepper-dance-screen" ); }; localDanceAudio .play() .catch( function (error) { console.log( "Local dance audio could not play:", error ); } ); } /* ========================================================== REFRESHERS TABLET MEDIA Bees: assets/Bees_Gees.mp4 Surprise: assets/Rick Roll Link.mp4 Speech: no video - Pepper performs speech/animation. ========================================================== */ function playLocalRefreshers( refreshersName ) { var playingScreen = document.getElementById( "dance-playing-screen" ); var preview = document.getElementById( "local-preview" ); var playingLogo = document.getElementById( "playing-logo" ); var playingMessage = document.getElementById( "playing-message" ); var videoFile = ""; var title = ""; refreshersName = refreshersName.toLowerCase(); /* ------------------------------ BEES ------------------------------ */ if ( refreshersName === "bees" ) { title = "Bees"; videoFile = "assets/Bees_Gees.mp4"; } /* ------------------------------ SURPRISE ------------------------------ */ if ( refreshersName === "surprise" ) { title = "Surprise"; videoFile = "assets/Rick Roll Link.mp4"; } /* ------------------------------ SPEECH ------------------------------ */ if ( refreshersName === "speech" ) { title = "Robotics Society"; } stopLocalMedia(); if (!preview) { return; } /* ------------------------------ ENABLE VIDEO UI MODE ------------------------------ */ if (playingScreen) { playingScreen.className = "screen active refreshers-video-mode"; } /* ------------------------------ VIDEO ACTIVITY ------------------------------ */ if ( videoFile !== "" ) { if (playingLogo) { playingLogo.style.display = "none"; } if (playingMessage) { playingMessage.style.display = "none"; } preview.innerHTML = '
' + 'Join the Robotics Society!' + '
' + '" + "Local test mode: Pepper would now cycle through the photo animations." + "
"; } console.log( "LOCAL TEST: would start Photo Opportunity animation loop" ); return; } /* ------------------------------ PEPPER EVENT ------------------------------ */ raisePepperEvent( "PepperFreshers/DanceSelected", "photo_opp" ); } /* ========================================================== NEXT SECTION ========================================================== */ function nextSection() { stopLocalMedia(); showScreen( "projects-screen" ); } /* ========================================================== PROJECT SELECTION ========================================================== */ function selectProject( projectName ) { sendResultToPepper( "You selected " + projectName + "." ); } /* ========================================================== GENERIC ALMEMORY EVENT ========================================================== */ function raisePepperEvent( eventName, value ) { if ( !isPepperTablet() ) { console.log( "LOCAL TEST: would send to Pepper:", eventName, value ); return; } QiSession( function (session) { session .service("ALMemory") .then( function (memory) { memory.raiseEvent( eventName, value ); } ); } ); } /* ========================================================== DANCE SELECTION ========================================================== */ function selectDance( danceName ) { restorePlayingScreen(); setPlayingScreen( "Pepper is dancing!", "pepper-dance-screen" ); /* ------------------------------ LOCAL BROWSER TEST ------------------------------ */ if ( !isPepperTablet() ) { console.log( "LOCAL TEST: dance selected:", danceName ); playLocalDanceAudio( danceName ); return; } /* ------------------------------ PEPPER ------------------------------ */ raisePepperEvent( "PepperFreshers/DanceSelected", danceName ); } /* ========================================================== REFRESHERS SELECTION ========================================================== */ function selectRefreshers( refreshersName ) { setPlayingScreen( "Starting: " + refreshersName, "refreshers-screen" ); /* * The tablet always handles the Refreshers video. * * Pepper simultaneously receives the ALMemory event so the * matching physical animation/speech still runs. */ playLocalRefreshers( refreshersName ); if ( isPepperTablet() ) { raisePepperEvent( "PepperFreshers/DanceSelected", refreshersName ); } } /* ========================================================== RESET QUIZ ========================================================== */ function resetQuiz() { stopLocalMedia(); showScreen( "start-screen" ); } /* ========================================================== OPTIONAL RETURN EVENTS FROM PEPPER These listeners are safe to keep. The WORKING Choregraphe behaviour remains the base of the project, so these do not replace or interfere with the existing dance/refreshers flow. ========================================================== */ function setupPepperReturnEvents() { if ( typeof QiSession === "undefined" ) { console.log( "Not running on Pepper tablet." ); return; } QiSession( function (session) { session .service("ALMemory") .then( function (memory) { /* ------------------------------ RETURN TO DANCE PAGE ------------------------------ */ memory .subscriber( "PepperFreshers/ReturnToDancePage" ) .then( function (subscriber) { subscriber.signal.connect( function () { stopLocalMedia(); showScreen( "pepper-dance-screen" ); } ); } ); /* ------------------------------ RETURN TO REFRESHERS PAGE ------------------------------ */ memory .subscriber( "PepperFreshers/ReturnToRefreshersPage" ) .then( function (subscriber) { subscriber.signal.connect( function () { stopLocalMedia(); showScreen( "refreshers-screen" ); } ); } ); } ) .catch( function (error) { console.log( "Could not connect tablet return events:", error ); } ); } ); } /* ========================================================== PAGE STARTUP ========================================================== */ window.onload = function () { setupPepperReturnEvents(); };