1346 lines
57 KiB
JavaScript
1346 lines
57 KiB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jiboEmotionSystem = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
|
"use strict";
|
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const SensorySystem_1 = require("./sensing/SensorySystem");
|
|
const AppraisalSystem_1 = require("./appraisal/AppraisalSystem");
|
|
const ExpressionSystem_1 = require("./expression/ExpressionSystem");
|
|
const EmotionSpace_1 = require("./emotion/EmotionSpace");
|
|
const jibo_typed_events_1 = require("jibo-typed-events");
|
|
const rules_1 = require("./appraisal/rules");
|
|
const EmotionalExpression_1 = require("./expression/EmotionalExpression");
|
|
const Emotion_1 = require("./emotion/Emotion");
|
|
const TouchSensor_1 = require("./sensing/sensors/TouchSensor");
|
|
const MimSensor_1 = require("./sensing/sensors/MimSensor");
|
|
const ExternalImpactSensor_1 = require("./sensing/sensors/ExternalImpactSensor");
|
|
const MotorFaultSensor_1 = require("./sensing/sensors/MotorFaultSensor");
|
|
const Types_1 = require("./common/Types");
|
|
const EmotionDefinitions_1 = require("./emotion/EmotionDefinitions");
|
|
const IdentitySensor_1 = require("./sensing/sensors/IdentitySensor");
|
|
const IdentityRule_1 = require("./appraisal/rules/IdentityRule");
|
|
const log_1 = require("./log");
|
|
const log = log_1.default.createChild("EmotionSystem");
|
|
class EmotionEvents extends jibo_typed_events_1.EventContainer {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.emotionChanged = new jibo_typed_events_1.Event('Emotion has changed');
|
|
}
|
|
}
|
|
exports.EmotionEvents = EmotionEvents;
|
|
class EmotionSystem {
|
|
constructor(debug = true) {
|
|
this.history = [];
|
|
this.events = new EmotionEvents();
|
|
this.emotions = [];
|
|
EmotionDefinitions_1.DEFAULT_EMOTIONS.forEach((emotionValues, emotionName) => {
|
|
let emotion = new Emotion_1.Emotion(emotionName, emotionValues.valence, emotionValues.confidence);
|
|
this.emotions.push(emotion);
|
|
});
|
|
this._emotionSpace = new EmotionSpace_1.EmotionSpace(this);
|
|
this._expressions = new Map();
|
|
this._expressionSystem = new ExpressionSystem_1.ExpressionSystem(this);
|
|
this.sensors = [
|
|
new ExternalImpactSensor_1.ExternalImpactSensor(this),
|
|
new IdentitySensor_1.IdentitySensor(this),
|
|
new TouchSensor_1.TouchSensor(this),
|
|
new MotorFaultSensor_1.MotorFaultSensor(this),
|
|
new MimSensor_1.MimSensor(this)
|
|
];
|
|
this._sensorySystem = new SensorySystem_1.SensorySystem(this);
|
|
this.rules = [
|
|
new IdentityRule_1.IdentityRule(Types_1.RuleNames.IdentityRule, this),
|
|
new rules_1.TouchRule(Types_1.RuleNames.TouchRule, this),
|
|
new rules_1.ExternalImpactRule(Types_1.RuleNames.SkillInputRule, this),
|
|
new rules_1.MotorFaultRule(Types_1.RuleNames.MotorFaultRule, this),
|
|
new rules_1.MimRule(Types_1.RuleNames.MimRule, this)
|
|
];
|
|
this._appraisalSystem = new AppraisalSystem_1.AppraisalSystem(this);
|
|
}
|
|
init(options) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
this.jibo = options.jibo;
|
|
EmotionDefinitions_1.DEFAULT_EMOTIONS.forEach((emotion, emotionName) => {
|
|
this._expressions.set(emotionName, new EmotionalExpression_1.EmotionalExpression(emotionName, this));
|
|
});
|
|
this._expressionSystem.init(this._expressions);
|
|
this._emotionSpace.init(this.emotions);
|
|
this._sensorySystem.init(this.sensors);
|
|
this.rules.forEach((rule) => {
|
|
rule.init(this._sensorySystem);
|
|
});
|
|
this._appraisalSystem.init(this.rules);
|
|
this._appraisalSystem.events.impactTriggered.on((emotionTrace) => {
|
|
this._emotionSpace.update(emotionTrace);
|
|
});
|
|
this._emotionSpace.events.updated.on((emotionTrace) => {
|
|
this._expressionSystem.trackSnuggle(emotionTrace);
|
|
});
|
|
this._emotionSpace.events.changeEvent.on((emotion) => {
|
|
this.events.emotionChanged.emit(emotion);
|
|
});
|
|
});
|
|
}
|
|
dispose() {
|
|
this.events.removeAllListeners();
|
|
this.rules.forEach((rule) => {
|
|
rule.dispose();
|
|
});
|
|
this.rules = [];
|
|
this.sensors = [];
|
|
this._emotionSpace.dispose();
|
|
this._appraisalSystem.dispose();
|
|
this._sensorySystem.dispose();
|
|
this._expressionSystem.dispose();
|
|
}
|
|
getNearestEmotion(referencePoint) {
|
|
const nearestEmotion = this._emotionSpace.getNearestEmotion(referencePoint);
|
|
log.debug(`getNearestEmotion: ${nearestEmotion.name}`);
|
|
return nearestEmotion;
|
|
}
|
|
getCurrentEmotionalValues() {
|
|
const currentEmotionPosition = this._emotionSpace.getCurrentPosition();
|
|
log.debug(`getCurrentEmotionalValues [valence:${currentEmotionPosition.valence}, confidence:${currentEmotionPosition.confidence}]`);
|
|
return currentEmotionPosition;
|
|
}
|
|
triggerImpact(impactPoint) {
|
|
log.debug("triggerImpact", impactPoint);
|
|
const sensor = this._sensorySystem.getSensor(ExternalImpactSensor_1.ExternalImpactSensor.SENSOR_NAME);
|
|
sensor.supplyData(impactPoint);
|
|
}
|
|
triggerTouch(options) {
|
|
log.debug("triggerTouch", options);
|
|
const ts = this._sensorySystem.getSensor(TouchSensor_1.TouchSensor.SENSOR_NAME);
|
|
ts.jiboWasTouched(options);
|
|
}
|
|
reactToHeadTouch(pads) {
|
|
const ts = this._sensorySystem.getSensor(TouchSensor_1.TouchSensor.SENSOR_NAME);
|
|
return ts.reactToHeadTouch(pads);
|
|
}
|
|
}
|
|
exports.EmotionSystem = EmotionSystem;
|
|
|
|
},{"./appraisal/AppraisalSystem":3,"./appraisal/rules":12,"./appraisal/rules/IdentityRule":8,"./common/Types":13,"./emotion/Emotion":16,"./emotion/EmotionDefinitions":17,"./emotion/EmotionSpace":18,"./expression/EmotionalExpression":21,"./expression/ExpressionSystem":23,"./log":25,"./sensing/SensorySystem":27,"./sensing/sensors/ExternalImpactSensor":30,"./sensing/sensors/IdentitySensor":31,"./sensing/sensors/MimSensor":32,"./sensing/sensors/MotorFaultSensor":33,"./sensing/sensors/TouchSensor":35,"jibo-typed-events":undefined}],2:[function(require,module,exports){
|
|
"use strict";
|
|
function __export(m) {
|
|
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
|
}
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const EmotionSystem_1 = require("./EmotionSystem");
|
|
const Emotion_1 = require("./emotion/Emotion");
|
|
exports.Emotion = Emotion_1.Emotion;
|
|
const Types_1 = require("./common/Types");
|
|
const EmotionDefinitions_1 = require("./emotion/EmotionDefinitions");
|
|
__export(require("./common/Types"));
|
|
function init(initOptions) {
|
|
exports._runtime = new EmotionSystem_1.EmotionSystem();
|
|
exports.events = exports._runtime.events;
|
|
return exports._runtime.init(initOptions);
|
|
}
|
|
exports.init = init;
|
|
function getNearestEmotion() {
|
|
return exports._runtime.getNearestEmotion();
|
|
}
|
|
exports.getNearestEmotion = getNearestEmotion;
|
|
function getCurrentEmotionalValues() {
|
|
return exports._runtime.getCurrentEmotionalValues();
|
|
}
|
|
exports.getCurrentEmotionalValues = getCurrentEmotionalValues;
|
|
function triggerImpact(impact) {
|
|
let valenceImpact = EmotionDefinitions_1.ImpactValues.get(impact.valence) || 0;
|
|
let confidenceImpact = EmotionDefinitions_1.ImpactValues.get(impact.confidence) || 0;
|
|
const emoImpact = new Types_1.EmotionPoint(valenceImpact, confidenceImpact);
|
|
exports._runtime.triggerImpact(emoImpact);
|
|
}
|
|
exports.triggerImpact = triggerImpact;
|
|
function reactToHeadTouch(pads) {
|
|
return exports._runtime.reactToHeadTouch(pads);
|
|
}
|
|
exports.reactToHeadTouch = reactToHeadTouch;
|
|
|
|
},{"./EmotionSystem":1,"./common/Types":13,"./emotion/Emotion":16,"./emotion/EmotionDefinitions":17}],3:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const jibo_typed_events_1 = require("jibo-typed-events");
|
|
const Types_1 = require("../common/Types");
|
|
class AppraisalEvents extends jibo_typed_events_1.EventContainer {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.impactTriggered = new jibo_typed_events_1.Event('Impact triggered!');
|
|
}
|
|
}
|
|
exports.AppraisalEvents = AppraisalEvents;
|
|
class AppraisalSystem {
|
|
constructor(parent) {
|
|
this.events = new AppraisalEvents();
|
|
this.rules = new Map();
|
|
this.parent = parent;
|
|
}
|
|
init(rules) {
|
|
rules.forEach(rule => {
|
|
this.rules.set(Types_1.RuleNames[rule.name], rule);
|
|
});
|
|
this._registerRules();
|
|
}
|
|
dispose() {
|
|
this.events.removeAllListeners();
|
|
}
|
|
_registerRules() {
|
|
this.rules.forEach((rule) => {
|
|
rule.events.impactTriggered.on((emotionTrace) => {
|
|
this.events.impactTriggered.emit(emotionTrace);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
exports.AppraisalSystem = AppraisalSystem;
|
|
|
|
},{"../common/Types":13,"jibo-typed-events":undefined}],4:[function(require,module,exports){
|
|
"use strict";
|
|
function __export(m) {
|
|
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
|
}
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
__export(require("./AppraisalSystem"));
|
|
const rules = require("./rules");
|
|
exports.rules = rules;
|
|
|
|
},{"./AppraisalSystem":3,"./rules":12}],5:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const AppraisalRule_1 = require("./AppraisalRule");
|
|
const ASRInputSensor_1 = require("../../sensing/sensors/ASRInputSensor");
|
|
const EmotionTrace_1 = require("../../emotion/EmotionTrace");
|
|
const Types_1 = require("../../common/Types");
|
|
const log_1 = require("../../log");
|
|
const log = log_1.default.createChild('Appraisal.ASRTextInputRule');
|
|
const DESIRABLE_WORDS = [
|
|
'good',
|
|
'great',
|
|
'love',
|
|
'awesome',
|
|
'amazing',
|
|
'like',
|
|
'wonderful',
|
|
'happy',
|
|
'lovely',
|
|
'beautiful',
|
|
'handsome',
|
|
'gorgeous',
|
|
];
|
|
const DESIRABLE_WORD_PATTERN = new RegExp(DESIRABLE_WORDS.join('|'), 'g');
|
|
const UNDESIRED_WORDS = [
|
|
'hate',
|
|
'horrible',
|
|
'dumb',
|
|
'stupid',
|
|
'ugly',
|
|
'bad',
|
|
'suck',
|
|
'bitch',
|
|
'fuck',
|
|
'shit',
|
|
'crap',
|
|
'moron',
|
|
'idiot',
|
|
'wanker',
|
|
];
|
|
const UNDESIRABLE_WORD_PATTERN = new RegExp(UNDESIRED_WORDS.join('|'), 'g');
|
|
class ASRTextInputRule extends AppraisalRule_1.AppraisalRule {
|
|
constructor(name, parent) {
|
|
super(name, parent);
|
|
}
|
|
init(sensorySystem) {
|
|
this.asrSensor = sensorySystem.getSensor(ASRInputSensor_1.ASRInputSensor.SENSOR_NAME);
|
|
if (!this.asrSensor) {
|
|
throw new Error(`ASR sensor is required, but doesn't exist.`);
|
|
}
|
|
this.asrSensor.events.newDataEvent.on((sensorDataWrapper) => {
|
|
this.createAndRegisterImpact(sensorDataWrapper);
|
|
});
|
|
}
|
|
createAndRegisterImpact(sensorDataWrapper) {
|
|
log.debug('Appraising ASR data:', sensorDataWrapper.sensorData);
|
|
let impactRatio = this.appraiseData(sensorDataWrapper.sensorData);
|
|
let myTrace = new EmotionTrace_1.EmotionTrace([sensorDataWrapper], this, new Types_1.EmotionPoint(impactRatio));
|
|
if (impactRatio >= .25 || impactRatio <= .25) {
|
|
log.debug(`impactRatio was ${impactRatio}`);
|
|
myTrace.emotionalImpact = new Types_1.EmotionPoint(impactRatio);
|
|
this.events.impactTriggered.emit(myTrace);
|
|
}
|
|
else {
|
|
log.debug(`impactRatio was ${impactRatio}: not impactful enough to make a difference`);
|
|
}
|
|
}
|
|
appraiseData(txtInput) {
|
|
let badWords = txtInput.match(UNDESIRABLE_WORD_PATTERN) || [];
|
|
let goodWords = txtInput.match(DESIRABLE_WORD_PATTERN) || [];
|
|
let totalWordCount = txtInput.split(/[;.,\s+]/g).length;
|
|
let wordEffectValue = goodWords.length - badWords.length;
|
|
return wordEffectValue / totalWordCount;
|
|
}
|
|
dispose() {
|
|
this.asrSensor.events.removeAllListeners();
|
|
}
|
|
}
|
|
exports.ASRTextInputRule = ASRTextInputRule;
|
|
|
|
},{"../../common/Types":13,"../../emotion/EmotionTrace":19,"../../log":25,"../../sensing/sensors/ASRInputSensor":29,"./AppraisalRule":6}],6:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const jibo_typed_events_1 = require("jibo-typed-events");
|
|
class AppraisalRuleEvents extends jibo_typed_events_1.EventContainer {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.impactTriggered = new jibo_typed_events_1.Event('Impact has been triggered.');
|
|
}
|
|
}
|
|
exports.AppraisalRuleEvents = AppraisalRuleEvents;
|
|
class AppraisalRule {
|
|
constructor(name, parent) {
|
|
this.name = name;
|
|
this.parent = parent;
|
|
this.events = new AppraisalRuleEvents();
|
|
return;
|
|
}
|
|
}
|
|
exports.AppraisalRule = AppraisalRule;
|
|
|
|
},{"jibo-typed-events":undefined}],7:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const AppraisalRule_1 = require("./AppraisalRule");
|
|
const ExternalImpactSensor_1 = require("../../sensing/sensors/ExternalImpactSensor");
|
|
const EmotionTrace_1 = require("../../emotion/EmotionTrace");
|
|
const log_1 = require("../../log");
|
|
const log = log_1.default.createChild('Appraisal.ExternalImpactRule');
|
|
class ExternalImpactRule extends AppraisalRule_1.AppraisalRule {
|
|
constructor(name, parent) {
|
|
super(name, parent);
|
|
}
|
|
init(sensorySystem) {
|
|
this.sensor = sensorySystem.getSensor(ExternalImpactSensor_1.ExternalImpactSensor.SENSOR_NAME);
|
|
if (!this.sensor) {
|
|
throw new Error(`Skill sensor is required, but doesn't exist.`);
|
|
}
|
|
this.sensor.events.newDataEvent.on((sensorDataWrapper) => {
|
|
this.createAndRegisterImpact(sensorDataWrapper);
|
|
});
|
|
}
|
|
createAndRegisterImpact(sensorDataWrapper) {
|
|
log.debug("creating impact", sensorDataWrapper);
|
|
let myTrace = new EmotionTrace_1.EmotionTrace([sensorDataWrapper], this, this.appraiseData(sensorDataWrapper.sensorData));
|
|
this.events.impactTriggered.emit(myTrace);
|
|
}
|
|
appraiseData(skillData) {
|
|
return skillData;
|
|
}
|
|
dispose() {
|
|
this.sensor.events.removeAllListeners();
|
|
}
|
|
}
|
|
exports.ExternalImpactRule = ExternalImpactRule;
|
|
|
|
},{"../../emotion/EmotionTrace":19,"../../log":25,"../../sensing/sensors/ExternalImpactSensor":30,"./AppraisalRule":6}],8:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const AppraisalRule_1 = require("./AppraisalRule");
|
|
const EmotionTrace_1 = require("../../emotion/EmotionTrace");
|
|
const Types_1 = require("../../common/Types");
|
|
const IdentitySensor_1 = require("../../sensing/sensors/IdentitySensor");
|
|
const log_1 = require("../../log");
|
|
const log = log_1.default.createChild('Appraisal.IdentityRule');
|
|
class IdentityRule extends AppraisalRule_1.AppraisalRule {
|
|
constructor(name, parent) {
|
|
super(name, parent);
|
|
}
|
|
init(sensorySystem) {
|
|
this.identitySensor = sensorySystem.getSensor(IdentitySensor_1.IdentitySensor.SENSOR_NAME);
|
|
if (!this.identitySensor) {
|
|
throw new Error(`Identity sensor is required, doesn't exist.`);
|
|
}
|
|
this.identitySensor.events.newDataEvent.on((sensorDataWrapper) => {
|
|
log.info('Appraising data from identity data:', sensorDataWrapper.sensorData);
|
|
let myTrace = new EmotionTrace_1.EmotionTrace([sensorDataWrapper], this, this.appraiseData(sensorDataWrapper.sensorData));
|
|
this.events.impactTriggered.emit(myTrace);
|
|
});
|
|
}
|
|
appraiseData(input) {
|
|
switch (input) {
|
|
case Types_1.IdentityEvents.VISIBLE_FACE_STARTED:
|
|
return new Types_1.EmotionPoint(Types_1.RuleImpactValues.VISIBLE_FACE_STARTED_VALENCE, Types_1.RuleImpactValues.VISIBLE_FACE_STARTED_CONFIDENCE);
|
|
case Types_1.IdentityEvents.ID_ACQUIRED:
|
|
return new Types_1.EmotionPoint(Types_1.RuleImpactValues.ID_ACQUIRED_VALENCE, Types_1.RuleImpactValues.ID_ACQUIRED_CONFIDENCE);
|
|
default:
|
|
log.warn('got ID event with no matching emotion impact', input);
|
|
return new Types_1.EmotionPoint();
|
|
}
|
|
}
|
|
dispose() {
|
|
this.identitySensor.events.removeAllListeners();
|
|
}
|
|
}
|
|
exports.IdentityRule = IdentityRule;
|
|
|
|
},{"../../common/Types":13,"../../emotion/EmotionTrace":19,"../../log":25,"../../sensing/sensors/IdentitySensor":31,"./AppraisalRule":6}],9:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const AppraisalRule_1 = require("./AppraisalRule");
|
|
const MimSensor_1 = require("../../sensing/sensors/MimSensor");
|
|
const EmotionTrace_1 = require("../../emotion/EmotionTrace");
|
|
const Types_1 = require("../../common/Types");
|
|
const log_1 = require("../../log");
|
|
const log = log_1.default.createChild('Appraisal.MIMRule');
|
|
class MimRule extends AppraisalRule_1.AppraisalRule {
|
|
constructor(name, parent) {
|
|
super(name, parent);
|
|
}
|
|
init(sensorySystem) {
|
|
this.mimSensor = sensorySystem.getSensor(MimSensor_1.MimSensor.SENSOR_NAME);
|
|
if (!this.mimSensor) {
|
|
throw new Error(`MimSensor is required, doesn't exist.`);
|
|
}
|
|
this.mimSensor.events.newDataEvent.on((sensorDataWrapper) => {
|
|
log.debug("event data", sensorDataWrapper);
|
|
let myTrace = new EmotionTrace_1.EmotionTrace([sensorDataWrapper], this, this.appraiseData(sensorDataWrapper.sensorData));
|
|
this.events.impactTriggered.emit(myTrace);
|
|
});
|
|
}
|
|
appraiseData(mimState) {
|
|
return new Types_1.EmotionPoint(Types_1.RuleImpactValues.MIM_ERROR_VALENCE, Types_1.RuleImpactValues.MIM_ERROR_CONFIDENCE);
|
|
}
|
|
dispose() {
|
|
this.mimSensor.events.removeAllListeners();
|
|
}
|
|
}
|
|
exports.MimRule = MimRule;
|
|
|
|
},{"../../common/Types":13,"../../emotion/EmotionTrace":19,"../../log":25,"../../sensing/sensors/MimSensor":32,"./AppraisalRule":6}],10:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const AppraisalRule_1 = require("./AppraisalRule");
|
|
const MotorFaultSensor_1 = require("../../sensing/sensors/MotorFaultSensor");
|
|
const EmotionTrace_1 = require("../../emotion/EmotionTrace");
|
|
const Types_1 = require("../../common/Types");
|
|
const log_1 = require("../../log");
|
|
const log = log_1.default.createChild('Appraisal.MotorFaultRule');
|
|
class MotorFaultRule extends AppraisalRule_1.AppraisalRule {
|
|
constructor(name, parent) {
|
|
super(name, parent);
|
|
}
|
|
init(sensorySystem) {
|
|
this.touchSensor = sensorySystem.getSensor(MotorFaultSensor_1.MotorFaultSensor.SENSOR_NAME);
|
|
if (!this.touchSensor) {
|
|
throw new Error(`MotorFaultSensor sensor is required, doesn't exist.`);
|
|
}
|
|
this.touchSensor.events.newDataEvent.on((sensorDataWrapper) => {
|
|
log.info('Appraising data from MotorFault data:', sensorDataWrapper.sensorData);
|
|
this.parent.jibo.analytics.track("Snuggle Occurred", { type: "Motor Fault" });
|
|
let myTrace = new EmotionTrace_1.EmotionTrace([sensorDataWrapper], this, this.appraiseData(sensorDataWrapper.sensorData));
|
|
this.events.impactTriggered.emit(myTrace);
|
|
});
|
|
}
|
|
appraiseData(input) {
|
|
log.debug(`motor fault`);
|
|
return new Types_1.EmotionPoint(Types_1.RuleImpactValues.MOTOR_FAULT_VALENCE, Types_1.RuleImpactValues.MOTOR_FAULT_CONFIDENCE);
|
|
}
|
|
dispose() {
|
|
this.touchSensor.events.removeAllListeners();
|
|
}
|
|
}
|
|
exports.MotorFaultRule = MotorFaultRule;
|
|
|
|
},{"../../common/Types":13,"../../emotion/EmotionTrace":19,"../../log":25,"../../sensing/sensors/MotorFaultSensor":33,"./AppraisalRule":6}],11:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const AppraisalRule_1 = require("./AppraisalRule");
|
|
const TouchSensor_1 = require("../../sensing/sensors/TouchSensor");
|
|
const EmotionTrace_1 = require("../../emotion/EmotionTrace");
|
|
const Types_1 = require("../../common/Types");
|
|
const log_1 = require("../../log");
|
|
const log = log_1.default.createChild('Appraisal.TouchRule');
|
|
class TouchRule extends AppraisalRule_1.AppraisalRule {
|
|
constructor(name, parent) {
|
|
super(name, parent);
|
|
}
|
|
init(sensorySystem) {
|
|
this.touchSensor = sensorySystem.getSensor(TouchSensor_1.TouchSensor.SENSOR_NAME);
|
|
if (!this.touchSensor) {
|
|
throw new Error(`TouchSensor sensor is required, doesn't exist.`);
|
|
}
|
|
this.touchSensor.events.newDataEvent.on((sensorDataWrapper) => {
|
|
let myTrace = new EmotionTrace_1.EmotionTrace([sensorDataWrapper], this, this.appraiseData(sensorDataWrapper.sensorData));
|
|
this.events.impactTriggered.emit(myTrace);
|
|
});
|
|
}
|
|
appraiseData(input) {
|
|
if (input.type === Types_1.TouchTypes.HEAD_LEFT || input.type === Types_1.TouchTypes.HEAD_RIGHT) {
|
|
log.info(`jibo had a head touch`, input.type);
|
|
return new Types_1.EmotionPoint(Types_1.RuleImpactValues.HEAD_TOUCH_VALENCE, Types_1.RuleImpactValues.HEAD_TOUCH_CONFIDENCE);
|
|
}
|
|
else if (input.type === Types_1.TouchTypes.TICKLE) {
|
|
log.info(`jibo was tickled`);
|
|
return new Types_1.EmotionPoint(Types_1.RuleImpactValues.TICKLE_VALENCE, Types_1.RuleImpactValues.TICKLE_CONFIDENCE);
|
|
}
|
|
else {
|
|
log.error(`could not match touch input to emotion point`, input);
|
|
return new Types_1.EmotionPoint();
|
|
}
|
|
}
|
|
dispose() {
|
|
this.touchSensor.events.removeAllListeners();
|
|
}
|
|
}
|
|
exports.TouchRule = TouchRule;
|
|
|
|
},{"../../common/Types":13,"../../emotion/EmotionTrace":19,"../../log":25,"../../sensing/sensors/TouchSensor":35,"./AppraisalRule":6}],12:[function(require,module,exports){
|
|
"use strict";
|
|
function __export(m) {
|
|
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
|
}
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
__export(require("./MimRule"));
|
|
__export(require("./ASRTextInputRule"));
|
|
__export(require("./AppraisalRule"));
|
|
__export(require("./TouchRule"));
|
|
__export(require("./ExternalImpactRule"));
|
|
__export(require("./MotorFaultRule"));
|
|
__export(require("./IdentityRule"));
|
|
|
|
},{"./ASRTextInputRule":5,"./AppraisalRule":6,"./ExternalImpactRule":7,"./IdentityRule":8,"./MimRule":9,"./MotorFaultRule":10,"./TouchRule":11}],13:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const jibo_common_types_1 = require("jibo-common-types");
|
|
exports.EmotionName = jibo_common_types_1.EmotionName;
|
|
class EmotionPoint {
|
|
constructor(valence = 0, confidence = 0) {
|
|
this.valence = valence;
|
|
this.confidence = confidence;
|
|
}
|
|
}
|
|
exports.EmotionPoint = EmotionPoint;
|
|
var ImpactSize;
|
|
(function (ImpactSize) {
|
|
ImpactSize["NONE"] = "NONE";
|
|
ImpactSize["LOW_POS"] = "LOW_POS";
|
|
ImpactSize["MEDIUM_POS"] = "MEDIUM_POS";
|
|
ImpactSize["HIGH_POS"] = "HIGH_POS";
|
|
ImpactSize["LOW_NEG"] = "LOW_NEG";
|
|
ImpactSize["MEDIUM_NEG"] = "MEDIUM_NEG";
|
|
ImpactSize["HIGH_NEG"] = "HIGH_NEG";
|
|
})(ImpactSize = exports.ImpactSize || (exports.ImpactSize = {}));
|
|
var RuleNames;
|
|
(function (RuleNames) {
|
|
RuleNames["ASRTextInputRule"] = "ASRTextInputRule";
|
|
RuleNames["TouchRule"] = "TouchRule";
|
|
RuleNames["SkillInputRule"] = "SkillInputRule";
|
|
RuleNames["MotorFaultRule"] = "MotorFaultRule";
|
|
RuleNames["MimRule"] = "MimRule";
|
|
RuleNames["IdentityRule"] = "IdentityRule";
|
|
})(RuleNames = exports.RuleNames || (exports.RuleNames = {}));
|
|
var TouchTypes;
|
|
(function (TouchTypes) {
|
|
TouchTypes["HEAD_LEFT"] = "HEAD_LEFT";
|
|
TouchTypes["HEAD_RIGHT"] = "HEAD_RIGHT";
|
|
TouchTypes["TICKLE"] = "TICKLE";
|
|
})(TouchTypes = exports.TouchTypes || (exports.TouchTypes = {}));
|
|
var IdentityEvents;
|
|
(function (IdentityEvents) {
|
|
IdentityEvents["PRESENCE_STARTED"] = "PRESENCE_STARTED";
|
|
IdentityEvents["VISIBLE_FACE_STARTED"] = "VISIBLE_FACE_STARTED";
|
|
IdentityEvents["ID_ACQUIRED"] = "ID_ACQUIRED";
|
|
})(IdentityEvents = exports.IdentityEvents || (exports.IdentityEvents = {}));
|
|
var RuleImpactValues;
|
|
(function (RuleImpactValues) {
|
|
RuleImpactValues[RuleImpactValues["PRESENCE_STARTED_VALENCE"] = 0.01] = "PRESENCE_STARTED_VALENCE";
|
|
RuleImpactValues[RuleImpactValues["PRESENCE_STARTED_CONFIDENCE"] = 0.01] = "PRESENCE_STARTED_CONFIDENCE";
|
|
RuleImpactValues[RuleImpactValues["VISIBLE_FACE_STARTED_VALENCE"] = 0.01] = "VISIBLE_FACE_STARTED_VALENCE";
|
|
RuleImpactValues[RuleImpactValues["VISIBLE_FACE_STARTED_CONFIDENCE"] = 0.01] = "VISIBLE_FACE_STARTED_CONFIDENCE";
|
|
RuleImpactValues[RuleImpactValues["ID_ACQUIRED_VALENCE"] = 0.01] = "ID_ACQUIRED_VALENCE";
|
|
RuleImpactValues[RuleImpactValues["ID_ACQUIRED_CONFIDENCE"] = 0.01] = "ID_ACQUIRED_CONFIDENCE";
|
|
RuleImpactValues[RuleImpactValues["HEAD_TOUCH_VALENCE"] = 0.2] = "HEAD_TOUCH_VALENCE";
|
|
RuleImpactValues[RuleImpactValues["HEAD_TOUCH_CONFIDENCE"] = 0.1] = "HEAD_TOUCH_CONFIDENCE";
|
|
RuleImpactValues[RuleImpactValues["TICKLE_VALENCE"] = 1] = "TICKLE_VALENCE";
|
|
RuleImpactValues[RuleImpactValues["TICKLE_CONFIDENCE"] = 1] = "TICKLE_CONFIDENCE";
|
|
RuleImpactValues[RuleImpactValues["MOTOR_FAULT_VALENCE"] = -2] = "MOTOR_FAULT_VALENCE";
|
|
RuleImpactValues[RuleImpactValues["MOTOR_FAULT_CONFIDENCE"] = -2] = "MOTOR_FAULT_CONFIDENCE";
|
|
RuleImpactValues[RuleImpactValues["MIM_ERROR_VALENCE"] = 0] = "MIM_ERROR_VALENCE";
|
|
RuleImpactValues[RuleImpactValues["MIM_ERROR_CONFIDENCE"] = -1] = "MIM_ERROR_CONFIDENCE";
|
|
})(RuleImpactValues = exports.RuleImpactValues || (exports.RuleImpactValues = {}));
|
|
|
|
},{"jibo-common-types":undefined}],14:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
class Utils {
|
|
static limitToRange(value, min, max) {
|
|
if (value > max) {
|
|
value = max;
|
|
}
|
|
if (value < min) {
|
|
value = min;
|
|
}
|
|
return value;
|
|
}
|
|
static getEuclideanDistance(a, b, properties) {
|
|
let sumOfSquares = 0;
|
|
properties.forEach((propName) => {
|
|
if (typeof a[propName] !== 'number' ||
|
|
typeof b[propName] !== 'number') {
|
|
throw new TypeError(`Expected ${propName} to be a number.`);
|
|
}
|
|
sumOfSquares += Math.pow(a[propName] - b[propName], 2);
|
|
});
|
|
return Math.sqrt(sumOfSquares);
|
|
}
|
|
}
|
|
exports.Utils = Utils;
|
|
|
|
},{}],15:[function(require,module,exports){
|
|
"use strict";
|
|
function __export(m) {
|
|
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
|
}
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
__export(require("./Types"));
|
|
__export(require("./Utils"));
|
|
|
|
},{"./Types":13,"./Utils":14}],16:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const Utils_1 = require("../common/Utils");
|
|
const Types_1 = require("../common/Types");
|
|
class Emotion {
|
|
constructor(name, valence = 0, confidence = 0) {
|
|
this.name = name;
|
|
this.values = new Types_1.EmotionPoint(valence, confidence);
|
|
}
|
|
get emotionValues() {
|
|
return this.values;
|
|
}
|
|
set emotionValues(values) {
|
|
this.values.valence = Utils_1.Utils.limitToRange(values.valence, -1, 1);
|
|
this.values.confidence = Utils_1.Utils.limitToRange(values.confidence, -1, 1);
|
|
}
|
|
}
|
|
exports.Emotion = Emotion;
|
|
|
|
},{"../common/Types":13,"../common/Utils":14}],17:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const Types_1 = require("../common/Types");
|
|
const Emotion_1 = require("./Emotion");
|
|
exports.JIBO_BASELINE = new Emotion_1.Emotion(Types_1.EmotionName.BASELINE, 0.45, 0.2);
|
|
exports.EMOTION_DECAY_RATE = 10;
|
|
exports.ImpactValues = new Map();
|
|
exports.ImpactValues.set(Types_1.ImpactSize.NONE, 0);
|
|
exports.ImpactValues.set(Types_1.ImpactSize.LOW_POS, 0.5);
|
|
exports.ImpactValues.set(Types_1.ImpactSize.MEDIUM_POS, 1);
|
|
exports.ImpactValues.set(Types_1.ImpactSize.HIGH_POS, 2);
|
|
exports.ImpactValues.set(Types_1.ImpactSize.LOW_NEG, -0.5);
|
|
exports.ImpactValues.set(Types_1.ImpactSize.MEDIUM_NEG, -1);
|
|
exports.ImpactValues.set(Types_1.ImpactSize.HIGH_NEG, -2);
|
|
exports.AppraisalEvents = {
|
|
IMPACT_TRIGGERED: 'IMPACT_TRIGGERED',
|
|
};
|
|
exports.DEFAULT_EMOTIONS = new Map();
|
|
exports.DEFAULT_EMOTIONS.set(Types_1.EmotionName.NEUTRAL, { valence: 0, confidence: 0 });
|
|
exports.DEFAULT_EMOTIONS.set(Types_1.EmotionName.CONFIDENT, { valence: 0, confidence: 1 });
|
|
exports.DEFAULT_EMOTIONS.set(Types_1.EmotionName.INSECURE, { valence: 0, confidence: -1 });
|
|
exports.DEFAULT_EMOTIONS.set(Types_1.EmotionName.PLEASED, { valence: 1, confidence: 0 });
|
|
exports.DEFAULT_EMOTIONS.set(Types_1.EmotionName.JOYFUL, { valence: 1, confidence: 1 });
|
|
exports.DEFAULT_EMOTIONS.set(Types_1.EmotionName.DETERMINED, { valence: 1, confidence: -1 });
|
|
exports.DEFAULT_EMOTIONS.set(Types_1.EmotionName.SAD, { valence: -1, confidence: 0 });
|
|
exports.DEFAULT_EMOTIONS.set(Types_1.EmotionName.HOPEFUL, { valence: -1, confidence: 1 });
|
|
exports.DEFAULT_EMOTIONS.set(Types_1.EmotionName.FRUSTRATED, { valence: -1, confidence: -1 });
|
|
exports.EMOTION_TO_ANIM_CATEGORY = new Map();
|
|
exports.EMOTION_TO_ANIM_CATEGORY.set(Types_1.EmotionName.PLEASED, 'happy');
|
|
exports.EMOTION_TO_ANIM_CATEGORY.set(Types_1.EmotionName.SAD, 'sad');
|
|
exports.EMOTION_TO_ANIM_CATEGORY.set(Types_1.EmotionName.NEUTRAL, 'politereply');
|
|
exports.EMOTION_TO_ANIM_CATEGORY.set(Types_1.EmotionName.CONFIDENT, 'proud');
|
|
exports.EMOTION_TO_ANIM_CATEGORY.set(Types_1.EmotionName.UNCERTAIN, 'confused');
|
|
exports.EMOTION_TO_ANIM_CATEGORY.set(Types_1.EmotionName.INSECURE, 'confused');
|
|
exports.EMOTION_TO_ANIM_CATEGORY.set(Types_1.EmotionName.PESSIMISTIC, 'disgusted');
|
|
exports.EMOTION_TO_ANIM_CATEGORY.set(Types_1.EmotionName.HOPEFUL, 'disgusted');
|
|
exports.EMOTION_TO_ANIM_CATEGORY.set(Types_1.EmotionName.FRUSTRATED, 'frustrated');
|
|
exports.EMOTION_TO_ANIM_CATEGORY.set(Types_1.EmotionName.DETERMINED, 'curious');
|
|
exports.EMOTION_TO_ANIM_CATEGORY.set(Types_1.EmotionName.JOYFUL, 'laughing');
|
|
|
|
},{"../common/Types":13,"./Emotion":16}],18:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const EmotionTrace_1 = require("../emotion/EmotionTrace");
|
|
const jibo_typed_events_1 = require("jibo-typed-events");
|
|
const Utils_1 = require("../common/Utils");
|
|
const Types_1 = require("../common/Types");
|
|
const EmotionDefinitions_1 = require("./EmotionDefinitions");
|
|
const log_1 = require("../log");
|
|
const log = log_1.default.createChild('Space');
|
|
class EmotionSpaceEvents extends jibo_typed_events_1.EventContainer {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.changeEvent = new jibo_typed_events_1.Event('Emotion has changed.');
|
|
this.updated = new jibo_typed_events_1.Event('Emotion has changed.');
|
|
}
|
|
}
|
|
exports.EmotionSpaceEvents = EmotionSpaceEvents;
|
|
class EmotionSpace {
|
|
constructor(parent) {
|
|
this.parent = parent;
|
|
this.events = new EmotionSpaceEvents();
|
|
this._decayImpactPerHour = 10;
|
|
this._decayTimerId = null;
|
|
this.emotions = new Set();
|
|
this.currentEmotionPoint = new Types_1.EmotionPoint(EmotionDefinitions_1.JIBO_BASELINE.emotionValues.valence, EmotionDefinitions_1.JIBO_BASELINE.emotionValues.confidence);
|
|
this.lastEmotionPoint = new Types_1.EmotionPoint(EmotionDefinitions_1.JIBO_BASELINE.emotionValues.valence, EmotionDefinitions_1.JIBO_BASELINE.emotionValues.confidence);
|
|
this.setInterval = (callback, delay) => {
|
|
return this.parent.jibo.timer.setInterval(callback, delay);
|
|
};
|
|
this.clearInterval = (timerId) => {
|
|
this.parent.jibo.timer.clearInterval(timerId);
|
|
};
|
|
}
|
|
init(emotions) {
|
|
for (let i = 0; i < emotions.length; i++) {
|
|
this.emotions.add(emotions[i]);
|
|
}
|
|
this._startDecayToBaseline();
|
|
}
|
|
getNearestEmotion(referencePoint = this.currentEmotionPoint) {
|
|
let bestMatch = null;
|
|
let bestScore = Infinity;
|
|
this.emotions.forEach((emotion) => {
|
|
let currentScore = Utils_1.Utils.getEuclideanDistance(emotion.emotionValues, referencePoint, ['valence', 'confidence']);
|
|
if (currentScore < bestScore) {
|
|
bestMatch = emotion;
|
|
bestScore = currentScore;
|
|
}
|
|
});
|
|
return bestMatch;
|
|
}
|
|
getCurrentPosition() {
|
|
return this.currentEmotionPoint;
|
|
}
|
|
getLastTrace() {
|
|
return this.lastEmotionTrace;
|
|
}
|
|
dispose() {
|
|
this.events.removeAllListeners();
|
|
this.clearInterval(this._decayTimerId);
|
|
}
|
|
update(emotionTrace) {
|
|
let impact = emotionTrace.emotionalImpact;
|
|
this.currentEmotionPoint.valence += impact.valence;
|
|
this.currentEmotionPoint.confidence += impact.confidence;
|
|
emotionTrace.startingPosition = new Types_1.EmotionPoint(this.lastEmotionPoint.valence, this.lastEmotionPoint.confidence);
|
|
emotionTrace.newPosition = new Types_1.EmotionPoint(this.currentEmotionPoint.valence, this.currentEmotionPoint.confidence);
|
|
emotionTrace.nearestEmotionAfterImpact = this.getNearestEmotion(this.currentEmotionPoint);
|
|
const lastFeltEmotion = this.getNearestEmotion(this.lastEmotionPoint);
|
|
if (lastFeltEmotion.name !== emotionTrace.nearestEmotionAfterImpact.name) {
|
|
log.info(`jibo's emotion changed to ${emotionTrace.nearestEmotionAfterImpact.name}`);
|
|
this.events.changeEvent.emit(emotionTrace.nearestEmotionAfterImpact);
|
|
this.parent.jibo.analytics.track("Emotion Change", {
|
|
emotion_before: lastFeltEmotion.name,
|
|
emotion_after: emotionTrace.nearestEmotionAfterImpact.name,
|
|
valence: this.currentEmotionPoint.valence,
|
|
confidence: this.currentEmotionPoint.confidence,
|
|
emotion_combined: this.currentEmotionPoint.valence + this.currentEmotionPoint.confidence
|
|
});
|
|
}
|
|
this.lastEmotionPoint.valence = this.currentEmotionPoint.valence;
|
|
this.lastEmotionPoint.confidence = this.currentEmotionPoint.confidence;
|
|
this.lastEmotionTrace = emotionTrace;
|
|
this.events.updated.emit(emotionTrace);
|
|
}
|
|
_resetToNeutral() {
|
|
let valenceDiff = EmotionDefinitions_1.JIBO_BASELINE.emotionValues.valence - this.currentEmotionPoint.valence;
|
|
let confidenceDiff = EmotionDefinitions_1.JIBO_BASELINE.emotionValues.confidence - this.currentEmotionPoint.confidence;
|
|
let impact = new Types_1.EmotionPoint(valenceDiff, confidenceDiff);
|
|
const emotionTrace = new EmotionTrace_1.EmotionTrace(null, null, impact);
|
|
this.update(emotionTrace);
|
|
return emotionTrace;
|
|
}
|
|
_startDecayToBaseline() {
|
|
if (this._decayTimerId) {
|
|
this.clearInterval(this._decayTimerId);
|
|
}
|
|
let decayRate = this._decayImpactPerHour / (60);
|
|
this._decayTimerId = this.setInterval(() => {
|
|
const impactUpdatePoint = new Types_1.EmotionPoint();
|
|
const baselineValence = EmotionDefinitions_1.JIBO_BASELINE.emotionValues.valence;
|
|
const baselineConfidence = EmotionDefinitions_1.JIBO_BASELINE.emotionValues.confidence;
|
|
if (this.currentEmotionPoint.valence > baselineValence) {
|
|
if (this.currentEmotionPoint.valence - decayRate < baselineValence) {
|
|
impactUpdatePoint.valence = baselineValence - this.currentEmotionPoint.valence;
|
|
}
|
|
else {
|
|
impactUpdatePoint.valence = -decayRate;
|
|
}
|
|
}
|
|
else if (this.currentEmotionPoint.valence < baselineValence) {
|
|
if (this.currentEmotionPoint.valence + decayRate > baselineValence) {
|
|
impactUpdatePoint.valence = baselineValence - this.currentEmotionPoint.valence;
|
|
}
|
|
else {
|
|
impactUpdatePoint.valence = decayRate;
|
|
}
|
|
}
|
|
if (this.currentEmotionPoint.confidence > baselineConfidence) {
|
|
if (this.currentEmotionPoint.confidence - decayRate < baselineConfidence) {
|
|
impactUpdatePoint.confidence = baselineConfidence - this.currentEmotionPoint.confidence;
|
|
}
|
|
else {
|
|
impactUpdatePoint.confidence = -decayRate;
|
|
}
|
|
}
|
|
else if (this.currentEmotionPoint.confidence < baselineConfidence) {
|
|
if (this.currentEmotionPoint.confidence + decayRate > baselineConfidence) {
|
|
impactUpdatePoint.confidence = baselineConfidence - this.currentEmotionPoint.confidence;
|
|
}
|
|
else {
|
|
impactUpdatePoint.confidence = decayRate;
|
|
}
|
|
}
|
|
const updateTrace = new EmotionTrace_1.EmotionTrace(null, null, impactUpdatePoint);
|
|
this.update(updateTrace);
|
|
}, EmotionDefinitions_1.EMOTION_DECAY_RATE * 1000);
|
|
}
|
|
}
|
|
exports.EmotionSpace = EmotionSpace;
|
|
|
|
},{"../common/Types":13,"../common/Utils":14,"../emotion/EmotionTrace":19,"../log":25,"./EmotionDefinitions":17,"jibo-typed-events":undefined}],19:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
class EmotionTrace {
|
|
constructor(sensorDataWrappers, appraisalRule, emotionalImpact) {
|
|
this.sensorDataWrappers = sensorDataWrappers;
|
|
this.appraisalRule = appraisalRule;
|
|
this.emotionalImpact = emotionalImpact;
|
|
}
|
|
}
|
|
exports.EmotionTrace = EmotionTrace;
|
|
|
|
},{}],20:[function(require,module,exports){
|
|
"use strict";
|
|
function __export(m) {
|
|
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
|
}
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
__export(require("./Emotion"));
|
|
__export(require("./EmotionDefinitions"));
|
|
__export(require("./EmotionSpace"));
|
|
__export(require("./EmotionTrace"));
|
|
|
|
},{"./Emotion":16,"./EmotionDefinitions":17,"./EmotionSpace":18,"./EmotionTrace":19}],21:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const EmotionDefinitions_1 = require("../emotion/EmotionDefinitions");
|
|
const Types_1 = require("../common/Types");
|
|
const jibo_common_types_1 = require("jibo-common-types");
|
|
const log_1 = require("../log");
|
|
const log = log_1.default.createChild('Expression.Express');
|
|
class EmotionalExpression {
|
|
constructor(name, parent) {
|
|
this.name = name;
|
|
this.parent = parent;
|
|
}
|
|
run(emotion) {
|
|
const jibo = this.parent.jibo;
|
|
return new Promise((res, rej) => {
|
|
const animCategory = EmotionDefinitions_1.EMOTION_TO_ANIM_CATEGORY.get(Types_1.EmotionName[emotion.name]);
|
|
if (!animCategory) {
|
|
rej(`No animation category with corresponding emotion name ${emotion.name}`);
|
|
}
|
|
else {
|
|
const state = jibo.action.getState();
|
|
if (state.circadianState === jibo_common_types_1.CircadianState.ALERT ||
|
|
state.circadianState === jibo_common_types_1.CircadianState.RELAXED) {
|
|
const endTime = new Date(state.time.getTime());
|
|
endTime.setSeconds(endTime.getSeconds() + 10);
|
|
jibo.action.addPlayAnimationGoal({
|
|
category: animCategory,
|
|
criteria: {
|
|
endTime,
|
|
currentSkill: '@be/idle',
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
log.debug(`Not playing animation category '${animCategory}' because we are not awake`);
|
|
}
|
|
res();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
exports.EmotionalExpression = EmotionalExpression;
|
|
|
|
},{"../common/Types":13,"../emotion/EmotionDefinitions":17,"../log":25,"jibo-common-types":undefined}],22:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const Types_1 = require("../common/Types");
|
|
exports.TouchExpressions = new Map();
|
|
exports.TouchExpressions.set(Types_1.TouchTypes.HEAD_LEFT, {
|
|
name: Types_1.TouchTypes.HEAD_LEFT,
|
|
category: 'Touch',
|
|
includeMeta: ['rub-left']
|
|
});
|
|
exports.TouchExpressions.set(Types_1.TouchTypes.HEAD_RIGHT, {
|
|
name: Types_1.TouchTypes.HEAD_RIGHT,
|
|
category: 'Touch',
|
|
includeMeta: ['rub-right']
|
|
});
|
|
exports.TouchExpressions.set(Types_1.TouchTypes.TICKLE, {
|
|
name: Types_1.TouchTypes.TICKLE,
|
|
category: 'laughing',
|
|
includeMeta: []
|
|
});
|
|
|
|
},{"../common/Types":13}],23:[function(require,module,exports){
|
|
"use strict";
|
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const Types_1 = require("../common/Types");
|
|
const ExpressionMaps_1 = require("./ExpressionMaps");
|
|
const jibo_cai_utils_1 = require("jibo-cai-utils");
|
|
const log_1 = require("../log");
|
|
class ExpressionSystem {
|
|
constructor(parent) {
|
|
this.parent = parent;
|
|
this.log = log_1.default.createChild("ExpressionSystem");
|
|
this.emotionExpressions = new Map();
|
|
}
|
|
init(emotionExpressions) {
|
|
this.emotionExpressions = emotionExpressions;
|
|
this.cacheExpressionAnimations();
|
|
}
|
|
verifyExpressionsExist(emotionSpace) {
|
|
emotionSpace.emotions.forEach(e => {
|
|
let expression = this.emotionExpressions.get(e.name);
|
|
if (!expression) {
|
|
throw new Error(`No Expression defined for emotion: "${e.name}"`);
|
|
}
|
|
});
|
|
}
|
|
trackSnuggle(emotionTrace) {
|
|
const emotionBeforeUpdate = this.parent.getNearestEmotion(emotionTrace.startingPosition).name;
|
|
if (emotionTrace.appraisalRule && emotionTrace.appraisalRule.name === Types_1.RuleNames.TouchRule) {
|
|
const touchData = emotionTrace.sensorDataWrappers[0].sensorData;
|
|
let snuggleType;
|
|
if (touchData.type === Types_1.TouchTypes.HEAD_LEFT || touchData.type === Types_1.TouchTypes.HEAD_RIGHT) {
|
|
snuggleType = "Head Pat";
|
|
}
|
|
else if (touchData.type === Types_1.TouchTypes.TICKLE) {
|
|
snuggleType = "Tickle";
|
|
}
|
|
if (snuggleType) {
|
|
this.parent.jibo.analytics.track("Snuggle Occurred", { type: snuggleType });
|
|
}
|
|
}
|
|
else if (emotionBeforeUpdate !== this.parent.getNearestEmotion().name) {
|
|
}
|
|
}
|
|
expressEmotion(emotion) {
|
|
let expression = this.emotionExpressions.get(emotion.name);
|
|
if (!expression) {
|
|
throw new Error(`No Expression defined for emotion ${emotion.name}.`);
|
|
}
|
|
return expression.run(emotion);
|
|
}
|
|
dispose() {
|
|
this.emotionExpressions.clear();
|
|
}
|
|
cacheExpressionAnimations() {
|
|
this.parent.jibo.timer.once('update', () => {
|
|
this.log.debug('Caching head touch animations.');
|
|
const rubLeft = {
|
|
category: ExpressionMaps_1.TouchExpressions.get(Types_1.TouchTypes.HEAD_LEFT).category,
|
|
includeMeta: ExpressionMaps_1.TouchExpressions.get(Types_1.TouchTypes.HEAD_LEFT).includeMeta
|
|
};
|
|
const rubRight = {
|
|
category: ExpressionMaps_1.TouchExpressions.get(Types_1.TouchTypes.HEAD_RIGHT).category,
|
|
includeMeta: ExpressionMaps_1.TouchExpressions.get(Types_1.TouchTypes.HEAD_RIGHT).includeMeta
|
|
};
|
|
const tickle = {
|
|
category: ExpressionMaps_1.TouchExpressions.get(Types_1.TouchTypes.TICKLE).category,
|
|
};
|
|
let assets = [];
|
|
[rubLeft, rubRight, tickle].forEach(query => {
|
|
const results = this.parent.jibo.animDB.query(query);
|
|
if (!results.matching.length) {
|
|
this.log.warn(`No animation of ${query} found in animDB`);
|
|
}
|
|
else {
|
|
assets.push(...results.matching);
|
|
}
|
|
});
|
|
assets.forEach((asset) => __awaiter(this, void 0, void 0, function* () {
|
|
try {
|
|
yield asset.createFromConfig({
|
|
cache: jibo_cai_utils_1.CacheUtils.GlobalCacheName
|
|
});
|
|
}
|
|
catch (_a) {
|
|
this.log.warn(`Unable to load animations from query ${JSON.stringify(asset.name)} into cache ${jibo_cai_utils_1.CacheUtils.GlobalCacheName}`);
|
|
}
|
|
}));
|
|
});
|
|
}
|
|
}
|
|
exports.ExpressionSystem = ExpressionSystem;
|
|
|
|
},{"../common/Types":13,"../log":25,"./ExpressionMaps":22,"jibo-cai-utils":undefined}],24:[function(require,module,exports){
|
|
"use strict";
|
|
function __export(m) {
|
|
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
|
}
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
__export(require("./ExpressionSystem"));
|
|
__export(require("./EmotionalExpression"));
|
|
|
|
},{"./EmotionalExpression":21,"./ExpressionSystem":23}],25:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const jibo_log_1 = require("jibo-log");
|
|
exports.default = new jibo_log_1.Log('Jibo.Emotion');
|
|
|
|
},{"jibo-log":undefined}],26:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const appraisal = require("./appraisal");
|
|
exports.appraisal = appraisal;
|
|
const emotion = require("./emotion");
|
|
exports.emotion = emotion;
|
|
const sensing = require("./sensing");
|
|
exports.sensing = sensing;
|
|
const expression = require("./expression");
|
|
exports.expression = expression;
|
|
const api = require("./api");
|
|
exports.api = api;
|
|
const emotionSystem = require("./EmotionSystem");
|
|
exports.emotionSystem = emotionSystem;
|
|
const common = require("./common");
|
|
exports.common = common;
|
|
|
|
},{"./EmotionSystem":1,"./api":2,"./appraisal":4,"./common":15,"./emotion":20,"./expression":24,"./sensing":28}],27:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const log_1 = require("../log");
|
|
const log = log_1.default.createChild('SensorySystem');
|
|
class SensorySystem {
|
|
constructor(parent) {
|
|
this.sensorMap = new Map();
|
|
return;
|
|
}
|
|
init(sensors) {
|
|
sensors.forEach(sensor => {
|
|
log.debug("initting sensor", sensor.name);
|
|
sensor.init();
|
|
this.sensorMap.set(sensor.name, sensor);
|
|
});
|
|
}
|
|
getSensor(name) {
|
|
return this.sensorMap.get(name);
|
|
}
|
|
dispose() {
|
|
this.sensorMap.forEach((sensor) => {
|
|
sensor.dispose();
|
|
});
|
|
this.sensorMap.clear();
|
|
}
|
|
}
|
|
exports.SensorySystem = SensorySystem;
|
|
|
|
},{"../log":25}],28:[function(require,module,exports){
|
|
"use strict";
|
|
function __export(m) {
|
|
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
|
}
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
__export(require("./SensorySystem"));
|
|
const sensors = require("./sensors");
|
|
exports.sensors = sensors;
|
|
|
|
},{"./SensorySystem":27,"./sensors":36}],29:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const Sensor_1 = require("./Sensor");
|
|
class ASRInputSensor extends Sensor_1.Sensor {
|
|
constructor(parent) {
|
|
super(ASRInputSensor.SENSOR_NAME, true, parent);
|
|
}
|
|
init() {
|
|
super.init();
|
|
this.onCloudReceived = ((cloud) => {
|
|
if (cloud.status === this.parent.jibo.jetstream.types.TurnResultType.SUCCEEDED) {
|
|
this.supplyData(cloud.result.asr.text);
|
|
}
|
|
});
|
|
this.parent.jibo.jetstream.events.globalTurnResult.on(this.onCloudReceived);
|
|
this.parent.jibo.jetstream.events.localTurnResult.on(this.onCloudReceived);
|
|
}
|
|
dispose() {
|
|
super.dispose();
|
|
this.parent.jibo.jetstream.events.globalTurnResult.off(this.onCloudReceived);
|
|
this.parent.jibo.jetstream.events.localTurnResult.off(this.onCloudReceived);
|
|
}
|
|
}
|
|
ASRInputSensor.SENSOR_NAME = 'ASRInputSensor';
|
|
exports.ASRInputSensor = ASRInputSensor;
|
|
|
|
},{"./Sensor":34}],30:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const Sensor_1 = require("./Sensor");
|
|
class ExternalImpactSensor extends Sensor_1.Sensor {
|
|
constructor(emotionSystem) {
|
|
super(ExternalImpactSensor.SENSOR_NAME, true, emotionSystem);
|
|
}
|
|
}
|
|
ExternalImpactSensor.SENSOR_NAME = 'ExternalImpactSensor';
|
|
exports.ExternalImpactSensor = ExternalImpactSensor;
|
|
|
|
},{"./Sensor":34}],31:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const Sensor_1 = require("./Sensor");
|
|
const Types_1 = require("../../common/Types");
|
|
class IdentitySensor extends Sensor_1.Sensor {
|
|
constructor(parent) {
|
|
super(IdentitySensor.SENSOR_NAME, true, parent);
|
|
}
|
|
init() {
|
|
super.init();
|
|
this.presenceStartedHandler = () => {
|
|
this.supplyData(Types_1.IdentityEvents.PRESENCE_STARTED);
|
|
};
|
|
this.visibleFaceStartedHandler = () => {
|
|
this.supplyData(Types_1.IdentityEvents.VISIBLE_FACE_STARTED);
|
|
};
|
|
this.idAcquiredHandler = () => {
|
|
this.supplyData(Types_1.IdentityEvents.ID_ACQUIRED);
|
|
};
|
|
this.parent.jibo.lps.identity.events.presenceStarted.on(this.presenceStartedHandler);
|
|
this.parent.jibo.lps.identity.events.visibleFaceStarted.on(this.visibleFaceStartedHandler);
|
|
this.parent.jibo.lps.identity.events.idAcquired.on(this.idAcquiredHandler);
|
|
}
|
|
dispose() {
|
|
super.dispose();
|
|
this.parent.jibo.lps.identity.events.presenceStarted.removeListener(this.presenceStartedHandler);
|
|
this.parent.jibo.lps.identity.events.visibleFaceStarted.removeListener(this.visibleFaceStartedHandler);
|
|
this.parent.jibo.lps.identity.events.idAcquired.removeListener(this.idAcquiredHandler);
|
|
}
|
|
}
|
|
IdentitySensor.SENSOR_NAME = 'IdentitySensor';
|
|
exports.IdentitySensor = IdentitySensor;
|
|
|
|
},{"../../common/Types":13,"./Sensor":34}],32:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const Sensor_1 = require("./Sensor");
|
|
class MimSensor extends Sensor_1.Sensor {
|
|
constructor(parent) {
|
|
super(MimSensor.SENSOR_NAME, true, parent);
|
|
}
|
|
init() {
|
|
super.init();
|
|
}
|
|
dispose() {
|
|
super.dispose();
|
|
}
|
|
}
|
|
MimSensor.SENSOR_NAME = 'MimSensor';
|
|
exports.MimSensor = MimSensor;
|
|
|
|
},{"./Sensor":34}],33:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const Sensor_1 = require("./Sensor");
|
|
class MotorFaultEvent {
|
|
constructor(type = 'neck') {
|
|
this.timestamp = Date.now();
|
|
this.type = type;
|
|
}
|
|
}
|
|
exports.MotorFaultEvent = MotorFaultEvent;
|
|
class MotorFaultSensor extends Sensor_1.Sensor {
|
|
constructor(parent) {
|
|
super(MotorFaultSensor.SENSOR_NAME, true, parent);
|
|
this.readyForFault = true;
|
|
}
|
|
init() {
|
|
super.init();
|
|
this.faultListenerOn = (data) => {
|
|
if (this.readyForFault) {
|
|
this.readyForFault = false;
|
|
this.supplyData(new MotorFaultEvent('neck'));
|
|
}
|
|
};
|
|
this.faultListenerOff = () => {
|
|
this.readyForFault = true;
|
|
};
|
|
}
|
|
dispose() {
|
|
super.dispose();
|
|
}
|
|
}
|
|
MotorFaultSensor.SENSOR_NAME = 'MotorFaultSensor';
|
|
exports.MotorFaultSensor = MotorFaultSensor;
|
|
|
|
},{"./Sensor":34}],34:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const jibo_typed_events_1 = require("jibo-typed-events");
|
|
class SensorDataWrapper {
|
|
constructor(sensorName, sensorData) {
|
|
this.sensorName = sensorName;
|
|
this.sensorData = sensorData;
|
|
}
|
|
}
|
|
exports.SensorDataWrapper = SensorDataWrapper;
|
|
class SensorEventContainer extends jibo_typed_events_1.EventContainer {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.newDataEvent = new jibo_typed_events_1.Event('New Data Event from Sensor.');
|
|
}
|
|
}
|
|
exports.SensorEventContainer = SensorEventContainer;
|
|
class Sensor {
|
|
constructor(name, emitNewDataEvent = false, parent) {
|
|
this.name = name;
|
|
this.emitNewDataEvent = emitNewDataEvent;
|
|
this.parent = parent;
|
|
this.events = new SensorEventContainer();
|
|
return;
|
|
}
|
|
getLastData() {
|
|
return this.lastData;
|
|
}
|
|
supplyData(data) {
|
|
this.lastData = data;
|
|
if (this.emitNewDataEvent) {
|
|
const sensorData = new SensorDataWrapper(this.name, data);
|
|
this.events.newDataEvent.emit(sensorData);
|
|
}
|
|
}
|
|
init() {
|
|
return;
|
|
}
|
|
dispose() {
|
|
this.events.removeAllListeners();
|
|
return;
|
|
}
|
|
}
|
|
exports.Sensor = Sensor;
|
|
|
|
},{"jibo-typed-events":undefined}],35:[function(require,module,exports){
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const Sensor_1 = require("./Sensor");
|
|
const Types_1 = require("../../common/Types");
|
|
const log_1 = require("../../log");
|
|
const ExpressionMaps_1 = require("../../expression/ExpressionMaps");
|
|
const log = log_1.default.createChild('Sensor.Touch');
|
|
class TouchEvent {
|
|
constructor(type = 'HeadTouch') {
|
|
this.timestamp = Date.now();
|
|
this.type = type;
|
|
}
|
|
}
|
|
exports.TouchEvent = TouchEvent;
|
|
class TouchSensor extends Sensor_1.Sensor {
|
|
constructor(parent) {
|
|
super(TouchSensor.SENSOR_NAME, true, parent);
|
|
}
|
|
init() {
|
|
super.init();
|
|
}
|
|
dispose() {
|
|
super.dispose();
|
|
if (this.parent.jibo.action.events) {
|
|
this.parent.jibo.action.events.headPat.removeListener(this.touchHandler);
|
|
}
|
|
}
|
|
reactToHeadTouch(pads = []) {
|
|
log.debug("sensing touch", pads);
|
|
let options = {
|
|
randomOrientation: false
|
|
};
|
|
const rightTouches = pads[3] || pads[4] || pads[5];
|
|
const leftTouches = pads[0] || pads[1] || pads[2];
|
|
if (rightTouches) {
|
|
options.type = Types_1.TouchTypes.HEAD_RIGHT;
|
|
}
|
|
else if (leftTouches) {
|
|
options.type = Types_1.TouchTypes.HEAD_LEFT;
|
|
}
|
|
if (pads[5] && !pads[0] && !pads[1] && !pads[2] && !pads[3] && !pads[4] && !pads[6]) {
|
|
options.type = Types_1.TouchTypes.TICKLE;
|
|
this.jiboWasTickled(options);
|
|
}
|
|
else {
|
|
this.jiboWasTouched(options);
|
|
}
|
|
if (options.type) {
|
|
let animationOptions = ExpressionMaps_1.TouchExpressions.get(options.type);
|
|
if (animationOptions) {
|
|
log.debug(`Got animation ${animationOptions.name} for head touch.`);
|
|
let query = {
|
|
category: animationOptions.category,
|
|
includeMeta: animationOptions.includeMeta
|
|
};
|
|
return query;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
jiboWasTouched(options) {
|
|
log.debug("jiboWasTouched", options);
|
|
this.supplyData(new TouchEvent(options.type));
|
|
}
|
|
jiboWasTickled(options) {
|
|
this.supplyData(new TouchEvent(options.type));
|
|
}
|
|
}
|
|
TouchSensor.SENSOR_NAME = 'TouchSensor';
|
|
exports.TouchSensor = TouchSensor;
|
|
|
|
},{"../../common/Types":13,"../../expression/ExpressionMaps":22,"../../log":25,"./Sensor":34}],36:[function(require,module,exports){
|
|
"use strict";
|
|
function __export(m) {
|
|
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
|
}
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
__export(require("./Sensor"));
|
|
__export(require("./ASRInputSensor"));
|
|
__export(require("./MimSensor"));
|
|
__export(require("./TouchSensor"));
|
|
__export(require("./ExternalImpactSensor"));
|
|
__export(require("./MotorFaultSensor"));
|
|
__export(require("./IdentitySensor"));
|
|
|
|
},{"./ASRInputSensor":29,"./ExternalImpactSensor":30,"./IdentitySensor":31,"./MimSensor":32,"./MotorFaultSensor":33,"./Sensor":34,"./TouchSensor":35}],37:[function(require,module,exports){
|
|
"use strict";
|
|
function __export(m) {
|
|
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
|
}
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
__export(require("./main"));
|
|
|
|
},{"./main":26}]},{},[37])(37)
|
|
});
|
|
|
|
//# sourceMappingURL=jibo-emotion-system.js.map
|