package acc import ( "context" "fmt" "joylink.club/bj-rtsts-server/config" "joylink.club/bj-rtsts-server/dto/state_proto" "joylink.club/bj-rtsts-server/third_party/message" "joylink.club/bj-rtsts-server/third_party/udp" "math" "sync" "time" ) type AccVobc interface { Start(accManager AccVobcManager) Stop() } type AccVobcManager interface { GetRunAccConfig() config.AccConfig FindAccTrain() *state_proto.TrainState } var ( initLock = &sync.Mutex{} singleObj *accVobcService ) const ( accInterval = 15 accSpeedUnit = 9.8 ) func Default() AccVobc { defer initLock.Unlock() if singleObj == nil { initLock.Lock() singleObj = &accVobcService{} } return singleObj } type accVobcService struct { controlContext context.CancelFunc vobcClient udp.UdpClient radarVobcManager AccVobcManager } func (acc *accVobcService) Start(accManager AccVobcManager) { config := accManager.GetRunAccConfig() if config.RemoteIp == "" || config.RemotePort <= 0 || !config.Open { } acc.vobcClient = udp.NewClient(fmt.Sprintf("%v:%v", config.RemoteIp, config.RemotePort)) ctx, cancleFunc := context.WithCancel(context.Background()) acc.controlContext = cancleFunc acc.radarVobcManager = accManager go acc.sendTask(ctx) } func (acc *accVobcService) sendTask(ctx context.Context) { for { select { case <-ctx.Done(): return default: } trainStatus := acc.radarVobcManager.FindAccTrain() if trainStatus != nil { speedAcc := trainStatus.DynamicState.Acceleration t := speedAcc / accSpeedUnit acc.vobcClient.SendMsg(&message.Accelerometer{Acc: math.Float32bits(t)}) } time.Sleep(time.Millisecond * accInterval) } } func (acc *accVobcService) Stop() { if acc.controlContext != nil { acc.controlContext() acc.controlContext = nil } if acc.vobcClient != nil { acc.vobcClient.Close() acc.vobcClient = nil } }