如何在胡椒模拟器中模拟一个人?

How to simulate a person in pepper emulator?

我正在尝试让胡椒机器人听基本的语音命令。问题是该语言不受支持,我必须为此使用 google 语音转文本而不是机器人的默认识别库。 用模拟器测试这个比每次都在真正的机器人上安装会更方便。但是我找不到任何关于如何在模拟器中模拟一个人出现在机器人面前的信息。如果那不可能,也许有一些解决方法?

override fun onRobotFocusGained(qiContext: QiContext) {
    this.qiContext = qiContext
    Utils.defaultHolderBuilder(qiContext).build().async()?.release()

    qiContext.humanAwareness?.addOnHumansAroundChangedListener { humansAround ->
        if (humansAround.isNotEmpty()) {
            listenToHuman(qiContext, humansAround)
        }
    }
}

也许我可以只调用提供给 addOnUpdatedListener 的函数,但我应该如何调用它?也许从程序中模拟一些测试广播? listenToHuman 函数:

private fun listenToHuman(qiContext: QiContext, humansAround: MutableList<Human>) {
    val actuation: Actuation = qiContext.actuation
    val robotFrame: Frame = actuation.robotFrame()

    val closestHuman = ...get closest human

    closestHuman?.headFrame?.addOnUpdatedListener {
        val distance: Double = ...computeDistance

        if (availableForListening) {
            availableForListening = false

            Qi.onUiThread {
                mLastResultTextView.text = "Listening"
                mSpeechRecognizer.startListening(speechIntent)
            }
        }
    }
}

没有围绕 Pepper 模拟器的工具来模拟人类。 但是,您的测试可以自动化,并且可以模拟来自 Qi SDK 的 classes。

解决方案 1

this public sample, a mock LookAt action is used to test whether the code behaves properly upon success or failure. It uses Mockk这样做。

考虑到这一点,您也可以模拟 HumanAwareness class,在调用 getHumansAround 时提供模拟 Human,并触发listener of the humans around property。这是一项相当大的工作,尤其是当您知道这是 Java 对更简单的对象系统 libQi 的包装时。

解决方案 2

所以我写了a helper class to create Qi Objects directly in Kotlin(对不起Java),我用它来更容易地创建模拟:

abstract class FakeHumanAwareness: QiObjectImpl() {

    val humansAround = Property<List<Human>>(listOf())
    val recommendedHumanToApproach = Property(Human::class.java)
    val recommendedHumanToEngage = Property(Human::class.java)

    abstract fun makeEngageHuman(robotContext: RobotContext, human: Human): EngageHuman

    override fun advertise(objectBuilder: DynamicObjectBuilder): DynamicObjectBuilder {
        objectBuilder.advertiseProperty(this, FakeHumanAwareness::humansAround)
        objectBuilder.advertiseProperty(this, FakeHumanAwareness::recommendedHumanToApproach)
        objectBuilder.advertiseProperty(this, FakeHumanAwareness::recommendedHumanToEngage)
        objectBuilder.advertiseMethod(this, FakeHumanAwareness::makeEngageHuman)
        return objectBuilder
    }
}

然后我可以模拟它,并将其转换为 HumanAwareness 对象:

val fakeHumanAwareness: FakeHumanAwareness = spyk()
val humanAwareness: HumanAwareness = qiObjectCast(fakeHumanAwareness)

你可以对 Human 做同样的事情(FakeHuman class 不包括在这里),模拟它并直接设置 HumanAwareness.humansAround

val fakeHuman: FakeHuman = spyk()
val human: Human = qiObjectCast(fakeHuman)
fakeHumanAwareness.humansAround.setValue(listOf(human))

设置该值后,会自动调用侦听器,getHumansAround 将 return 该值。