/// <summary> /// This event handler is called when the robot/user sends a start message /// The parameters can be set in the Skill Runner (or as json) and used in the skill if desired /// </summary> /// <param name="parameters"></param> public async void OnStart(object sender, IDictionary <string, object> parameters) { //TODO Put your code here and update the summary above int task_id = 0; _timeToTellJokes = true; try { //Get the audio and image lists for use in the skill _audioList = (await _misty.GetAudioListAsync())?.Data; _imageList = (await _misty.GetImageListAsync())?.Data; _misty.Wait(2000); task_id++; _misty.PlayAudio("Misty_Hi.wav", 80, null); _misty.Wait(2000); _misty.PlayAudio("Misty_I_am_Annie.wav", 80, null); _misty.Wait(4000); _misty.ChangeLED(255, 255, 255, null); _misty.DisplayImage("e_DefaultContent.jpg", 1, null); _misty.MoveHead(10, 0, 0, 60, AngularUnit.Degrees, null); task_id++; _misty.RegisterAudioPlayCompleteEvent(AudioPlayCallback, 0, true, null, null); // Temporarily disable this voice recognition of the keyphrase wake up words due to SDK software issue. // It will be used the the fix is done. // The skill will be initiated by the skill sequencer. // _misty.StartKeyPhraseRecognition(null); // _misty.RegisterKeyPhraseRecognizedEvent(10, false, "KeyPhrase", null); // _misty.KeyPhraseRecognizedEventReceived += ProcessKeyPhraseEvent; _misty.StartFaceRecognition(null); RegisterEvents(); task_id++; _heartbeatTimer = new Timer(HeartbeatCallback, null, 5000, 3000); _moveHeadTimer = new Timer(MoveHeadCallback, null, 5000, 7000); _moveArmsTimer = new Timer(MoveArmCallback, null, 5000, 4000); _ledTimer = new Timer(ChangeLEDCallback, null, 1000, 1000); } catch (Exception ex) { if (task_id == 0) { _misty.SkillLogger.LogVerbose($"TellingJokeSkill : Failed to Load audio and image files"); } else if (task_id == 1) { _misty.SkillLogger.LogVerbose($"TellingJokeSkill : Failed to play audio and display image files"); } else if (task_id == 2) { _misty.SkillLogger.LogVerbose($"TellingJokeSkill : Failed to register events"); } else { _misty.SkillLogger.LogVerbose($"TellingJokeSkill : Failed to setup timers"); } _misty.SkillLogger.Log($"TellingJokeSkill : OnStart: => Exception", ex); } }
/// <summary> /// Called when the robot wants to start this skill /// </summary> /// <param name="parameters"></param> public void OnStart(object sender, IDictionary <string, object> parameters) { try { //These calls assume system assets on the robot at the time of writing. //Update as needed for new or different assets or as an exercise to allow user to pass in asset names :) _misty.PlayAudio("s_Acceptance.wav", 100, null); _misty.MoveHead(45, 25, 0, 50, AngularUnit.Degrees, null); _misty.MoveArms(0, 45, 25, 60, null, AngularUnit.Degrees, null); _misty.ChangeLED(0, 255, 0, null); _misty.DisplayImage("e_Disoriented.jpg", 1, null); //Pause for 4 seconds, if the cancellation token is set during this time, exit the pause and the method if (!_misty.Wait(4000)) { return; } _misty.PlayAudio("s_Awe2.wav", 100, null); _misty.MoveHead(75, 15, 30, 50, AngularUnit.Degrees, null); _misty.MoveArms(-45, 0, 60, 100, null, AngularUnit.Degrees, null); _misty.ChangeLED(0, 255, 255, null); _misty.DisplayImage("e_ContentRight.jpg", 1, null); //Pause for 3.5 seconds, if the cancellation token is set during this time, exit the pause and the method if (!_misty.Wait(3500)) { return; } _misty.PlayAudio("s_Joy.wav", 100, null); _misty.MoveHead(75, 25, 10, 50, AngularUnit.Degrees, null); _misty.MoveArms(-45, 45, 60, 100, null, AngularUnit.Degrees, null); _misty.ChangeLED(255, 255, 255, null); _misty.DisplayImage("e_ContentLeft.jpg", 1, null); //Pause for 2.5 seconds, if the cancellation token is set during this time, exit the pause and the method if (!_misty.Wait(2500)) { return; } _misty.PlayAudio("s_PhraseHello.wav", 100, null); _misty.MoveHead(-10, 0, -10, 50, AngularUnit.Degrees, null); _misty.MoveArms(0, -45, 60, 100, null, AngularUnit.Degrees, null); _misty.ChangeLED(0, 0, 255, null); _misty.DisplayImage("e_Joy.jpg", 1, null); //Tell the robot the skill has completed early _misty.SkillCompleted(); } catch (Exception ex) { _misty.SkillLogger.Log($"HelloWorldSkill : OnStart: => Exception", ex); } }
public async Task MoveHeadAsync(double pitchDegrees, double rollDegrees, double yawDegrees) { _misty.RegisterActuatorEvent(ActuatorEventCallback, 0, true, null, "SkillHelperActuatorEventCallback", OnResponse); // We move head to non-final position first so that we can verify change in position. double firstPitchDegrees = pitchDegrees + 10; if (pitchDegrees > 0) { firstPitchDegrees = pitchDegrees - 10; } _misty.MoveHead(firstPitchDegrees, rollDegrees, yawDegrees, 70, MistyRobotics.Common.Types.AngularUnit.Degrees, OnResponse); await Task.Delay(3000); _headPosition = new HeadPosition(); _headPositionSemaphore = new SemaphoreSlim(0); await _headPositionSemaphore.WaitAsync(5000); double initPitch = _headPosition.Pitch.HasValue ? _headPosition.Pitch.Value : 100; LogMessage($"Head position after pre-move: {_headPosition.Pitch:f2}, {_headPosition.Roll:f2}, {_headPosition.Yaw:f2}."); // Now move head to final position. _headPosition = new HeadPosition(); int retries = 0; while ((!_headPosition.Pitch.HasValue || (_headPosition.Pitch.HasValue && initPitch != 100 && Math.Abs(_headPosition.Pitch.Value - initPitch) < 2)) && retries++ < 3) { _misty.MoveHead(pitchDegrees, rollDegrees, yawDegrees, 70, MistyRobotics.Common.Types.AngularUnit.Degrees, OnResponse); await Task.Delay(5000); if (_abort) { break; } _headPositionSemaphore = new SemaphoreSlim(0); await _headPositionSemaphore.WaitAsync(5000); LogMessage($"Head position after move: {_headPosition.Pitch:f2}, {_headPosition.Roll:f2}, {_headPosition.Yaw:f2}."); } _misty.UnregisterEvent("SkillHelperActuatorEventCallback", OnResponse); }
/// <summary> /// This event handler is called when the robot/user sends a start message /// The parameters can be set in the Skill Runner (or as json) and used in the skill if desired /// </summary> /// <param name="parameters"></param> public void OnStart(object sender, IDictionary <string, object> parameters) { try { _misty.SendDebugMessage("MistyMiner skill started", null); _misty.MoveHead(20, 0, 0, 0, AngularUnit.Position, null); //_takeImageTimer = new Timer(CheckForOreCallback, null, 0, 5000); _misty.RegisterCapTouchEvent(CheckForOreCallback, 1000, true, null, null, null); _misty.RegisterIMUEvent(setYaw, 5, true, null, null, null); List <ActuatorPositionValidation> HeadPositionValidation = new List <ActuatorPositionValidation>(); HeadPositionValidation.Add(new ActuatorPositionValidation { Name = ActuatorPositionFilter.SensorName, Comparison = ComparisonOperator.Equal, ComparisonValue = ActuatorPosition.HeadPitch }); _misty.RegisterActuatorEvent(setHeadPitch, 10, true, HeadPositionValidation, null, null); List <ActuatorPositionValidation> ArmPositionValidation = new List <ActuatorPositionValidation>(); ArmPositionValidation.Add(new ActuatorPositionValidation { Name = ActuatorPositionFilter.SensorName, Comparison = ComparisonOperator.Equal, ComparisonValue = ActuatorPosition.RightArm }); _misty.RegisterActuatorEvent(setArmPitch, 100, true, ArmPositionValidation, null, null); _misty.RegisterTimeOfFlightEvent(setTimeOfFlight, 0, true, null, null, null); //Clean up any lingering runs yaw.YawReached -= HandleYawReached; yaw.YawReached -= HandleReturnYawReached; yaw.YawReached -= FinalYaw; tof.DistanceReached -= HandleOreReached; tof.DistanceReached -= HandleReturnReached; arm.ArmPosReached -= ArmDown; arm.ArmPosReached -= ArmUp; } catch (Exception ex) { _misty.SkillLogger.Log($"MistyMiner : OnStart: => Exception", ex); _misty.SendDebugMessage($"MistyMiner : OnStart: => Exception" + ex, null); } }
/// <summary> /// Move head with retries if pitch isn't where we want it to be. /// </summary> public async Task MoveHeadAsync(double pitchDegrees, double rollDegrees, double yawDegrees) { _misty.RegisterActuatorEvent(ActuatorEventCallback, 0, true, null, "SkillHelperActuatorEventCallback", OnResponse); LogMessage($"Move head: {pitchDegrees:f0}, {rollDegrees:f0}, {yawDegrees:f0}."); _headPosition = new HeadPosition(); int retries = 0; while ((!_headPosition.Pitch.HasValue || Math.Abs(_headPosition.Pitch.Value - pitchDegrees) > 3) && retries++ < 3) { _misty.MoveHead(pitchDegrees, rollDegrees, yawDegrees, 70, MistyRobotics.Common.Types.AngularUnit.Degrees, OnResponse); await Task.Delay(3000); // totally arbitrary wait if (_abort) { break; } } LogMessage($"Head position after move: {_headPosition.Pitch:f0}, {_headPosition.Roll:f0}, {_headPosition.Yaw:f0}."); _misty.UnregisterEvent("SkillHelperActuatorEventCallback", OnResponse); }
private void MoveHeadCallback(object info) { _misty.MoveHead(_randomGenerator.Next(-30, 15), _randomGenerator.Next(-30, 30), _randomGenerator.Next(-70, 70), _randomGenerator.Next(10, 30), AngularUnit.Degrees, null); }
private void ProcessQueryResult(object sender, string stringResult) { JObject dynamicResponse = JObject.Parse(stringResult); string color = ((string)dynamicResponse["queryResult"]?["parameters"]?["Color"])?.ToLower(); string position = ((string)dynamicResponse["queryResult"]?["parameters"]?["Direction"])?.ToLower(); string outputAudioString = (string)dynamicResponse["outputAudio"]; byte[] outputAudio = Convert.FromBase64String(outputAudioString); try { JsonConverter[] converters = new JsonConverter[2] { new ProtoByteStringConverter(), new OutputAudioEncodingConverter() }; DetectIntentResponse response = JsonConvert.DeserializeObject <DetectIntentResponse>(stringResult, converters); string intent = response?.QueryResult?.Intent?.DisplayName; string defaultResponse = response?.QueryResult?.FulfillmentText; switch (intent) { case "ChangeLED": if (color != null) { Color argbColor = Color.FromName(color); _misty.ChangeLED(argbColor.R, argbColor.G, argbColor.B, null); } break; case "Joke": _misty.PlayAudio(defaultResponse, 30, null); break; case "Move your arms": if (position == "up") { _misty.MoveArms(-90, -90, 50, 50, null, AngularUnit.Degrees, null); } if (position == "down") { _misty.MoveArms(90, 90, 50, 50, null, AngularUnit.Degrees, null); } _misty.Halt(null, null); break; case "MoveHeadPosition": if (position == "up") { _misty.MoveHead(-100, 0, 0, 50, AngularUnit.Degrees, null); } if (position == "down") { _misty.MoveHead(100, 0, 0, 50, AngularUnit.Degrees, null); } if (position == "right") { _misty.MoveHead(0, 0, -100, 50, AngularUnit.Degrees, null); } if (position == "left") { _misty.MoveHead(0, 0, 100, 50, AngularUnit.Degrees, null); } break; default: _misty.SaveAudio("tts.wav", outputAudio, true, true, null); break; } } catch (Exception ex) { } }
public void MoveHeadCallback(object timerData) { _misty.MoveHead(_randomGenerator.Next(MinimumPitchDegreesInclusive, MaximumPitchDegreesExclusive), _randomGenerator.Next(MinimumRollDegreesInclusive, MaximumRollDegreesExclusive), _randomGenerator.Next(MinimumYawDegreesInclusive, MaximumYawDegreesExclusive), _randomGenerator.Next(MinimumHeadSpeedInclusive, MaximumHeadSpeedExclusive), AngularUnit.Degrees, null); }