//STEP 2 END RECORDING AND SAVE DATA FROM CACHE public async Task <ActionResult> EndCarRecord(int carName) { //get car info from db var car = _carService.GetCarByName(carName); //save cached coordinates to database var carInCache = await RedisHelper.Instance.GetCacheItem <CachedRecordingModel>($"car_{car.CarName}"); _carService.EndCarRecording(car.Id, carInCache.CachedCoordinates); //update robot status in cache carInCache.RobotStatus = 0; carInCache.CachedCoordinates = new List <Coordinate>(); await RedisHelper.Instance.SetCache($"car_{car.CarName}", carInCache); //send to robot to end recording var msg = new msg_control_cmd() { cmd = 0, cmd_slave = 0, route_id = 0 }; var outbound = new OutboundModel() { Ip = carInCache.Ip, CarName = carInCache.CarName, Data = new List <object> { msg } }; await RedisHelper.Instance.SetCache <OutboundModel>("command", outbound); return(Ok()); }
////STEP 4 IMPORT THE COORDINATES FROM CSV AND GENERATE ROUTE public async Task ImportCoordinatesCreateRoute(int carName, bool isReturn = false) { //get the coordinates from uploaded CSV var formFile = HttpContext.Request.Form.Files[0]; if (formFile != null) { var list = new List <Coordinate>(); using (var ms = new MemoryStream()) { formFile.CopyTo(ms); ms.Position = 0; StreamReader reader = new StreamReader(ms); while (!reader.EndOfStream) { var line = reader.ReadLine(); var values = line.Split(','); var anc = new Coordinate(double.Parse(values[0]), double.Parse(values[1])); list.Add(anc); } } ////update the end position in cache // update the final endpoint in cache var carData = _carService.GetCarByName(carName); var cached = await RedisHelper.Instance.GetCacheItem <CachedRecordingModel>($"car_{carData.CarName}"); cached.EndPoint = list.LastOrDefault(); cached.ImpotedCoordinates = list.ToArray(); cached.RouteStatus = 1; await RedisHelper.Instance.SetCache($"car_{carData.CarName}", cached); //create a new route in db _carService.AddRoute(carData.Id, list.ToArray()); //send command to robot //路径点与传输: var outbound = new OutboundModel(); outbound.CarName = cached.CarName; outbound.Data = new List <object>(); outbound.Ip = cached.Ip; var msg_total = cached.ImpotedCoordinates.Count; for (int i = 0; i < msg_total; i++) { outbound.Data.Add(new msg_map_route { msg_total = msg_total, msg_count = i + 1, //it starts with 1 latitude = cached.ImpotedCoordinates[i].Latitude, longitude = cached.ImpotedCoordinates[i].Longitude }); } RedisHelper.Instance.SetCache("command", outbound).Wait(); } }
//STEP 1 START RECORDING CAR COORDINATES public async Task <ActionResult> StartCoordinateRecording(int carName, string recordId) { if (recordId == null) { //get car info from db var car = _carService.GetCarByName(carName); //update robot status in cache var carInCache = await RedisHelper.Instance.GetCacheItem <CachedRecordingModel>($"car_{car.CarName}"); if (carInCache == null) { return(BadRequest()); } carInCache.RobotStatus = Const.ROBOT_STATUS_REMOTE; await RedisHelper.Instance.SetCache($"car_{car.CarName}", carInCache); //add to db _carService.AddNewCarRecord(car.Id); //send to robot to start recording var msg = new msg_control_cmd() { cmd = 1, cmd_slave = 0, route_id = 0 }; var outbound = new OutboundModel() { Ip = carInCache.Ip, CarName = carInCache.CarName, Data = new List <object> { msg } }; await RedisHelper.Instance.SetCache <OutboundModel>("command", outbound); return(Ok()); } else { return(BadRequest()); } }
private static void printReceiveMsg(object reciveClient) { /* */ /* 用来打印接收的消息*/ /* */ TcpClient client = reciveClient as TcpClient; if (client == null) { Console.WriteLine("client error"); return; } try { NetworkStream stream = client.GetStream(); while (true) { byte[] result = new byte[1024]; int num = 0; try { num = stream.Read(result, 0, result.Length); //将数据读到result中,并返回字符长度 } catch (IOException ex) { Logger.Instance.Log(LogLevel.Warning, $"IO exception detected, client {client.Client.RemoteEndPoint.ToString()} might be disconnected"); } if (num != 0) { string str = Encoding.UTF8.GetString(result, 0, num);//把字节数组中流存储的数据以字符串方式赋值给str Logger.Instance.Log(LogLevel.Information, $"From: " + client.Client.RemoteEndPoint.ToString() + " : " + str); try { var rows = str.Split(new string[] { "}{" }, StringSplitOptions.None); foreach (var aRow in rows) { var validatedStr = aRow.FormatValidJson(); HeartBeatModel heartBeat = JsonConvert.DeserializeObject <HeartBeatModel>(validatedStr); if (heartBeat.robot_id == 0) { continue; } if (heartBeat != null) { //zhu che if (heartBeat.robot_id == Const.MAIN_CAR_ID) { //update current postion RedisHelper.Instance.SetCache <HeartBeatModel>("main", heartBeat).Wait(); //carInCache.CurrentPosition = new Coordinate(_heartBeat.longitude, _heartBeat.latitude); //add to the coordinate list //carInCache.CachedCoordinates.Add(new Coordinate(_heartBeat.longitude, _heartBeat.latitude)); //trigger other route if possible var _cars = RedisHelper.Instance.GetCurrentCarsInCache().Result; foreach (var cachedModel in _cars) { Logger.Instance.Log(LogLevel.Information, $"checking trigger point for robot {cachedModel.CarName}"); if (cachedModel.RouteStatus == 1) { Logger.Instance.Log(LogLevel.Information, $"calculating robot {cachedModel.CarName} trigger point: {cachedModel.TriggerPoint.Longitude}, {cachedModel.TriggerPoint.Latitude}. Main car long:{heartBeat.longitude}, lat: {heartBeat.latitude}"); if (cachedModel.TriggerPoint.IsInRange(heartBeat.longitude, heartBeat.latitude)) { //trigger the route now //go to auto pilot mode and send the coordinates to client Logger.Instance.Log(LogLevel.Information, $"robot {cachedModel.CarName} is getting triggered by main car"); var outbound = new OutboundModel(); outbound.CarName = cachedModel.CarName; outbound.Data = new List <object>(); outbound.Ip = cachedModel.Ip; //切换⾄数据传输模式 outbound.Data.Add(new msg_control_cmd() { cmd = 1, cmd_slave = 3, route_id = 0 }); //循迹驾驶 outbound.Data.Add(new msg_control_cmd() { cmd = 1, cmd_slave = 1, route_id = 0, check = 8, speed = cachedModel.Speed }); RedisHelper.Instance.SetCache("command", outbound).Wait(); //update database with the //update cache status to action cachedModel.RouteStatus = 2; cachedModel.IsDirty = true; Logger.Instance.Log(LogLevel.Information, $"dirty car found, db sync {cachedModel.CarId}"); _carDbService.SyncRoute(cachedModel).Wait(); cachedModel.IsDirty = false; } } } } //fu che else { //Check if the car is in cache //get cache car list var carInCache = RedisHelper.Instance.TryGetFromCarList($"car_{heartBeat.robot_id}").Result; var updateCache = false; if (carInCache == null) { //new robot registers carInCache = heartBeat.ToCachedRecordModel(); //ADD TO DB IF NOT EXIST _carDbService.AddCarIfNotExist(carInCache); //READ FROM DB var carInDb = _carDbService.GetCarByName(heartBeat.robot_id); carInCache.CarId = carInDb.Id; carInCache.Ip = client.Client.RemoteEndPoint.ToString(); //Console.WriteLine($"attempt loading car from db: {carInDb.CarName}, {client.Client.RemoteEndPoint.ToString()}"); Logger.Instance.Log(LogLevel.Information, $"attempt loading car from db: {carInCache.CarName}, {client.Client.RemoteEndPoint.ToString()}"); updateCache = true; //add to the cache RedisHelper.Instance.AddCachedNameIndex(carInCache.CarName); Logger.Instance.Log(LogLevel.Information, "new robot added successfully " + client.Client.RemoteEndPoint.ToString()); } else { ///Ip will change randomly upon reconnect Logger.Instance.Log(LogLevel.Information, $"loaded robot '{heartBeat.robot_id}' successfully from cache:" + client.Client.RemoteEndPoint.ToString()); if (carInCache.Ip != client.Client.RemoteEndPoint.ToString()) { carInCache.Ip = client.Client.RemoteEndPoint.ToString(); updateCache = true; } } if (updateCache) { var carInDb = _carDbService.GetCarByName(heartBeat.robot_id); var latestRouteIfAny = _carDbService.LatestRoute(carInDb.Id); //ready to be triggered by main car if (latestRouteIfAny != null && latestRouteIfAny.RouteStatus == 1) { carInCache.ImpotedCoordinates = latestRouteIfAny.ImportedCarTrack; carInCache.RouteId = latestRouteIfAny.Id; carInCache.RouteStatus = latestRouteIfAny.RouteStatus; } RedisHelper.Instance.SetCache($"car_{carInCache.CarName}", carInCache).Wait(); } //fu che //verify the car status in cache consitent with client if (heartBeat.robot_status == carInCache.RobotStatus) { Console.WriteLine($"synced Robot {client.Client.RemoteEndPoint.ToString()} status {heartBeat.robot_status}"); //update current position in cache carInCache.CurrentPosition = new Coordinate(heartBeat.longitude, heartBeat.latitude); carInCache.Speed = heartBeat.speed; carInCache.Battery = heartBeat.battery; //recording //// 1 == REMOTE CONTROL MODE if (heartBeat.robot_status == Const.ROBOT_STATUS_REMOTE) { Console.WriteLine($"remote control request: update coordinate {heartBeat.longitude}, {heartBeat.latitude}"); //add the coordinate to the cache carInCache.CachedCoordinates.Add(new Coordinate(heartBeat.longitude, heartBeat.latitude)); } //2 == AUTO PILOT MODE else if (heartBeat.robot_status == Const.ROBOT_STATUS_AUTO_PILOT) { //add the coordinates to the cache carInCache.CachedCoordinates.Add(new Coordinate(heartBeat.longitude, heartBeat.latitude)); //is the current position within the endpoint? if (carInCache.EndPoint.IsInRange(heartBeat.longitude, heartBeat.latitude)) { //send to client to stop auto pilot mode var outbound = new OutboundModel(carInCache.Ip, carInCache.CarName); RedisHelper.Instance.SetCache("command", outbound).Wait(); //update database with the cached coordinates _carDbService.UpdateRouteWithCoordinates(null, carInCache.IsReturn); //update cache status to idle carInCache.RouteStatus++; //end of the process //if (carInCache.RouteStatus == 4) //{ // RedisHelper.Instance.ClearKey("car_{ip}"); //} } } //update cache RedisHelper.Instance.SetCache($"car_{carInCache.CarName}", carInCache).Wait(); } } } } } catch (Exception e) { Logger.Instance.Log(LogLevel.Error, e.Message); } //TODO REMOVE //服务器收到消息后并会给客户端一个消息。 string msg = str; result = Encoding.UTF8.GetBytes(msg); //stream = client.GetStream(); stream.Write(result, 0, result.Length); stream.Flush(); } else { //这里需要注意 当num=0时表明客户端已经断开连接,需要结束循环,不然会死循环一直卡住 clients.Remove(client); Console.WriteLine("client closed"); stream.Dispose(); break; } } stream.Dispose(); } catch (Exception e) { clients.Remove(client); Console.WriteLine("error:" + e.ToString()); Logger.Instance.Log(LogLevel.Error, e.Message); } }
public async Task <IActionResult> Control(int control, int carName) { var carInDb = _carService.GetCarByName(carName); var carInCache = await RedisHelper.Instance.GetCacheItem <CachedRecordingModel>($"car_{carInDb.CarName}"); if (carInCache == null) { return(BadRequest()); } var outbound = new OutboundModel(carInCache.Ip, carInCache.CarName); switch (control) { //急停 case 1: outbound.Data.Add(new msg_control_cmd() { cmd = 0, cmd_slave = 0, route_id = 0, check = 8, speed = 2.1 }); await RedisHelper.Instance.SetCache("command", outbound); return(Ok()); //遥控 case 2: outbound.Data.Add(new msg_control_cmd() { cmd = 1, cmd_slave = 0, route_id = 0, check = 8, speed = 2.1 }); await RedisHelper.Instance.SetCache("command", outbound); return(Ok()); //测绘 case 3: outbound.Data.Add(new msg_control_cmd() { cmd = 2, cmd_slave = 0, route_id = 0, check = 8, speed = 2.1 }); await RedisHelper.Instance.SetCache("command", outbound); return(Ok()); //循迹驾驶 case 4: outbound.Data.Add(new msg_control_cmd() { cmd = 1, cmd_slave = 1, route_id = 0, check = 8, speed = 2.1 }); await RedisHelper.Instance.SetCache("command", outbound); return(Ok()); } return(BadRequest()); }