Skip to content

Commit

Permalink
Removed handle_single_interlocutor_input (#130).
Browse files Browse the repository at this point in the history
  • Loading branch information
josephbirkner committed Oct 3, 2019
1 parent b2bb42f commit 43f8938
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 120 deletions.
9 changes: 3 additions & 6 deletions modules/ravestate_conio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@

import ravestate as rs

import ravestate_rawio as rawio
import ravestate_interloc as interloc

from reggol import get_logger
logger = get_logger(__name__)


with rs.Module(name="consoleio", depends=(rawio.mod, interloc.mod)) as mod:
with rs.Module(name="consoleio", depends=(rawio.mod,)) as mod:

@rs.state(cond=rs.sig_startup, read=interloc.prop_all)
@rs.state(cond=rs.sig_startup)
def console_input(ctx: rs.ContextWrapper):

while not ctx.shutting_down():
input_value = input("> ")
interloc.handle_single_interlocutor_input(ctx, input_value)
rawio.say(ctx, input_value)

@rs.state(read=rawio.prop_out)
def console_output(ctx):
Expand Down
78 changes: 22 additions & 56 deletions modules/ravestate_interloc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,73 +1,39 @@
import ravestate as rs
import ravestate_rawio as rawio
import ravestate_verbaliser as verbaliser
import ravestate_phrases_basic_en as lang
import ravestate_nlp as nlp
import ravestate_ontology as mem

from scientio.ontology.node import Node
from scientio.session import Session
from scientio.ontology.ontology import Ontology

from reggol import get_logger
logger = get_logger(__name__)

ANON_INTERLOC_ID = "anonymous_interlocutor"
ANON_INTERLOC_PATH = f"interloc:all:{ANON_INTERLOC_ID}"

with rs.Module(name="interloc", depends=(rawio.mod, verbaliser.mod, mem.mod)) as mod:

with rs.Module(name="interloc", depends=(nlp.mod, mem.mod)) as mod:

# TODO: Make interloc:all a special property type, that only accepts ScientioNodeProperty as children
prop_all = rs.Property(name="all", allow_read=True, allow_write=False, allow_push=True, allow_pop=True)
prop_persisted = rs.Property(name="persisted", allow_read=True, allow_write=True, allow_push=True, allow_pop=True,
always_signal_changed=True)


def handle_single_interlocutor_input(ctx: rs.ContextWrapper, input_value: str, id=ANON_INTERLOC_ID) -> None:
"""
Forwards input to `rawio:in` and manages creation/deletion of a singleton
interlocutor. A new interlocutor node is pushed, when the input is a greeting,
and there is no interlocutor present. The interlocutor is popped,
if the input is a farewell, and there is an interlocutor present.
* `ctx`: Context Wrapper of the calling state. Must have read permissions
for `interloc:all`.
* `input_value`: The string input value that should be written to `rawio:in`.
* `id`: Name of the interlocutor context property, and initial name for
the interlocutor's Neo4j node (until a proper name is set by persqa).
"""

@rs.receptor(ctx_wrap=ctx, write=rawio.prop_in)
def write_input(ctx_input, value: str):
ctx_input[rawio.prop_in] = value

@rs.receptor(ctx_wrap=ctx, write=prop_all)
def push_interloc(ctx: rs.ContextWrapper, interlocutor_node: Node):
if ctx.push(
parent_property_or_path=prop_all,
child=rs.Property(name=id, default_value=interlocutor_node)):
logger.debug(f"Pushed {interlocutor_node} to interloc:all")

@rs.receptor(ctx_wrap=ctx, write=prop_all)
def pop_interloc(ctx: rs.ContextWrapper):
if ctx.pop(f"interloc:all:{id}"):
logger.debug(f"Popped interloc:all:{id}")

write_input(input_value)

interloc_exists = f"interloc:all:{id}" in ctx.enum(prop_all)

# push Node if you got a greeting
if input_value.strip() in verbaliser.get_phrase_list(lang.intent_greeting) and not interloc_exists:
# set up scientio
mem.initialized.wait()
onto: Ontology = mem.get_ontology()

# create scientio Node of type Person
new_interloc = Node(metatype=onto.get_type("Person"))
new_interloc.set_name(id)
push_interloc(new_interloc)

# pop Node if you got a farewell
elif input_value.strip() in verbaliser.get_phrase_list("farewells") and interloc_exists:
pop_interloc()
@rs.state(cond=nlp.sig_intent_hi, write=prop_all)
def push_interlocutor(ctx):
interloc_exists = ANON_INTERLOC_PATH in ctx.enum(prop_all)
if not interloc_exists:
mem.initialized.wait()
onto: Ontology = mem.get_ontology()
new_interloc = Node(metatype=onto.get_type("Person"))
new_interloc.set_name(ANON_INTERLOC_ID)
if ctx.push(
parent_property_or_path=prop_all,
child=rs.Property(name=ANON_INTERLOC_ID, default_value=new_interloc)):
logger.debug(f"Pushed {new_interloc} to interloc:all")

@rs.state(cond=nlp.sig_intent_bye, write=prop_all)
def pop_interlocutor(ctx):
interloc_exists = ANON_INTERLOC_PATH in ctx.enum(prop_all)
if interloc_exists and ctx.pop(ANON_INTERLOC_PATH):
logger.debug(f"Popped {ANON_INTERLOC_PATH}")
27 changes: 20 additions & 7 deletions modules/ravestate_nlp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import ravestate as rs

import ravestate_rawio as rawio
import ravestate_verbaliser as verbaliser
import ravestate_phrases_basic_en as lang

from .question_word import QuestionWord
from .triple import Triple
from .extract_triples import extract_triples
Expand Down Expand Up @@ -53,7 +56,8 @@ def roboy_getter(doc) -> bool:
sig_contains_roboy = rs.Signal(name="contains-roboy")
sig_is_question = rs.Signal(name="is-question")
sig_intent_play = rs.Signal(name="intent-play")

sig_intent_hi = rs.Signal(name="intent-hi")
sig_intent_bye = rs.Signal(name="intent-bye")

@rs.state(read=rawio.prop_in, write=(prop_tokens, prop_postags, prop_lemmas, prop_tags, prop_ner, prop_triples, prop_roboy, prop_yesno))
def nlp_preprocess(ctx):
Expand Down Expand Up @@ -97,23 +101,32 @@ def nlp_preprocess(ctx):
logger.info(f"[NLP:yesno]: {nlp_yesno}")

@rs.state(signal=sig_contains_roboy, read=prop_roboy)
def nlp_contains_roboy_signal(ctx):
def recognize_roboy(ctx):
if ctx[prop_roboy]:
return rs.Emit()
return False

@rs.state(signal=sig_is_question, read=(prop_triples, prop_tags))
def nlp_is_question_signal(ctx):
def recognize_question(ctx):
if ctx[prop_triples][0].is_question():
return rs.Emit()
return False

@rs.state(signal=sig_intent_play, read=prop_triples)
def nlp_intent_play_signal(ctx):
def recognize_intent_play(ctx):
nlp_triples = ctx[prop_triples]
if nlp_triples[0].match_either_lemma(pred={"play"}, obj={"game"}):
return rs.Emit()
return False

@rs.state(signal=sig_intent_hi, read=rawio.prop_in)
def recognize_intent_hi(ctx):
input_value = (ctx[rawio.prop_in] or "").strip().lower()
if input_value in verbaliser.get_phrase_list(lang.intent_greeting):
return rs.Emit()

@rs.state(signal=sig_intent_bye, read=rawio.prop_in)
def recognize_intent_bye(ctx):
input_value = (ctx[rawio.prop_in] or "").strip().lower()
if input_value in verbaliser.get_phrase_list(lang.intent_farewells):
return rs.Emit()

def detect_yesno_question(tags):
"""
Expand Down
11 changes: 11 additions & 0 deletions modules/ravestate_rawio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,14 @@
allow_pop=False,
allow_push=False,
always_signal_changed=True)


def say(ctx, what: str) -> None:
"""
Calls an internal receptor to write a value to `rawio.prop_in`.
Use this function in any IO module that has a state with a long-running loop.
"""
@rs.receptor(ctx_wrap=ctx, write=prop_in)
def write_input(ctx_input, value: str):
ctx_input[prop_in] = value
write_input(what)
43 changes: 6 additions & 37 deletions modules/ravestate_roboyio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,7 @@
3. pyroboy
--------
""")
import time
global listen_start_timestamp
global say_end_timestamp
listen_start_timestamp = 0
say_end_timestamp = 0


if PYROBOY_AVAILABLE:

Expand Down Expand Up @@ -75,7 +71,6 @@
LUCKY_EMOTION = "lucky"
KISS_EMOTION = "kiss"


with rs.Module(
name="roboyio",
config=CONFIG,
Expand All @@ -94,34 +89,12 @@
msg_type=RecognizedSpeech,
always_signal_changed=True)

@rs.state(cond=recognized_speech.changed(), read=(interloc.prop_all,recognized_speech.id()) )
@rs.state(cond=recognized_speech.changed(), read=(interloc.prop_all, recognized_speech), write=rawio.prop_in)
def roboy_input(ctx: rs.ContextWrapper):

# global say_end_timestamp
logger.info("in roboy_input again")
result = ctx[recognized_speech.id()]
# listen_start_timestamp = result.start_timestamp
# if say_end_timestamp >= listen_start_timestamp:
# logger.info("Discarded: " + str(result.text))
# result = None
# interloc.handle_single_interlocutor_input(ctx, "")
# else:
result = ctx[recognized_speech.changed()]
if result.text:
logger.info(result.text)
interloc.handle_single_interlocutor_input(ctx, result.text)

# while not ctx.shutting_down():
# listen_start_timestamp = time.time()
# result = result = ctx[recognized_speech.id()]
# print(result)
# logger.info(f"pyroboy.listen() -> {result}")
# if say_end_timestamp >= listen_start_timestamp:
# logger.info("Discarded: " + str(result))
# result = None
# interloc.handle_single_interlocutor_input(ctx, "")
# else:
# if result:
# interloc.handle_single_interlocutor_input(ctx, result)
logger.info("Input:", result.text)
rawio.say(ctx, result.text)

@rs.state(read=rawio.prop_out)
def roboy_output(ctx):
Expand All @@ -132,15 +105,11 @@ def roboy_output(ctx):
except:
logger.info("does /raveskills/off.sh exist?")
with say_lock:
# logger.warn(unidecode(ctx[rawio.prop_out.changed()]))
ret = say(unidecode(ctx[rawio.prop_out.changed()]))
say_end_timestamp = time.time()
say(unidecode(ctx[rawio.prop_out.changed()]))
try:
os.system('/raveskills/rainbow.sh')
except:
logger.info("does /raveskills/rainbow.sh exist?")
# logger.info(f"pyroboy.say({ctx[rawio.prop_out.changed()]}) -> {ret}")\


@rs.state(cond=rawio.prop_in.changed() | idle.sig_bored, write=(prop_head_axis0, prop_head_axis1, prop_head_axis2))
def move_head(ctx: rs.ContextWrapper):
Expand Down
9 changes: 4 additions & 5 deletions modules/ravestate_visionio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import ravestate as rs
import ravestate_rawio as rawio
import ravestate_interloc as interloc
import ravestate_ontology as mem
import ravestate_persqa as persqa
import ravestate_ros1 as ros

from ravestate_visionio.faceoraclefilter import FaceOracleFilter, Person
from scientio.session import Session
from scientio.ontology.ontology import Ontology
Expand Down Expand Up @@ -33,18 +32,18 @@
REDIS_PASS_CONF = "redis_pass"
ROS1_FACE_TOPIC_CONFIG = "ros1-node"
FACE_CONFIDENCE_THRESHOLD = "min-confidence"
PERSON_DISAPPEARED_THRESHOLD = "person-disappeared-treshold"
PERSON_DISAPPEARED_THRESHOLD = "person-disappeared-threshold"

CONFIG = {
REDIS_HOST_CONF: "localhost",
REDIS_PORT_CONF: 6379,
REDIS_PASS_CONF: "pass",
ROS1_FACE_TOPIC_CONFIG: "/roboy/cognition/vision/visible_face_names",
FACE_CONFIDENCE_THRESHOLD: 0.85,
PERSON_DISAPPEARED_THRESHOLD: 4
PERSON_DISAPPEARED_THRESHOLD: 5
}

with rs.Module(name="visionio", config=CONFIG) as mod:
with rs.Module(name="visionio", config=CONFIG, depends=(interloc.mod, mem.mod, ros.mod)) as mod:

prop_subscribe_faces = ros.Ros1SubProperty(
"face_names",
Expand Down
14 changes: 5 additions & 9 deletions test/modules/ravestate_persqa/test_qa.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,21 @@
import ravestate_interloc as interloc
import ravestate_rawio as rawio
import ravestate_persqa as persqa
import ravestate_idle as idle
import ravestate_ontology
import ravestate_verbaliser as verbaliser


from reggol import get_logger, set_default_loglevel
logger = get_logger(__name__)


#@pytest.mark.skip(reason="Might interfere with visionIO tests.")
def test_run_qa():
last_output = ""

with rs.Module(name="persqa_test"):

@rs.state(cond=rs.sig_startup, read=interloc.prop_all)
@rs.state(cond=rs.sig_startup, write=rawio.prop_in)
def persqa_hi(ctx: rs.ContextWrapper):
ravestate_ontology.initialized.wait()
interloc.handle_single_interlocutor_input(ctx, "hi")
ctx[rawio.prop_in] = "hi"

@rs.state(read=rawio.prop_out)
def raw_out(ctx: rs.ContextWrapper):
Expand All @@ -44,9 +40,9 @@ def say(ctx: rs.ContextWrapper, what: str):
ctx[rawio.prop_in] = what

ctx.emit(rs.sig_startup)
ctx.run_once()

assert persqa_hi.wait()
while not persqa_hi.wait(.1):
ctx.run_once(debug=True)
ctx.test()

# Wait for name being asked
while not raw_out.wait(.1):
Expand Down

0 comments on commit 43f8938

Please sign in to comment.