public void SendTextToNLU(EventMessageObject asrRequestMessageObject)
    {
        string asrRequest = (string)asrRequestMessageObject.MessageBody;

        PrintMessageBody(asrRequestMessageObject);
        nlu.UnderstandRequest(asrRequest);
    }
    //Gibt ein Präfix gefolgt vom Inhalt der EventMessage im debugTextfeld aus
    private void PrintMessageBody(EventMessageObject _eventMessageObject)
    {
        string messageBody;

        try
        {
            messageBody = (string)_eventMessageObject.MessageBody;
        }
        catch (Exception e)
        {
            Debug.LogError("Falscher Typ des Message Bodys Objekts" + e.Message);
            messageBody = "ERROR";
        }
        string messageType = _eventMessageObject.Type;



        if (messageType.Equals(EventManager.keywordDetectedEvent))
        {
            debugText.text = "Keyword detected: " + messageBody;
        }

        else if (messageType.Equals(EventManager.asrRequerstDetectedEvent))
        {
            debugText.text = "ASR Request detected: " + messageBody;
        }

        else if (messageType.Equals(EventManager.nluAnswerDetectedEvent))

        {
            debugText.text = "NLU answer detected: " + messageBody;
        }
    }
Exemple #3
0
    /* public static void TriggerEvent (string eventName, Object args )
     * {
     *   UnityEventWithParameter thisEvent = null;
     *   if (instance.eventDictonary.TryGetValue(eventName, out thisEvent))
     *   {
     *       thisEvent.Invoke();
     *   }
     * }*/

    public static void TriggerEvent(string eventName, EventMessageObject args)
    {
        UnityEventWithParameter thisEvent = null;

        if (instance.eventDictonary.TryGetValue(eventName, out thisEvent))
        {
            thisEvent.Invoke(args);
        }
    }
Exemple #4
0
 private void SSTErrorHandling(EventMessageObject args)  //Prüfe bei Fehlern der SST den ASR Zustand und starte ggf. WakeWordEngine
 {
     //Prüfe #Kommandos in Schlange -> keine + kein aktiver Wechsel-> gehe zu WWE; sonst: Ausgabe aller Befehle + Handle je nachdem was drin steht
     if (ASRModeSwitchQueue.Count == 0 && WakeWordState != SpeechSystemStatus.Running && !isSwitchingASRMode)   //Zurückwechseln zur WWE notwendig, da sonst keine ASR Technik mehr aktiv ist
     {
         Debug.LogErrorFormat("Die Schlange war leer als der Fehler auftrag {0}. Füge deshalb Wechsel zu WWE hinzu ", args.MessageBody);
         ASRModeSwitchQueue.Enqueue(SwitchToWWE);
     }
     else if (ASRModeSwitchQueue.Count > 0)
     {
         Debug.LogError("Benötige weitere Fehlerbehandlung da STT Fehler auftrat als die Schalange wie folgt gefüllt war:");
         int i = 0;
         foreach (AsrSwitchDelegate command in ASRModeSwitchQueue)
         {
             Debug.LogErrorFormat("Befehl {0} befindet sich an Position {1}", command.Method.Name, i);
             i++;
         }
     }
     else
     {
         Debug.LogErrorFormat("Schlange war leer bei ASR Fehleranzeige. Aber keine Wechsel hinzugefügt da entweder STT oder Wechsel aktiv.");
     }
 }
Exemple #5
0
 public void AddWWERequestToQueue(EventMessageObject args)
 {
     Debug.LogFormat("Wechsel zu WWE angefordert. Message: {0}", args.MessageBody.ToString());
     ASRModeSwitchQueue.Enqueue(SwitchToWWE);
 }
    public void HandleIntent(EventMessageObject nluAnswer)
    {
        AIResponse nluResponse = (AIResponse)nluAnswer.MessageBody;

        Debug.Log("##### Habe folgenden Intent erkannt und möchte ihn jetzt verarbeiten: " + nluResponse.Result.Metadata.IntentName);


        //Dialog Delegation prüfen
        Debug.Log("Überprüfe ob noch Slots fehlen: ");
        //AIOutputContext context = nluResponse.Result.GetContext();
        AIOutputContext[] context = nluResponse.Result.Contexts;
        bool slotsMissing         = false;

        foreach (AIOutputContext con in context)
        {
            Debug.Log(con.Name);
            if (con.Name.Contains("dialog_context"))
            {
                slotsMissing = true;
            }
        }
        if (slotsMissing)
        {
            wasInDialogDelegationLastRound = true; //damit nächster Intent sieht, ob DialogDelegation zuvor aktiv war
            slotMissingRounds++;
            Debug.Log("Es fehlen noch Slotbelegungen. Ich gebe die Kontrolle an TTS");
            //Debug.Log("WWE Status " + asr.WakeWordState);
            //Debug.Log("STT Status " + asr.DictationState);
            EventManager.TriggerEvent(EventManager.keywordDetectedEvent, new EventMessageObject(EventManager.keywordDetectedEvent, "Slots fehlen"));
            //actions.DisplayText(debugText, nluResponse.Result.Fulfillment.Speech);
            string cancelInfo = "";

            if (slotMissingRounds > 1)
            {
                cancelInfo = "Du kannst ungewollte Anfragen jederzeit beenden, indem du abbrechen sagst.";
            }
            WindowsVoice.speak(string.Format("{0} {1}", cancelInfo, nluResponse.Result.Fulfillment.Speech), delay: 0f);
        }

        //ansonsten rufe die Handler auf
        else
        {
            slotMissingRounds = 0;
            Debug.Log("Alle Slots gefüllt:");
            Dictionary <String, System.Object> dic = nluResponse.Result.Parameters;
            foreach (String key in dic.Keys)
            {
                Debug.Log(string.Format("Parameter: {0}", key));
            }
            actions.DisplayText(debugText, nluResponse.Result.Fulfillment.Speech);

            String intent       = nluResponse.Result.Metadata.IntentName;
            Result nluResultObj = nluResponse.Result;

            //Ausgabe der Dialogflow Response -> Metadata.EndConversation Boolean bestimmt ob als Frage oder Aussage
            //***Kann in Unity JSON Objekt bisher nicht abgerufen werden -> Parameter: endConversation simuliert ihn
            bool canceledDialogDelegation = nluResponse.Result.ResolvedQuery.Equals("abbrechen") && wasInDialogDelegationLastRound ? true:false;    //Dialogflow eigenes Abbrechen simuliert endConversation nicht

            if (nluResultObj.Fulfillment.Speech != "")
            {
                if (nluResultObj.GetStringParameter("endConversation").Equals("true") || canceledDialogDelegation)  //***evtl. muss hier eine Abfrage rein die beim default fallback auch das mikrofon schließt
                {
                    actions.Speak(nluResultObj.Fulfillment.Speech);
                }
                else  //ansonsten öffne das Mikrofon wieder
                {
                    actions.AskQuestion(nluResultObj.Fulfillment.Speech);
                }
            }

            String action = nluResponse.Result.Action;

            bool noActionIntent = false;  //wird true falls der Intent keine Action enthält oder diese nicht implementiert ist

            switch (action)
            {
            /*case IPAAction.askQuestion:
             *  actions.AskQuestion(nluResultObj.GetStringParameter("speak"));
             *  break;
             *
             *
             * case IPAAction.speak:
             *  actions.Speak(nluResultObj.GetStringParameter("speak"));
             *  break;*/

            //Intents zur Fahrzeugsteuerung
            case IPAAction.moveCar:
                String groesseneinheit = nluResultObj.GetStringParameter("Groesseneinheit");
                String direction       = nluResultObj.GetStringParameter("MoveDirection");
                actions.MoveCar(groesseneinheit, direction);
                break;

            case IPAAction.stopCar:
                actions.StopCarMovement();
                break;

            case IPAAction.takeCarControl:
                actions.TakeCarControl();
                break;

            case IPAAction.getCarControlBack:
                actions.GetCarControlBack();
                break;

            case IPAAction.takePlateControl:
                actions.TakePlateControl();
                break;

            case IPAAction.getPlateControlBack:
                actions.GetPlateControlBack();
                break;

            //Map Manipulation Intents:
            case IPAAction.openMap:
                actions.OpenMap();
                break;

            case IPAAction.closeMap:
                actions.CloseMap();
                actions.SetMinimapFokusOnCar();
                break;

            case IPAAction.saveNavigationPoint:
                actions.SaveNavigationPoint(minimapLocationIcon);
                break;

            case IPAAction.deleteNavigationPoint:
                int zielNummer2 = Int32.Parse(nluResultObj.GetStringParameter("navigationNumber"));
                actions.DeleteNavigationPoint(zielNummer2);
                break;

            case IPAAction.changeMapFixedStep:
                groesseneinheit = nluResponse.Result.GetStringParameter("Groesseneinheit");
                direction       = nluResponse.Result.GetStringParameter("Direction");
                if (direction.Length == 0)
                {
                    direction = nluResponse.Result.GetStringParameter("MoveDirection");
                }

                actions.ChangMapFixedStep(groesseneinheit, direction);
                break;

            case IPAAction.focusOnCar:
                actions.SetMinimapFokusOnCar();
                break;

            //Navigation Intents:
            case IPAAction.startNavigation:
                int zielNummer = Int32.Parse(nluResultObj.GetStringParameter("navigationNumber"));
                if (sharedData.savedPlacesOnMap.Count > zielNummer - 1)
                {
                    Vector3 target = sharedData.savedPlacesOnMap[zielNummer - 1].transform.position;
                    actions.StartNavigation(target);
                }
                else
                {
                    WindowsVoice.speak(string.Format("Ich konnte keinen Ort mit Nummer {0} finden.", zielNummer), 3);
                }
                break;

            case IPAAction.endNavigation:
                actions.EndNavigation();
                break;

            //Intents zur Unterstützung der Teststreckenerstellung
            case IPAAction.restartTraining:
                SceneManager.LoadScene("Level1Training");       // Todo:Index auf Namen der Szene ändern
                break;

            case IPAAction.setCheckpoint:
                actions.SetTrainingCheckpoint(sharedData.currentFrameCount);
                actions.Speak("Sicherungspunkt erstellt bei Frame:" + sharedData.currentFrameCount);
                break;

            case IPAAction.discardCheckpoint:
                actions.SetTrainingCheckpoint(0);
                break;

            case IPAAction.endTrainingRouteCreation:
                actions.EndTraining();

                /*sharedData.trainingRouteRecordingStopped = true;    //Beendet hinzufügen neuer Framestrokes in AlternateCarController
                 *
                 *
                 * //Entferne PlayerControl und Ball
                 * sharedData.SetPlayerControl(false);
                 * GameObject.FindGameObjectWithTag("Ball").SetActive(false);
                 * if (String.IsNullOrEmpty(sharedData.playerName))
                 * {
                 *  Debug.LogError("Fehler bei Namenserfassung. Öffne Texteingabe.");
                 *  GameObject.Find("NameQuestionCanvas").GetComponent<Canvas>().enabled = true;
                 * }*/
                break;

            case IPAAction.performanceAndDifficultyMeasured:
                bool performanceOK = nluResultObj.GetStringParameter("Performance").Equals("gut") ? true : false;
                if (sharedData.debugMode && performanceOK)
                {
                    //Debug.LogError(WindowsVoice.statusMessage);
                    sharedData.trainingRouteDifficulty = nluResultObj.GetStringParameter("Difficulty") + "/";       //sobald gesetzt schreibt AlternateCarController die Route entsprechend ca Codezeile 500

                    //Beende verzögert
                    StartCoroutine(SharedFields.DelayedQuit(10f));
                }
                else
                {
                    Debug.LogError(nluResultObj.GetStringParameter("Performance"));
                    actions.Speak("Verwerfe Strecke aufgrund schlechter Performance. Beende Programm");
                    IEnumerator co = SharedFields.DelayedQuit(10f);
                    StartCoroutine(co);

                    //Application.Quit();
                }
                break;

            case IPAAction.wantToSetContext:
                int firstFreeContext              = context.Length;
                AIOutputContext[] newContext      = new AIOutputContext[firstFreeContext + 1];
                AIOutputContext   contextToInsert = new AIOutputContext();
                contextToInsert.Name         = "TestContext";
                contextToInsert.Lifespan     = 3;
                newContext[firstFreeContext] = contextToInsert;
                context = newContext;
                Debug.Log("So sollte es aussehen:");
                foreach (AIOutputContext con in context)
                {
                    Debug.Log(con.Name);
                    if (con.Name.Contains("dialog_context"))
                    {
                        slotsMissing = true;
                    }
                }
                Debug.Log("Trigger SpeechCommandRecognized to send new Context to Dialogflow");
                EventManager.TriggerEvent(EventManager.asrRequerstDetectedEvent, new EventMessageObject(EventManager.asrRequerstDetectedEvent, string.Format("Rueckantwort Kontext einfuegen")));
                break;

            case IPAAction.setContext:
                Debug.Log("Habe Kontext gesetzt.");
                foreach (AIOutputContext con in context)
                {
                    Debug.Log(con.Name);
                    if (con.Name.Contains("dialog_context"))
                    {
                        slotsMissing = true;
                    }
                }
                break;

            //PlayerInfo
            case IPAAction.setPlayerName:
                //var outText = NewJSon::Newtonsoft.Json.JsonConvert.SerializeObject(nluResultObj.GetJsonParameter("UserName"), jsonSettings);
                //Debug.LogError(outText);

                string name = "";
                //Sonderbehandlung falls Dialogflow Entitie givenName benutzt -> bekomme neues Dict statt String
                Dictionary <string, object> parameterDict = nluResultObj.Parameters;
                Type t      = parameterDict["UserName"].GetType();
                bool isDict = t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Dictionary <,>);
                Dictionary <string, object> givenNameEntitie;
                if (isDict)
                {
                    givenNameEntitie = (Dictionary <string, object>)parameterDict["UserName"];

                    try
                    {
                        name = (string)givenNameEntitie["given-name"];
                    }
                    catch (KeyNotFoundException)
                    {
                        name = (string)givenNameEntitie["MapStringsToName"];
                    }
                }
                else
                {
                    name = nluResultObj.GetStringParameter("UserName");
                }

                //Debug.LogErrorFormat("is dict? {0}", isDict);

                //Debug.LogError( parameterDict["UserName"].GetType());

                Debug.LogError("Haben folgenden Namen erkannt: " + name);
                if (String.IsNullOrEmpty(name))
                {
                    Debug.LogError("******Name konnte nicht gesetzt werden. Baue erneute Nachfrage ein?");
                }
                actions.SetPlayerName(name);
                Debug.LogError("Der neue Name ist: " + sharedData.playerName);
                break;

            case IPAAction.rename:
                EventManager.TriggerEvent(EventManager.asrRequerstDetectedEvent, new EventMessageObject(EventManager.asrRequerstDetectedEvent, "Spielerwechsel"));
                break;

            //Allgemeine Befehle:
            case IPAAction.repeatAnswer:
                actions.Speak(lastIPAspeech);
                break;

            case IPAAction.repeatLastAction:
                if (repeatableTasksDict.ContainsKey(lastIPAAction))
                {
                    EventManager.TriggerEvent(EventManager.asrRequerstDetectedEvent, new EventMessageObject(EventManager.asrRequerstDetectedEvent, repeatableTasksDict[lastIPAAction]));
                }
                break;

            case IPAAction.undo:
                string undoAction = "";
                Debug.LogError("Last Action was: " + lastIPAAction);
                if (symmetricTasksDict.ContainsKey(lastIPAAction))
                {
                    undoAction = symmetricTasksDict[lastIPAAction];
                }
                else if (symmetricTasksDict.ContainsValue(lastIPAAction))
                {
                    foreach (KeyValuePair <string, string> keyValue in symmetricTasksDict)
                    {
                        if (keyValue.Value.Equals(lastIPAAction))
                        {
                            undoAction = keyValue.Key;
                        }
                    }
                }
                else
                {
                    Debug.LogErrorFormat("Der letzte Task hatte keine Implementierung eines symmetrischen Gegenparts");
                    WindowsVoice.speak("Der letzte Task hatte keine Implementierung eines symmetrischen Gegenparts", 2);
                }


                if (eventTriggerStringForActionDict.ContainsKey(undoAction))
                {
                    string voiceCommandForUndoAction = eventTriggerStringForActionDict[undoAction];
                    EventManager.TriggerEvent(EventManager.asrRequerstDetectedEvent, new EventMessageObject(EventManager.asrRequerstDetectedEvent, voiceCommandForUndoAction));
                }
                else
                {
                    actions.Speak("Ich kann die letzte Aktion nicht rueckgängig machen. Die eingetragenen Funktionspaare funktionieren nur in die andere Richtung.");
                }
                break;

            case IPAAction.wantMoreHelp:
                //Ermittle zuletzt thematisierte Kategorie und simuliere eine entsprechende Anfrage an die NLU
                int navigationHelpSessionCount = 0;
                int mlTrainingHelpSessionCount = 0;
                int driveHelpSessionCount      = 0;


                foreach (AIOutputContext currentContext in nluResponse.Result.Contexts)
                {
                    string contextName = currentContext.Name;
                    if (contextName.Equals("mltraininghelprequested"))
                    {
                        Debug.Log("habe training kontext");
                        mlTrainingHelpSessionCount += (int)currentContext.Lifespan;
                    }
                    else if (context.Equals("navigationhelprequested"))
                    {
                        Debug.Log("habe navigation kontext");
                        navigationHelpSessionCount += (int)currentContext.Lifespan;
                    }
                    else if (context.Equals("drivehelprequested"))
                    {
                        Debug.Log("habe drive kontext");
                        driveHelpSessionCount += (int)currentContext.Lifespan;
                    }
                }

                if (navigationHelpSessionCount > Math.Max(mlTrainingHelpSessionCount, driveHelpSessionCount))
                {
                    EventManager.TriggerEvent(EventManager.asrRequerstDetectedEvent, new EventMessageObject(EventManager.asrRequerstDetectedEvent, "Ich brauche Hilfe in der Kategorie Fahren."));
                }

                else if (mlTrainingHelpSessionCount > Math.Max(navigationHelpSessionCount, driveHelpSessionCount))
                {
                    EventManager.TriggerEvent(EventManager.asrRequerstDetectedEvent, new EventMessageObject(EventManager.asrRequerstDetectedEvent, "Hilf mir beim trainieren"));
                }

                else if (driveHelpSessionCount > Math.Max(navigationHelpSessionCount, mlTrainingHelpSessionCount))
                {
                    EventManager.TriggerEvent(EventManager.asrRequerstDetectedEvent, new EventMessageObject(EventManager.asrRequerstDetectedEvent, "Hilf mir beim Navigieren"));
                }

                else
                {
                    Debug.LogFormat("Konnte kein Event auslösen: navigationHelpSessionCount {0}  mlTrainingHelpSessionCount{1}, driveHelpSessionCount {2}", navigationHelpSessionCount, mlTrainingHelpSessionCount, driveHelpSessionCount);
                }

                break;

            case IPAAction.continueGame:
                actions.ContinueGame();
                break;

            case IPAAction.pauseGame:
                actions.PauseGame();
                break;

            case IPAAction.quitGame:
                Application.Quit();
                break;

            default:
                Debug.Log(string.Format("Der Intent {0} wurde im IntentHandler nicht registiert.", intent));
                noActionIntent = true;
                //WindowsVoice.speak("Diesen Intent kenne ich nicht", 0f);  //wird von Fallback Intent in Block unten gemacht
                break;
            }

            //Die letzte Aktion soll von Intents ohne Action nicht überschrieben werden
            if (!noActionIntent)
            {
                lastIPAAction = action;
            }
        }
        lastIPAspeech = nluResponse.Result.Fulfillment.Speech;
        Debug.LogError(lastIPAspeech + " ist zuletzt gesagtes");
    }