// Send a message representing new page info to the controller.
    // Typically will be called when the user presses previous or next.
    // Sends until success, in a new thread.
    public void SendStorybookPageInfoAction(StorybookPageInfo pageInfo)
    {
        Thread thread = new Thread(() => {
            Dictionary <string, object> publish = new Dictionary <string, object>();
            publish.Add("topic", Constants.STORYBOOK_PAGE_INFO_TOPIC);
            publish.Add("op", "publish");

            Dictionary <string, object> data = new Dictionary <string, object>();
            data.Add("header", RosbridgeUtilities.GetROSHeader());
            data.Add("story_name", pageInfo.storyName);
            data.Add("page_number", pageInfo.pageNumber);
            data.Add("sentences", pageInfo.sentences);

            List <Dictionary <string, object> > tinkerTexts =
                new List <Dictionary <string, object> > ();
            foreach (StorybookTinkerText t in pageInfo.tinkerTexts)
            {
                Dictionary <string, object> tinkerText = new Dictionary <string, object>();
                tinkerText.Add("has_scene_object", t.hasSceneObject);
                tinkerText.Add("scene_object_id", t.sceneObjectId);
                tinkerText.Add("word", t.word);
                tinkerTexts.Add(tinkerText);
            }
            data.Add("tinkertexts", tinkerTexts);

            List <Dictionary <string, object> > sceneObjects =
                new List <Dictionary <string, object> >();
            foreach (StorybookSceneObject o in pageInfo.sceneObjects)
            {
                Dictionary <string, object> sceneObject = new Dictionary <string, object>();
                sceneObject.Add("id", o.id);
                sceneObject.Add("label", o.label);
                sceneObject.Add("in_text", o.inText);
                sceneObjects.Add(sceneObject);
            }
            data.Add("scene_objects", sceneObjects);

            List <Dictionary <string, object> > prompts = new List <Dictionary <string, object> >();
            foreach (JiboPrompt p in pageInfo.prompts)
            {
                Dictionary <string, object> prompt = new Dictionary <string, object>();
                prompt.Add("question", p.question);
                prompt.Add("response", p.response);
                prompt.Add("hint", p.hint);
                prompts.Add(prompt);
            }
            data.Add("prompts", prompts);

            publish.Add("msg", data);
            Logger.Log("Sending page info ROS message: " + Json.Serialize(publish));
            bool sent = false;
            while (!sent)
            {
                sent = this.rosClient.SendMessage(Json.Serialize(publish));
            }
            Logger.Log("Successfully sent page info ROS message.");
        });

        thread.Start();
    }
    // Send a message representing storybook state to the controller.
    // Doesn't need to return Action because it's only used as a timer elapsed handler.
    private void sendStorybookState(object _, System.Timers.ElapsedEventArgs __)
    {
        Dictionary <string, object> publish = new Dictionary <string, object>();

        publish.Add("topic", Constants.STORYBOOK_STATE_TOPIC);
        publish.Add("op", "publish");

        // TODO: could devise a better scheme to make sure states are sent in order.
        // Can also use the sequence numbers provided in the header. Probably overkill.
        Dictionary <string, object> data = StorybookStateManager.GetRosMessageData();

        data.Add("header", RosbridgeUtilities.GetROSHeader());
        // Don't allow audio_file to be null, ROS will get upset.
        if (data["audio_file"] == null)
        {
            data["audio_file"] = "";
        }
        publish.Add("msg", data);

        bool success = this.rosClient.SendMessage(Json.Serialize(publish));

        if (!success)
        {
            // Logger.Log("Failed to send StorybookState message: " + Json.Serialize((publish)));
        }
    }
示例#3
0
    // Send a message representing storybook state to the controller, in a new thread.
    // Doesn't need to return Action because it's only used as a timer elapsed handler.
    private void sendStorybookState(object _, System.Timers.ElapsedEventArgs __)
    {
        Dictionary <string, object> publish = new Dictionary <string, object>();

        publish.Add("topic", Constants.STORYBOOK_STATE_TOPIC);
        publish.Add("op", "publish");

        // Note that this is protected by a lock, so although ROS messages could
        // send out of order, the information within them will be consistent.
        // And if the sending rate isn't too high, the likelihood of out of order messages
        // is low, and inconsequential for the controller anyway.
        // TODO: should devise a better scheme to make sure states are sent in order.
        // Can also use the sequence numbers provided in the header.
        // Or use a lock in this class so that only one state message can be sent at a time.
        Dictionary <string, object> data = StorybookStateManager.GetRosMessageData();

        data.Add("header", RosbridgeUtilities.GetROSHeader());
        // Don't allow audio_file to be null, ROS will get upset.
        if (data["audio_file"] == null)
        {
            data["audio_file"] = "";
        }
        publish.Add("msg", data);

        bool success = this.rosClient.SendMessage(Json.Serialize(publish));

        if (!success)
        {
            // Logger.Log("Failed to send StorybookState message: " + Json.Serialize((publish)));
        }
    }
    // Send a message representing storybook state to the controller, in a new thread.
    // Doesn't need to return Action because it's only used as a timer elapsed handler.
    private void sendStorybookState(object sender, System.Timers.ElapsedEventArgs e)
    {
        Thread t = new Thread(() => {
            Dictionary <string, object> publish = new Dictionary <string, object>();
            publish.Add("topic", Constants.STORYBOOK_STATE_TOPIC);
            publish.Add("op", "publish");

            Dictionary <string, object> data = new Dictionary <string, object>();

            // Note that this is protected by a lock, so although ROS messages could
            // send out of order, the information within them will be consistent.
            // And if the sending rate isn't too high, the likelihood of out of order messages
            // is low, and inconsequential for the controller anyway.
            // TODO: should devise a better scheme to make sure states are sent in order.
            // Can also use the sequence numbers provided in the header.
            // Or use a lock in this class so that only one state message can be sent at a time.
            StorybookState currentStorybookState = this.storybookStateManager.getCurrentState();
            data.Add("header", RosbridgeUtilities.GetROSHeader());
            data.Add("audio_playing", currentStorybookState.audioPlaying);
            // ROS freaks out if it gets a null value, so just fill it in with an empty string
            // if there is no provided audio file.
            string audioFile = currentStorybookState.audioFile;
            if (audioFile == null)
            {
                audioFile = "";
            }
            data.Add("audio_file", audioFile);
            data.Add("storybook_mode", (int)currentStorybookState.storybookMode);
            data.Add("current_story", currentStorybookState.currentStory);
            data.Add("num_pages", currentStorybookState.numPages);
            data.Add("evaluating_stanza_index", currentStorybookState.evaluatingStanzaIndex);

            publish.Add("msg", data);

            bool success = this.rosClient.SendMessage(Json.Serialize(publish));
            if (!success)
            {
                Logger.Log("Failed to send StorybookState message: " + Json.Serialize((publish)));
            }
        });

        t.Start();
    }
    // Send StorybookEvent message until received, in a new thread.
    private void sendEventMessageToController(StorybookEventType messageType, string message)
    {
        Thread t = new Thread(() => {
            Dictionary <string, object> publish = new Dictionary <string, object>();
            publish.Add("topic", Constants.STORYBOOK_EVENT_TOPIC);
            publish.Add("op", "publish");
            // Build data to send.
            Dictionary <string, object> data = new Dictionary <string, object>();
            data.Add("event_type", (int)messageType);
            data.Add("header", RosbridgeUtilities.GetROSHeader());
            data.Add("message", message);
            publish.Add("msg", data);
            Logger.Log("Sending event ROS message: " + Json.Serialize(publish));
            bool sent = false;
            while (!sent)
            {
                sent = this.rosClient.SendMessage(Json.Serialize(publish));
            }
        });

        t.Start();
    }