###Feature list:
動作播放(Motion)
觸碰(Touch)
馬達轉動(Motor)
控制臉(Control Face)
燈光控制(LED)
語音播放(TTS)
聲音辨識(in app localcommand)
語音轉文字(Speed2Text)
物件辨識(Recognize)
人臉追蹤(Face_track)
人臉辨識(Face_Recognize)
移動/旋轉(Movement)
Unity / Android版本
Unity version 2018.4.0 later android SDK Min version : 6.0
DemoScene使用
匯入NuwaPlugins的UnityPackage後,把NuwaUnity\Scene 資料夾下的所有Scene加入Build setting中,並把Demo_title放在首位即可。
How to use
在Editor中使用addComponent加入NuwaEventTrigger.cs後即可使用。目前無法在執行期間使用addComponent掛載。
動作播放(Motion)
在Demo_motion_play Scene中可以看到動作播放功能。
1.播放動作 - Nuwa要有對應的動作檔名才能正確撥放動作
Nuwa.motionPlay(string motion_name);
想要撥放指定路徑的motion的話可以使用
xxxxxxxxxx
Nuwa.motionPlay(string motion_name, bool fade = false, string motion_bin_path);
這樣想要撥放 "/storage/emulated/0/Download/assets/motion_bin/" 中的motion檔名的話
motion_bin_path 設定成 : "/storage/emulated/0/Download" 即可
2.停止播放動作
xxxxxxxxxx
Nuwa.motionStop();
3.暫停動作
xxxxxxxxxx
Nuwa.motionPause();
4.從暫停處重新撥放
xxxxxxxxxx
Nuwa.motionResume();
控制臉(Control Face)
關於應用程式控制臉的用法,可參考範例Demo_ContorlFace。開啟臉後,如果要離開應用程式,務必關閉臉跟調整臉的大小,否則會影響凱比表情的正常運作。
xxxxxxxxxx
Nuwa.ShowFace();
xxxxxxxxxx
Nuwa.HideFace();
xxxxxxxxxx
Nuwa.MouthOn();
xxxxxxxxxx
Nuwa.MouthOff();
xxxxxxxxxx
string motionID; //凱比的表情id
Nuwa.PlayMotion(motionId);
xxxxxxxxxx
int x,y; //分別為橫軸跟縱軸座標
int w,h; //分別為凱比的寬跟高,凱比臉的正常大小為1024x600
Nuwa.ChangeFace(x, y, w, h);
觸碰(Touch)
在Demo_touch Scene 可以看到對觸控的反應。
以下是TouchBegin,TouchEnd,Tap,LongPress的接收Event方式
xxxxxxxxxx
NuwaEventTrigger trigger = this.GetComponent<NuwaEventTrigger>();
if (trigger != null)
{
trigger.onTouchBegan.AddListener(OnTouchBegin);
trigger.onTouchEnd.AddListener(OnTouchEnd);
trigger.onTap.AddListener(OnTap);
trigger.onLongPress.AddListener(OnLongPress);
}
注意!在接收從Android端傳過來的Event時更新UI會出現Error(error狀況 : 無法在非Main Thread的狀況下更新Monobehavior的內容),要更新UI或是Transform的東西的話需要放在Update中處理。
馬達轉動(Motor)
在Demon_motor Scene 中可以看到控制指定馬達的轉動位置, 程式碼在MotorMain.cs中
1.取得指定目標的馬達角度
xxxxxxxxxx
Nuwa.getMotorPresentPossitionInDegree(Nuwa.NuwaMotorType.neck_y)
2.設定指定目標的馬達角度
xxxxxxxxxx
Nuwa.setMotorPositionInDegree((int)type, (int)motorRotateDegree, (int)motorSpeed);
燈光控制(LED)
在Demo_LED Scene中可以讓UnityApp控制機器人的LED。呼叫此功能,機器人上的LED都會被應用程式控制。
1.設定APP控制燈
xxxxxxxxxx
Nuwa.disableSystemLED();//關閉系統LED
Nuwa.enableLed(Nuwa.LEDPosition, bool);//開啟App的LED控制權
Nuwa.setLedColor(Nuwa.LEDPosition , Color);//設定部位的LED顏色
2.關閉設定自由控制燈
xxxxxxxxxx
Nuwa.enableLed(Nuwa.LEDPosition, false); // 關閉app的LED控制權
Nuwa.enableSystemLED(); //讓系統管理LED
3.讓燈有呼吸效果
xxxxxxxxxx
Nuwa.enableLedBreath(Nuwa.LEDPosition, int, int);
語音播放(TTS)
在Demo_tts Scene中可以使用字串來撥放TTS語音, 支援中、英文。
1.播放tts
xxxxxxxxxx
Nuwa.startTTS(string);
2.停止播放tts
xxxxxxxxxx
Nuwa.stopTTS(string);
3.暫停播放tts
xxxxxxxxxx
Nuwa.pauseTTS(string);
4.恢復播放tts
xxxxxxxxxx
Nuwa.resumeTTS(string);
5.設定TTs撥放時的的Speed,Pitch,
xxxxxxxxxx
# value need be int, between 1~9
Nuwa.SetSpeakParameter("speed", value.ToString());
Nuwa.SetSpeakParameter("pitch", value.ToString());
聲音辨識(speech recognition)
在Demo_LocalCommand Scene中。接收命令,判斷接收到的內容後再做處理。只支援中文。
1.設定Grammar需要的名稱跟值
xstrinExceptiong mi_Name; //grammer的名稱
string[] values; //要辨識的字串
/*
mi_Name = "robot";
values = new string[2] {"哈囉","你好"};
*/
Nuwa.prepareGrammarToRobot(mi_Name, values);
2.界接Event
xxxxxxxxxx
Nuwa.onGrammarState += OnGrammarState; //Grammar設定完
Nuwa.onLocalCommandComplete += TrueFunction; //聲音辨識成功
Nuwa.onLocalCommandException += FalseFunction; //聲音辨識例外
3.Grammar完成設定後,開始聲音辨識。
xxxxxxxxxx
void OnGrammarState(bool isError, string info)
{
Debug.Log(string.Format("OnGrammarState isError = {0} , info = {1}", isError, info));
//開始聲音辨識
Nuwa.startLocalCommand();
}
收到的Json格式如下,resoult為聽到的聲音字串。
xxxxxxxxxx
{
"result": "測試",
"x-trace-id": "ef73bd1252544f30a818b0f68a6a72c7",
"engine": "IFly local command",
"type": 1,
"class": "com.nuwarobotics.lib.voice.ifly.engine.IFlyLocalAsrEngine",
"version": 1,
"extra": {
"content": "String"
},
"content": "{\n \"sn\":1,\n \"ls\":true,\n \"bg\":0,\n \"ed\":0,\n \"ws\":[{\n \"bg\":0,\n \"cw\":[{\n \"w\":\"測試\",\n \"gm\":0,\n \"sc\":67,\n \"id\":100001\n }],\n \"slot\":\"<NuwaQAQ>\"\n }],\n \"sc\":68\n}"
}
如果回來的json檔案為空的話代表沒有辨識到要求輸入的內容。
在Demo_MixUnderstand Scene中。接收命令,判斷接收到的內容後再做處理。目前支援中文、英文、韓文、日文。
1.界接Event
xxxxxxxxxx
Nuwa.onGrammarState += OnGrammarState; //Grammar設定完
Nuwa.onMixUnderstandComplete += MixUnderstandFunction; //接收mixUnderstand結果
Nuwa.onLocalCommandComplete += TrueFunction; //聲音辨識成功
Nuwa.onLocalCommandException += FalseFunction; //聲音辨識例外
2.設定Grammar需要的名稱跟值
xxxxxxxxxx
strinExceptiong mi_Name; //grammer的名稱
string[] values; //要辨識的字串
/*
mi_Name = "robot";
values = new string[2] {"哈囉","你好"};
*/
Nuwa.prepareGrammarToRobot(mi_Name, values);
3.Grammar完成設定後,開始聲音辨識。
xxxxxxxxxx
void OnGrammarState(bool isError, string info)
{
Debug.Log(string.Format("OnGrammarState isError = {0} , info = {1}", isError, info));
//開始聲音辨識
Nuwa.MixUnderstandFunction();
}
收到的結果有兩種,ResultType分別為LOCAL_COMMAND、UNDERSTAND。
LOCAL_COMMAND的Json格式如下:
xxxxxxxxxx
{
"result": "測試",
"x-trace-id": "2ed6670726b47c5a3ac006aafa9216d",
"engine": "Google Cloud",
"type": 1,
"class": "com.nuwarobotics.lib.voice.hybrid.engine.NuwaTWMixEngine",
"version": 1,
"extra": {
"content": "String"
},
"content": "{\"sn\":1,\"ls\":true,\"bg\":0,\"ed\":0,\"ws\":[{\"bg\":0,\"slot\":\"<MiboMixunderstand>\",\"cw\":[{\"id\":10001,\"w\":\"測試\",\"sc\":96,\"gm\":0}]}],\"sc\":94}"
}
UNDERSTAND的Json格式如下:
xxxxxxxxxx
{
"result": "123",
"x-trace-id": "e5e37c47dc4649b08cf71015c8d1b69e",
"engine": "Google Cloud",
"type": 2,
"class": "com.nuwarobotics.lib.voice.hybrid.engine.NuwaTWMixEngine",
"version": 1
}
語音轉文字(Speed2Text)
在Demo_Speed2Text Scene中,把收到的語音轉成文字,支援中文。
1.介接Event
xxxxxxxxxx
Nuwa.onSpeech2TextComplete += SpeechCallback;
2.呼叫SpeechToText
xxxxxxxxxx
Nuwa.setListenParameter(Nuwa.ListenType.RECOGNIZE, "language", "en_us");
Nuwa.setListenParameter(Nuwa.ListenType.RECOGNIZE, "accent", null);
Nuwa.startSpeech2Text(false); //不需要wake up, 所以設定false
回傳的字串為純文字,直接使用即可。
另外,此功能需要網路連線。假如機器人目前的系統時間沒跟目前所在地區時區相同的話,很有可能會出現回傳回來字串為空的狀態。這點要特別注意。
物件辨識(Recognize)
在Demo_Recognize Scene中,讓機器人可以辨識物件。
xxxxxxxxxx
Nuwa.onConnected += isConnectRecognizeSystem;//連線成功後接收
Nuwa.onOutput+=ReconizeCheck;//辨識輸出後的資料
xxxxxxxxxx
Nuwa.startRecognition(Nuwa.NuwaRecognition.OBJ);
xxxxxxxxxx
// ReconizeCheck is called once per frame
private void SetInfoData(Nuwa.FaceRecognizeData[] data)
{
for(int i = 0; i < data.Length; i++)
{
InfoText.text += "\nid:" + data[i].idx + ", name:" + data[i].name + ", conf:" + data[i].conf + "\nrect:" + JsonUtility.ToJson(data[i].rect);
}
}
data[i].dataset[j]的資料大致上會如下,抓title中的資料即可。
xxxxxxxxxx
{"confidence":0.21084809303283692,"id":"122","title":"10006_Cup_杯子"}
{"confidence":0.1969204843044281,"id":"265","title":"10337_SodaBottle_汽水瓶"}
{"confidence":0.13715511560440064,"id":"131","title":"10023_Feeding Bottle_奶瓶"}
人臉追蹤(Face_track)
在Demo_Facetrack中,讓機器人追蹤人臉的位置。
xxxxxxxxxx
Nuwa.onTrack += GetTrackData;
xxxxxxxxxx
Nuwa.startRecognition(Nuwa.NuwaRecognition.FACE);
xxxxxxxxxx
void GetTrackData(Nuwa.TrackData[] data)
{
float _x = float.Parse(data[0].x); //只攔截第一人
float _y = float.Parse(data[0].y);
float _w = float.Parse(data[0].width);
float _h = float.Parse(data[0].height);
FaceOriginPos = new Vector2(_x, _y); // set face pos
FaceOriginSize = new Vector2(_w, _h); // set face size
FaceCenterPos = FaceOriginPos + (FaceOriginSize / 2f); // set face center
}
回來的數據大致如下
xxxxxxxxxx
{"height":175,"width":175,"x":250,"y":93}
人臉辨識(Face_Recognize)
讓機器人可以辨識眼前的使用者是誰, 程式在Demo_FaceRecognize中。可以先使用新增家人來先行加入要辨識的使用者。
xxxxxxxxxx
Nuwa.onFaceRecognize += ReconizeCheck;
xxxxxxxxxx
Nuwa.startRecognition(Nuwa.NuwaRecognition.FACE_RECOGNITION);
xxxxxxxxxx
private void SetInfoData(Nuwa.FaceRecognizeData[] data)
{
if(data != null)
{
for(int i = 0; i < data.Length; i++)
{
InfoText.text += "\nid:" + data[i].idx + ", name:" + data[i].name + ", conf:" + data[i].conf + ", rect:" + JsonUtility.ToJson(data[i].rect);
}
}
}
移動/旋轉(Movement)
讓機器人可以前後移動以及旋轉。方式有直接設定值做移動/旋轉,或是線性加速的方式做移動/旋轉。 另外,此功能需要解除移動鎖定才能呼叫使用。另外、幫機器人充電時,機器人會自動設定移動鎖定。
下面為解除輪子的移動鎖定/移動鎖定的程式。
xxxxxxxxxx
Nuwa.LockWheel(); //鎖定輪子
Nuwa.UnLockWheel(); //解除鎖定輪子
移動,值介於-0.2~0.2間。需要停止移動的時候設定0即可
xxxxxxxxxx
Nuwa.SetMove(float);
線性加速移動(前進)
xxxxxxxxxx
Nuwa.MoveForwardInAccelerationEx();
線性加速移動(後退)
xxxxxxxxxx
Nuwa.MoveBackInAccelerationEx();
停止線性加速移動。此function只能停止線性加速的移動,無法停止由SetMove()呼叫的移動。
xxxxxxxxxx
Nuwa.StopInAcclerationEx();
旋轉 , 值介於-20~20, 需要停止旋轉的時候設定0即可
xxxxxxxxxx
Nuwa.SetTurn(int);
向左線性加速旋轉
xxxxxxxxxx
Nuwa.TurnLeftEx();
向右線性加速旋轉
xxxxxxxxxx
Nuwa.TurnRightEx();
停止線性加速旋轉。此Function只能停止線性加速旋轉的部分,無法停止由setTurn()呼叫的移動。
xxxxxxxxxx
Nuwa.StopTurnEx();
還有,當處於線性加速移動/旋轉時強制鎖定輪子、並且在解除鎖定後再使用相反的線性加入移動,機器人會先維持之前的線釁加速移動方式,才會漸漸變成要做的相反移動方式。