ict.lixian.three/Assets/Scripts/ROBOT/RobotManager.cs

806 lines
30 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using NAudio.Wave;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using DG.Tweening;
using static RobotManager;
public enum RobotCommand
{
/// <summary>
///设置位置
/// </summary>
init_position,
/// <summary>
/// 设置名称
/// </summary>
set_name,
/// <summary>
/// 设置颜色
/// </summary>
set_color,
/// <summary>
/// 控制舵机值
/// </summary>
servo_motor_control,
/// <summary>
/// 获取动作
/// </summary>
get_action_lab,
/// <summary>
/// 执行动作
/// </summary>
play_action,
/// <summary>
/// 获取语音识别结果
/// </summary>
get_speech_text,
/// <summary>
/// 获取识别结果
/// </summary>
get_image_action,
/// <summary>
/// 打开动作编辑面板
/// </summary>
define_action,
/// <summary>
/// 文本转语音
/// </summary>
speak,
/// <summary>
/// 打开颜色识别面板
/// </summary>
openColorDetect,
/// <summary>
/// 关闭颜色识别
/// </summary>
stopColorDetect,
/// <summary>
/// 左转
/// </summary>
trun_left,
/// <summary>
/// 右转
/// </summary>
trun_right
}
public class RobotManager : MonoBehaviour
{
public GameObject robotTempCamera;
public RobotUIManager robotUIManager;
public Collider Collider;
public static RobotManager instance;
public static GameObject robot;
public GameObject customPanel;
public GameObject robotActionTemple;
private GameObject templete;
/// <summary>
/// 机器人模板
/// </summary>
public GameObject Templete { get { if (templete == null) templete = Resources.Load("Prefabs/JQR_YJ") as GameObject; return templete; } }
/// <summary>
/// 机器人生成父物体
/// </summary>
public Transform robotParent;
public static List<GameObject> robotgames = new List<GameObject>();
public static List<Robot> robots = new List<Robot>();
/// <summary>
/// 使用全局坐标
/// </summary>
public bool useGlobalPosition;
public static int[] idsValue = new int[18];
public static bool ControlRobot;
public Robot Robot;
public List<Motion> Motions = new List<Motion>();
//默认动作站立
public static List<MotionGroup> standMon = new List<MotionGroup>();
public static int time;
/// <summary>
/// 动作组
/// </summary>
public List<MotionGroup> all_motions = new List<MotionGroup>();
/// <summary>
/// 场景元素物体
/// </summary>
private List<GameObject> sceneObject = new List<GameObject>();
private void Awake()
{
Collider = GameObject.Find("Object005").GetComponent<Collider>();
instance = this;
robotParent = GameObject.Find("GameScenter").transform;
GameObject game = GameObject.Find("MyTemp");
CustomPanel.robot = game.transform.Find("My_JQR_YJ_Temp").gameObject;
GetMotionLab();
}
private void Start()
{
Debug.Log("start");
MyServer.instance.SetHandler_jqr(PythonDataHandler);
MyServer.instance.SetHandler_other((data) =>
{
{
var command = (PublicCommond)Enum.Parse(typeof(PublicCommond), data["commond"].ToString());
var eventid = data["event_id"].ToObject<int>();
switch (command)
{
case PublicCommond.init_scene:
{
//关闭语音面板
RobotUIManager.instance.CloseTextToSpeakPanel();
//停止颜色识别
UnityCallPython.instance.StopColorRead();
//关闭媒体音乐
MediaPlayer.Instance.AudioStop();
//删除UI界面
if (RobotUI.Instance.panelDic != null && RobotUI.Instance.panelDic.Count > 0)
{
foreach (var item in RobotUI.Instance.panelDic.Values)
{
//item.SetActive(false);
Destroy(item.gameObject);
}
RobotUI.Instance.panelDic.Clear();
}
//初始化场景
RobotUI.Instance.Init();
RobotUIManager.instance.CloseWebCam();
if (robotgames.Count > 0)
{
robotgames.ForEach(a =>
{
Destroy(a.gameObject);
});
robotgames.Clear();
}
robots.Clear();
//删除自定义动作面板
if (customPanel != null)
{
//customPanel.SetActive(false);
Destroy(customPanel);
//RobotUI.Instance.OpenPanel(RobotePanelEnum.CustomPanel.ToString());
}
if (robotActionTemple != null)
{
robotActionTemple.SetActive(false);
}
//清理场景元素
sceneObject.ForEach(a =>
{
Destroy(a);
});
sceneObject.Clear();
//重置分数
ScoreManager.Instance.ResetScore();
//隐藏ide面板
MainCanvasManager.Instance.transform.Find("ide设置面板").gameObject.SetActive(false);
MyServer.instance.SendMsgToSDK(eventid, ResultStatus.SUCCESS);
}
break;
case PublicCommond.audio_load:
var __file_name = data["filepath"].ToObject<string>();
MediaPlayer.Instance.NewAudioLoad(__file_name, (result, msg) =>
{
ConsolePanel.ConsoleOutput("语音加载"+ (result==true?"完成:":"失败:"+ msg), "log");
DoReturn(result, eventid, msg);
});
break;
case PublicCommond.audio_play:
MediaPlayer.Instance.AudioPlay();
break;
case PublicCommond.audio_pause:
MediaPlayer.Instance.AudioPause();
break;
case PublicCommond.audio_stop:
MediaPlayer.Instance.AudioStop();
break;
case PublicCommond.audio_set_volume:
var __volume = data["volume"].ToObject<float>();
MediaPlayer.Instance.AudioSetVolume(__volume);
break;
case PublicCommond.screen_shot:
bool isStep = data["isStep"].ToObject<bool>();
string stepName = data["stepName"].ToObject<string>();
if (!isStep)
{
MainCanvasManager.Instance.ScreemShot(CallForTest.instance.pathTaskFile + "/任务.png");
}
else
{
MainCanvasManager.Instance.ScreemShot(CallForTest.instance.pathTaskFile + "/步骤_" + stepName + ".png");
}
break;
case PublicCommond.get_control_image:
List<string> tmpNames = new List<string>();
List<MyCardItem> list = GameObject.FindObjectsByType<MyCardItem>(FindObjectsInactive.Exclude, FindObjectsSortMode.None).ToList();
list.ForEach(a =>
{
if (!string.IsNullOrEmpty(a.Nameid))
{
tmpNames.Add(a.Nameid);
}
});
DoReturn(true, eventid, JsonConvert.SerializeObject(tmpNames));
break;
case PublicCommond.set_control_image:
{
string name = data["name"].ToString();
string filePath = data["filePath"].ToString();
MyCardItem item = GameObject.FindObjectsByType<MyCardItem>(FindObjectsInactive.Exclude, FindObjectsSortMode.None).ToList().Find(a => a.Nameid == name);
if (item != null)
{
item.ChangeTexture(filePath, (isok,str) =>
{
DoReturn(isok, eventid, str);
});
}
}
break;
case PublicCommond.get_scene_objet:
{
List<string> names=new List<string>();
var tmps=Resources.LoadAll<GameObject>("sceneObject").ToList();
tmps.ForEach(a =>
{
names.Add(a.name);
});
DoReturn(true, eventid, JsonConvert.SerializeObject(names));
}
break;
case PublicCommond.set_scene_objet:
{
string name = data["name"].ToString();
float[] point = data["point"].ToObject<float[]>();
float[] rotate = data["rotate"].ToObject<float[]>();
GameObject obj=Resources.Load<GameObject>("sceneObject/" + name);
if (obj != null)
{
GameObject sceneObj = GameObject.Instantiate<GameObject>(obj, robotParent,true);
sceneObject.Add(sceneObj);
sceneObj.transform.localPosition = new Vector3(point[0], point[1], point[2]);
sceneObj.transform.localEulerAngles = new Vector3(rotate[0], rotate[1], rotate[2]);
DoReturn(true, eventid, "设置成功");
}
else
{
DoReturn(false, eventid, "不存在此场景元素");
}
}
break;
case PublicCommond.set_camera_mode:
{
//设置相机模式
var mode = data["mode"].ToObject<string>();
if (mode == "自由模式")
{
Camera.main.transform.GetComponent<CameraMove>().enabled = true;
transform.GetComponent<MyCameraRoate>().EndRoate();
}
else if (mode == "环绕模式")
{
var center = data["center"].ToObject<float[]>();
var radius = data["radius"].ToObject<float>();
var tmpspeed = data["speed"].ToObject<float>();
var high = data["high"].ToObject<float>();
Camera.main.transform.GetComponent<CameraMove>().enabled = false;
Vector3 tmpc = new Vector3(center[0], center[1], center[2]);
transform.GetComponent<MyCameraRoate>().StartRoate(Camera.main, robotParent.position + tmpc, radius, tmpspeed, high);
}
}
break;
default:
break;
}
}
});
}
/// <summary>
/// 获取所有动作文件
/// </summary>
public void GetMotionLab()
{
var path = Path.Combine(Application.streamingAssetsPath, "RobotFiles/Motions");
DirectoryInfo directory = new DirectoryInfo(path);
FileInfo[] files = directory.GetFiles("*.txt");
for (int i = 0; i < files.Length; i++)
{
using (StreamReader reader = new StreamReader(files[i].FullName))
{
var txt = reader.ReadToEnd();
var newGroup = new MotionGroup() { motionName = files[i].Name.Split('.')[0], motionList = new List<Motion>() };
var motor_values = JsonConvert.DeserializeObject<List<RobotMotorValues>>(txt);
for (int j = 0; j < motor_values.Count; j++)
{
newGroup.motionList.Add(new Motion(motor_values[j]));
}
all_motions.Add(newGroup);
if (newGroup.motionName == "stand")
{
standMon.Add(newGroup);
}
}
}
}
public void ShowMotions()
{
}
public class MonsData
{
public string action;
public float duration;
public int loop_times;
public int number;
}
public void PythonDataHandler(JObject _jobject)
{
var command = (RobotCommand)Enum.Parse(typeof(RobotCommand), _jobject["commond"].ToString());
var eventid = _jobject["event_id"].ToObject<int>();
var number = _jobject["number"].ToObject<int>();
ScoreManager.Instance.UpdateScore(command.ToString());
switch (command)
{
case RobotCommand.init_position:
var pos = _jobject["point"].ToObject<float[]>();
var rotate = _jobject["rotate"].ToObject<float>();
//Console(string.Format("设置[0]号机器人位置:[{1},{2}]", number, pos[0], pos[1]));
if (CreateNewRobot(new Vector3(pos[0], 0, pos[1]), rotate, false, number))
{
DoReturn(true, eventid, "初始化机器人"+ number + "成功!");
ConsolePanel.ConsoleOutput("初始化机器人"+ number + "成功!", "log");
}
else
{
DoReturn(false, eventid, "初始化机器人失败!");
ConsolePanel.ConsoleOutput("初始化机器人失败!", "log");
}
break;
case RobotCommand.set_name:
var name = _jobject["name"].ToObject<string>();
//Console(string.Format("设置{0}号机器人名称:{1}", number, name));
if (robots!=null&&robots.Count>0)
{
if (UpdateRobotName(number, name))
{
DoReturn(true, eventid, "名称:" + name + "设置成功!");
}else
{
DoReturn(false, eventid, "名称:" + name + "设置失败!");
ConsolePanel.ConsoleOutput("名称:" + name + "设置失败!", "log");
}
}
else
{
DoReturn(false, eventid, "名称:" + name + "设置失败!"+ "请创建机器人!");
ConsolePanel.ConsoleOutput("名称:" + name + "设置失败!" + "请创建机器人!", "log");
}
break;
case RobotCommand.set_color:
var rob_colorstr = _jobject["color"].ToObject<string>();
//var rob_color = UnityEngine.Color.red;
//UnityEngine.ColorUtility.TryParseHtmlString("#" + rob_colorstr, out rob_color);
//Console(string.Format("设置{0}号机器人颜色:{1}", number, rob_color));
if (robots != null && robots.Count > 0)
{
if (UpdateRobotColor(number, rob_colorstr))
{
DoReturn(true, eventid, rob_colorstr + "颜色设置成功!");
}
else
{
DoReturn(false, eventid, rob_colorstr + "颜色设置失败!");
ConsolePanel.ConsoleOutput(rob_colorstr + "颜色设置失败!", "log");
}
}
else
{
DoReturn(false, eventid, rob_colorstr + "颜色设置失败!" + "请创建机器人!");
ConsolePanel.ConsoleOutput( rob_colorstr + "颜色设置失败!" + "请创建机器人!", "log");
}
break;
case RobotCommand.get_action_lab:
//获取动作列表
Debug.Log("获取成功");
string actions = "";
actions += ("nodHead2.5秒,");
actions += ("shakeHead2.5秒,");
all_motions.ForEach(a =>
{
float time=0;
a.motionList.ForEach(b =>
{
time += b.duration_time;
});
actions += (a.motionName + "" + time + "秒,");
});
DoReturn(true, eventid, actions.TrimEnd(''));
//string[] filesname = GetAction(false, number);
//if (filesname != null && filesname.Length > 0)
//{
// string str = "nodHeadshakeHead";
// for (int i = 0; i < filesname.Length; i++)
// {
// var a = filesname[i].Split('\\')[filesname[i].Split('\\').Length - 1];
// var b = a.Split('.')[0];
// str += b + "";
// }
// DoReturn(true, eventid, str.TrimEnd(''));
//}
//else
//{
// DoReturn(false, eventid, "获取失败");
//}
break;
case RobotCommand.play_action:
var action = _jobject["action"].ToObject<string>();
var duration = _jobject["duration"].ToObject<float>();
var loop_times = _jobject["loop_times"].ToObject<int>();
MonsData monsData = new MonsData();
monsData.action = action;
monsData.duration = duration;
monsData.loop_times = loop_times;
monsData.number = number;
//robotgames[number - 1].GetComponent<Robot>().isPlaying = true;
var tmpaction=RobotManager.instance.all_motions.Find(a => a.motionName == action);
if(tmpaction!=null)
{
robotgames[number - 1].GetComponent<Robot>().actionque.Enqueue(monsData);
}
else
{
if (action == "nodHead")
{
robotgames[number - 1].GetComponent<Robot>().NodHead(loop_times);
}
else if (action == "shakeHead")
{
robotgames[number - 1].GetComponent<Robot>().ShakeHead(loop_times);
}
else
{
DoReturn(false, eventid, "无此动作:" + action);
ConsolePanel.ConsoleOutput("无此动作:" + action, "log");
}
}
break;
case RobotCommand.get_speech_text:
Openmicrophone(number,(isok,result)=>
{
DoReturn(isok, eventid, result);
});
break;
case RobotCommand.define_action:
DoReturn(DefineAction(true, number), eventid, DefineAction(true, number) ? "自定义动作成功!" : "自定义动作失败!");
break;
case RobotCommand.servo_motor_control:
var id = _jobject["servo_id"].ToObject<int>();
var value = _jobject["value"].ToObject<int>();
SetServoMotorContorl(number, id, value);
break;
case RobotCommand.speak:
string text = _jobject["txt"].ToObject<string>();
string tone = _jobject["tone"].ToObject<string>();
int speed = _jobject["speed"].ToObject<int>();
RobotUIManager.instance.OpenTextToSpeekPanel(text, tone, speed, robotgames[number - 1].GetComponent<AudioSource>());
break;
case RobotCommand.openColorDetect:
StartColorDetect(number);
ConsolePanel.ConsoleOutput("开始颜色识别");
break;
case RobotCommand.stopColorDetect:
StopColorDetect(number);
ConsolePanel.ConsoleOutput("停止颜色识别");
break;
case RobotCommand.trun_left:
{
float angle = _jobject["angle"].ToObject<float>();
float time = _jobject["time"].ToObject<float>();
var robot = robots.Find(x => x.robot_id == number);
if (robot != null)
{
Vector3 initR = robot.transform.eulerAngles;
robot.transform.Rotate(Vector3.down, angle, Space.World);
Vector3 R = robot.transform.eulerAngles;
robot.transform.eulerAngles = initR;
robot.transform.DORotate(R, time).OnComplete(() =>
{
DoReturn(true, eventid, "");
});
}
}
break;
case RobotCommand.trun_right:
{
float angle = _jobject["angle"].ToObject<float>();
float time = _jobject["time"].ToObject<float>();
var robot = robots.Find(x => x.robot_id == number);
if (robot != null)
{
Vector3 initR = robot.transform.eulerAngles;
robot.transform.Rotate(Vector3.up, angle, Space.World);
Vector3 R = robot.transform.eulerAngles;
robot.transform.eulerAngles = initR;
robot.transform.DORotate(R, time).OnComplete(() =>
{
DoReturn(true, eventid, "");
});
}
}
break;
default:
Debug.Log("机器人无此指令:" + command);
break;
}
}
/// <summary>
/// 开始图像识别
/// </summary>
/// <param name="number"></param>
void StartColorDetect(int number)
{
UnityCallPython.instance.StartColorRead(robotgames[number - 1].GetComponent<Robot>());
}
/// <summary>
/// 关闭颜色识别
/// </summary>
/// <param name="number"></param>
void StopColorDetect(int number)
{
UnityCallPython.instance.StopColorRead();
}
private void SetServoMotorContorl(int _number, int id, int value)
{
robotgames[_number - 1].GetComponent<Robot>().HVBUSSERVOs.Find(x => x.indexNo.Equals(id)).UpdateValue(value, 0);
}
/// <summary>
/// 打开动作编辑面板
/// </summary>
/// <param name="v"></param>
/// <param name="_number"></param>
/// <returns></returns>
private bool DefineAction(bool v, int _number)
{
robotTempCamera.SetActive(true);
for (int i = 0; i < robotgames.Count; i++)
{
robotgames[i].SetActive(false);
}
ControlRobot = true;
customPanel = RobotUI.Instance.OpenPanel(RobotePanelEnum.CustomPanel.ToString());
if (customPanel != null)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 打开录音面板,并开始语音识别
/// </summary>
/// <param name="v"></param>
/// <param name="number"></param>
/// <returns></returns>
private void Openmicrophone(int number,Action<bool,string> callback)
{
RobotUI.Instance.OpenPanel(RobotePanelEnum.RecordPanel.ToString()).GetComponent<RecordPanel>().Init(number, callback);
//if (MicrophoneInput.instance.CheckMicrophone())
//{
// RobotUI.Instance.OpenPanel(RobotePanelEnum.RecordPanel.ToString()).GetComponent<RecordPanel>().Init(number,callback);
//}
//else
//{
// callback(false,"错误:无麦克风");
//}
}
/// <summary>
/// 获取动作
/// </summary>
/// <param name="_isarray"></param>
/// <param name="_uav_number"></param>
/// <returns></returns>
private string[] GetAction(bool _isarray, int _uav_number)
{
string[] filesName = Directory.GetFiles(Application.streamingAssetsPath + "/RobotFiles/Motions", "*.txt");
if (filesName.Length > 0)
{
return filesName;
}
return null;
}
/// <summary>
/// 打开摄像机
/// </summary>
public bool OpenCam(bool flag, int number)
{
if (robotgames[number - 1] != null)
{
bool isopencamera = robotgames[number - 1].GetComponent<Robot>().OpenCamera();
return isopencamera;
}
return false;
}
/// <summary>
/// 播放动画
/// </summary>
/// <param name="_action"></param>
/// <param name="_duration"></param>
/// <param name="loop_times"></param>
/// <summary>
/// 设置机器人颜色
/// </summary>
/// <param name="number"></param>
/// <param name="rob_color"></param>
/// <returns></returns>
private bool UpdateRobotColor(int number, string color)
{
UnityEngine.Color rob_color;
if(UnityEngine.ColorUtility.TryParseHtmlString(color, out rob_color))
{
var rob = robots.Find(x => x.robot_id == number);
if (rob == null)
{
return false;
}
else
{
rob.SetColor(rob_color);
return true;
}
}
else
{
return false;
}
}
/// <summary>
/// 输出机器人信息
/// </summary>
/// <param name="_message"></param>
/// <param name="_type"></param>
private void Console(string _message, string _type = "log")
{
ConsolePanel.ConsoleOutput(_message, _type);//输出机器人信息
}
/// <summary>
/// 执行并返回结果
/// </summary>
/// <param name="_success"></param>
/// <param name="_eventid"></param>
/// <param name="_result"></param>
private void DoReturn(bool _success, int _eventid, string _result)
{
MyServer.instance.SendMsgToSDK(_eventid, _success ? ResultStatus.SUCCESS : ResultStatus.FAILED_WARNING, _result);
//if (_success)
// MyServer.instance.SendMsgToSDK(_eventid, ResultStatus.SUCCESS);
//else
// MyServer.instance.SendMsgToSDK(_eventid, ResultStatus.FAILED_WARNING, _result);
}
/// <summary>
/// 从位置创建机器人
/// </summary>
/// <param name="_pos"></param>
/// <param name="_isarray"></param>
/// <param name="_uav_number"></param>
/// <returns></returns>
public bool CreateNewRobot(Vector3 _pos, float rotate, bool _isarray = false, int _number = 0)
{
////检测范围内是否有机器人
//if (Physics.CheckSphere(_pos, 0.75f, 1 << 6) && !_isarray)
// return false;
var newt = Instantiate(Templete, robotParent, true);
if (useGlobalPosition)
{
newt.transform.position = _pos;
newt.transform.eulerAngles = new Vector3(-90, rotate-90, 0);
}
else
{
newt.transform.localPosition = _pos;
newt.transform.localEulerAngles = new Vector3(-90, rotate-90, 0);
}
Collider[] collider = Physics.OverlapSphere(newt.transform.position, 0.1f);
if (collider.Contains(Collider))
{
}
else
{
ConsolePanel.ConsoleOutput(_number + "号机器人初始化位置超过限制,请重试", "warning");
Destroy(newt);
return false;
}
robotgames.Add(newt);
newt.GetComponent<Robot>().id = _number;
newt.transform.SetAsLastSibling();
newt.SetActive(true);
var rob = newt.GetComponentInChildren<Robot>();
robots.Add(rob);
rob.robot_id = _number == 0 ? robots.Count : _number;
return true;
}
public bool UpdateRobotName(int _number, string _name)
{
var robot = robots.Find(x => x.robot_id == _number);
if (robot == null)
{
return false;
}
else
{
robot.SetName(_name);
return true;
}
}
internal void GetTextString(string recordstr)
{
}
}