- [Deprecated: use Chat with a QiChatbot instead]
Goal - Give Pepper the ability to discuss around a topic.
// Create a topic.
val topic: Topic = TopicBuilder.with(qiContext)
.withResource(R.raw.animals)
.build()
// Build the action.
val discuss: Discuss = DiscussBuilder.with(qiContext)
.withTopic(topic)
.build()
// Run the action asynchronously.
discuss.async().run()
// Create a topic.
Topic topic = TopicBuilder.with(qiContext)
.withResource(R.raw.animals)
.build();
// Build the action.
Discuss discuss = DiscussBuilder.with(qiContext)
.withTopic(topic)
.build();
// Run the action asynchronously.
discuss.async().run();
Typical usage - You want Pepper to have an elaborate conversation with someone.
To build a Discuss, you use Topics:
A Topic
is made of rules that describe the logic of the conversation.
It mostly contains what Pepper should answer when someone talks to him.
Typically, a Topic
is created from a topic file (.top), and uses QiChat syntax.
See also QiChat Language.
You want Pepper to be able to discuss around a topic.
val topic: Topic = TopicBuilder.with(qiContext)
.withResource(R.raw.animals)
.build()
val discuss: Discuss = DiscussBuilder.with(qiContext)
.withTopic(topic)
.build()
discuss.async().run()
Topic topic = TopicBuilder.with(qiContext)
.withResource(R.raw.animals)
.build();
Discuss discuss = DiscussBuilder.with(qiContext)
.withTopic(topic)
.build();
discuss.async().run();
You want to handle the different cases leading to the end of the discuss.
val topic: Topic = TopicBuilder.with(qiContext)
.withResource(R.raw.game)
.build()
val discuss: Discuss = DiscussBuilder.with(qiContext)
.withTopic(topic)
.build()
val endReason: String = discuss.run()
when (endReason) {
"sword" -> buySword()
"bow" -> buyBow()
}
Topic topic = TopicBuilder.with(qiContext)
.withResource(R.raw.game)
.build();
Discuss discuss = DiscussBuilder.with(qiContext)
.withTopic(topic)
.build();
String endReason = discuss.run();
switch (endReason) {
case "sword":
buySword();
break;
case "bow":
buyBow();
break;
}
game.top content:
topic: ~game()
u: (buy) Do you want to buy a sword or a bow?
u1: (sword) This is a really sharp sword. ^endDiscuss(sword)
u1: (bow) This bow can draw arrows far away. ^endDiscuss(bow)
Recommendations give you access to the verbal inputs available to the user to interact with the robot when a Discuss action is running.
The Discuss action provides 3 different recommendation types:
Global recommendations:
Global recommendations correspond to all the activated u: rules loaded in the Discuss action.
val globalRecommendations: PhraseSet = discuss.globalRecommendations()
PhraseSet globalRecommendations = discuss.globalRecommendations();
Focused topic recommendations:
Focused topic recommendations correspond to all the activated u: rules in the currently focused topic.
val focusedTopicRecommendations: PhraseSet = discuss.focusedTopicRecommendations()
PhraseSet focusedTopicRecommendations = discuss.focusedTopicRecommendations();
Scope recommendations:
Scope recommendations correspond to all the activated sub-rules of the current scope.
val scopeRecommendations: PhraseSet = discuss.scopeRecommendations()
PhraseSet scopeRecommendations = discuss.scopeRecommendations();
Example:
top1.top:
topic: ~top1()
u:(color) what's your favourite color
u1:(blue) marine blue or sky blue
u2:(marine) Oh, like the sea then $color=marineblue
u2:(sky) Oh, like the sky then $color=skyblue
u1:(yellow) Oh, like the sand then $color=yellow
u1:(green) Oh, like the grass then $color=green
top2.top:
topic: ~top2()
u:(dogs) so you want to speak about dogs?
u:(cats) so you want to speak about cats?
Recommendation results:
// Discuss is running
discuss.globalRecommendations().phrases // ["color", "dogs", "cats"]
// User says "color"
discuss.globalRecommendations().phrases // ["color", "dogs", "cats"]
discuss.focusedTopicRecommendations().phrases // ["color"]
discuss.scopeRecommendations().phrases // ["yellow", "blue", "green"]
// User says "dogs"
discuss.globalRecommendations().phrases // ["color", "dogs", "cats"]
discuss.focusedTopicRecommendations().phrases // ["dogs", "cats"]
discuss.scopeRecommendations().phrases // []
// Discuss is running
discuss.globalRecommendations().getPhrases(); // ["color", "dogs", "cats"]
// User says "color"
discuss.globalRecommendations().getPhrases(); // ["color", "dogs", "cats"]
discuss.focusedTopicRecommendations().getPhrases(); // ["color"]
discuss.scopeRecommendations().getPhrases(); // ["yellow", "blue", "green"]
// User says "dogs"
discuss.globalRecommendations().getPhrases(); // ["color", "dogs", "cats"]
discuss.focusedTopicRecommendations().getPhrases(); // ["dogs", "cats"]
discuss.scopeRecommendations().getPhrases(); // []
Listening
To be understood, the user should only speak to the robot when the Discuss is in a listening state.
The listening state of the Discuss is accessible at any time, via the
getListening
method:
val isListening: Boolean = discuss.listening
Boolean isListening = discuss.getListening();
And a listener:
discuss.addOnListeningChangedListener { listening ->
// Called when the listening state changes.
}
discuss.addOnListeningChangedListener( listening -> {
// Called when the listening state changes.
});
Hearing
You can be notified when the robot hears human voice via the getHearing
method:
val isHearing: Boolean = discuss.hearing
Boolean isHearing = discuss.getHearing();
And a listener:
discuss.addOnHearingChangedListener { hearing ->
// Called when the hearing state changes.
}
discuss.addOnHearingChangedListener(hearing -> {
// Called when the hearing state changes.
});
Saying
The phrase the robot is saying is accessible via the getSaying
method:
val saying: Phrase? = discuss.saying
Phrase saying = discuss.getSaying();
And a listener:
discuss.addOnSayingChangedListener { sayingPhrase ->
// Called when the robot speaks.
}
discuss.addOnSayingChangedListener(sayingPhrase -> {
// Called when the robot speaks.
});
When the robot is not saying anything, the String contained in the Phrase is empty.
You can observe what the robot hears via a listener:
discuss.addOnHeardListener { heardPhrase ->
// Called when a phrase was recognized.
}
discuss.addOnHeardListener(heardPhrase -> {
// Called when a phrase was recognized.
});
Sometimes the robot detects human voice but cannot determine the content of the phrase said:
discuss.addOnNoPhraseRecognizedListener {
// Called when no phrase was recognized.
}
discuss.addOnNoPhraseRecognizedListener(() -> {
// Called when no phrase was recognized.
});
After the robot heard human speech, there can be 3 different cases:
Normal reply
The type of the reply is normal when the robot provides a provides an answer provided by any rule except fallback rules.
my_topic.top:
topic: ~normal_topic()
u: (hello) Hello!
It is accessible via a listener:
discuss.addOnNormalReplyFoundForListener { input ->
// Called when the reply has a normal type.
}
discuss.addOnNormalReplyFoundForListener(input -> {
// Called when the reply has a normal type.
});
Fallback reply
The type of the reply is fallback when a phrase was heard but the robot cannot provide a good answer, for example it matches a rule containing a e:Dialog/NotUnderstood
:
fallback_reply.top:
topic: ~fallback_reply()
u: (e:Dialog/NotUnderstood) I don't understand
In the case where the robot determined the content of the phrase said, the input
parameter will contain the phrase, otherwise, it will be empty.
discuss.addOnFallbackReplyFoundForListener { input -> {
// Called when the reply has a fallback type.
}
discuss.addOnFallbackReplyFoundForListener(input -> {
// Called when the reply has a fallback type.
});
No reply
If the user input doesn’t match a rule and there is no fallback reply, the robot will not reply.
In the case where the robot determined the content of the phrase said, the input
parameter will contain the phrase, otherwise, it will be empty.
discuss.addOnNoReplyFoundForListener { input -> {
// Called when no reply was found for the input.
}
discuss.addOnNoReplyFoundForListener(input -> {
// Called when no reply was found for the input.
});