737 lines
29 KiB
C#
737 lines
29 KiB
C#
using AgroBase.Services;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using static AgroBase.Models.Enums;
|
|
|
|
namespace AgroBase.Models.Modules
|
|
{
|
|
public class MovimentacaoUnificadaModel : DispositivoBaseModel
|
|
{
|
|
public T_Code Dispositivo { get; set; } = T_Code.Mvd;
|
|
public byte _EnderecoCAN_Tx { get; set; } = 0x00;
|
|
public byte _EnderecoCAN_Rx { get; set; } = 0x00;
|
|
|
|
public bool ConexaoAtiva
|
|
{
|
|
get
|
|
{
|
|
return Modulos.Any(x => x.Conectado);
|
|
}
|
|
}
|
|
public bool DirPronto { get; set; } = false;
|
|
public bool MovPronto { get; set; } = false;
|
|
|
|
public int _TaxaAmostragem { get; set; } = 250;
|
|
|
|
public double DistanciaPercorridaOperacao { get; set; } = 0;
|
|
public double TempoEmAtividade { get; set; } = 0;
|
|
public double DistanciaPercorridaTotal { get; set; } = 0;
|
|
public double DistanciaPercorridaParcial { get; set; } = 0;
|
|
public double VelocidadeMedia { get; set; } = 0.0;
|
|
public double DiametroRoda { get; set; } = 0.3556;
|
|
public double ReducaoMotorBLDC { get; set; } = 5;
|
|
public double RPM_Max_MotorBLDC { get; set; } = 500;
|
|
|
|
public DateTime UltimoTickRegistrador = DateTime.MinValue;
|
|
|
|
public static int LogsManter { get; set; } = 60;
|
|
[JsonIgnore]
|
|
public AsyncTaskTimerModel tmrRegistrador;
|
|
[JsonIgnore]
|
|
public AsyncTaskTimerModel tmrRegistradorMOV;
|
|
[JsonIgnore]
|
|
public AsyncTaskTimerModel tmrRegistradorDIR;
|
|
|
|
|
|
public List<ModuloMvdModel> Modulos { get; set; } = new List<ModuloMvdModel>();
|
|
|
|
public (bool, List<string>) StatusModulosMOV(Direcao Lado)
|
|
{
|
|
string Prefixo = Lado == Direcao.Esquerda ? "E" : Lado == Direcao.Direita ? "D" : "";
|
|
var Mods = Modulos.Where(Mod => Mod.Modulo_ID.Contains(Prefixo) && Mod.MovMotor.Comandar).ToList();
|
|
var ModsComFalha = Mods
|
|
.Where(Mod =>
|
|
!Mod.MovMotor.Inicializado || // nao inicializado
|
|
Mod.MovMotor.CodigoAlarme != OIDCanService.OidHandler.OidCodigoErro.NenhumErro || // com leitura de erro
|
|
Mod.MovMotor.AlarmeSensores || // com alarme atuado por sensor
|
|
Mod.MovMotor.AlarmeComando // com alarme atuado por comando de movimento mas o movimento nao acontece
|
|
)
|
|
.ToList();
|
|
|
|
int total = Mods.Count;
|
|
int falhas = ModsComFalha.Count;
|
|
bool _operante = falhas < total;
|
|
|
|
List<string> ModsInoperantes = ModsComFalha.Select(x => x.Modulo_ID).ToList();
|
|
|
|
return (_operante, ModsInoperantes);
|
|
}
|
|
|
|
public (bool, List<string>) StatusModulosDIR(TipoMovimentoDirecional TipoMovimento)
|
|
{
|
|
var Mods = Modulos.Where(Mod => Mod.DirMotor.Comandar).ToList();
|
|
var ModsComFalha = Mods.Where(Mod => !Mod.DirMotor.Inicializado); // nao inicializado
|
|
|
|
bool _operante = !ModsComFalha.Any();
|
|
List<string> ModsInoperantes = ModsComFalha.Select(x => x.Modulo_ID).ToList();
|
|
|
|
return (_operante, ModsInoperantes);
|
|
}
|
|
|
|
|
|
public static MovimentacaoUnificadaModel CarregarParametrosIniciais()
|
|
{
|
|
return new MovimentacaoUnificadaModel()
|
|
{
|
|
Modulos = new List<ModuloMvdModel>()
|
|
{
|
|
new ModuloMvdModel()
|
|
{
|
|
Modulo_ID = "ET",
|
|
MovMotor = MovimentacaoModel.CarregarParametrosIniciais("ET", 0x05, 0x05),
|
|
DirMotor = DirecionalModel.CarregarParametrosIniciais("ET", 0x01, 0x01),
|
|
},
|
|
new ModuloMvdModel()
|
|
{
|
|
Modulo_ID = "EF",
|
|
MovMotor = MovimentacaoModel.CarregarParametrosIniciais("EF", 0x07, 0x07),
|
|
DirMotor = DirecionalModel.CarregarParametrosIniciais("EF", 0x03, 0x03)
|
|
},
|
|
new ModuloMvdModel()
|
|
{
|
|
Modulo_ID = "DT",
|
|
MovMotor = MovimentacaoModel.CarregarParametrosIniciais("DT", 0x06, 0x06),
|
|
DirMotor = DirecionalModel.CarregarParametrosIniciais("DT", 0x02, 0x02)
|
|
},
|
|
new ModuloMvdModel()
|
|
{
|
|
Modulo_ID = "DF",
|
|
MovMotor = MovimentacaoModel.CarregarParametrosIniciais("DF", 0x08, 0x08),
|
|
DirMotor = DirecionalModel.CarregarParametrosIniciais("DF", 0x04, 0x04)
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
public void LimparDados<T>(T _dados)
|
|
{
|
|
var Dados = _dados as MovimentacaoUnificadaModel;
|
|
Dados.DirPronto = false;
|
|
Dados.MovPronto = false;
|
|
Dados.Modulos.ForEach(x =>
|
|
{
|
|
x.MovMotor.Leitura = null;
|
|
x.DirMotor.Leitura = null;
|
|
x.DirMotor.UltimoReferenciamento = DateTime.MinValue;
|
|
x.DirMotor.Referenciado = false;
|
|
x.DirMotor.Referenciando = false;
|
|
});
|
|
|
|
ReiniciarLeituras(Dados);
|
|
}
|
|
|
|
public void ReiniciarLeituras(MovimentacaoUnificadaModel Dados)
|
|
{
|
|
Dados.DistanciaPercorridaParcial = 0;
|
|
Dados.DistanciaPercorridaTotal = 0;
|
|
Dados.DistanciaPercorridaOperacao = 0;
|
|
Dados.VelocidadeMedia = 0;
|
|
Dados.TempoEmAtividade = 0;
|
|
Dados.UltimoTickRegistrador = DateTime.MinValue;
|
|
Dados.Modulos.ForEach(x =>
|
|
{
|
|
x.MovMotor.AlarmeSensores = false;
|
|
x.MovMotor.ConfigFreio.Leitura = false;
|
|
x.MovMotor.LogGrafico = new List<MvdMotorMOVSensorimanetoGrafico>();
|
|
x.MovMotor.Temperatura = 0;
|
|
x.MovMotor.RPM_SP = 0;
|
|
x.MovMotor.RPM_SP_Controle = 0;
|
|
|
|
x.DirMotor.Angulo_SP = 0;
|
|
x.DirMotor.Sentido_SP = Sentido.Parado;
|
|
});
|
|
}
|
|
|
|
public List<(int, CanMessagePosicaoDados, byte[])> ProtocoloConfiguracao(bool Conectar)
|
|
{
|
|
return new List<(int, CanMessagePosicaoDados, byte[])>();
|
|
}
|
|
|
|
public void RegistrarLogMov(ModuloMvdModel Modulo)
|
|
{
|
|
Modulo.MovMotor.LogGrafico.Add(new MvdMotorMOVSensorimanetoGrafico()
|
|
{
|
|
Momento = DateTime.Now,
|
|
Modulo_ID = Modulo.Modulo_ID,
|
|
RPM_SP = Modulo.MovMotor.RPM_SP_Leitura,
|
|
RPM_Motor = Modulo.MovMotor.RPM_Motor,
|
|
RPM_Roda = Modulo.MovMotor.RPM_Roda,
|
|
Corrente = Modulo.MovMotor.Corrente_Motor,
|
|
Sentido = Modulo.MovMotor.Sentido,
|
|
Temperatura = Modulo.MovMotor.Temperatura,
|
|
TemperaturaDriver = Modulo.MovMotor.TemperaturaDriver,
|
|
Tensao = Modulo.MovMotor.Tensao,
|
|
Velocidade = Modulo.MovMotor.VelocidadeInstantanea,
|
|
Potencia = Modulo.MovMotor.Potencia,
|
|
CicloTrabalho = Modulo.MovMotor.CicloTrabalho
|
|
});
|
|
|
|
if (Modulo.MovMotor.LogGrafico.Count > 60)
|
|
{
|
|
Modulo.MovMotor.LogGrafico.RemoveAt(0);
|
|
}
|
|
}
|
|
|
|
public void IniciarRegistrador()
|
|
{
|
|
if (!(tmrRegistrador?.IsRunning ?? false))
|
|
{
|
|
LimparDados(this);
|
|
|
|
PararRegistrador();
|
|
|
|
tmrRegistrador = new AsyncTaskTimerModel("tmrRegistrador_" + T_Code.Mvd.ToString(), tmrRegistrador_Tick, _TaxaAmostragem);
|
|
tmrRegistrador.Start();
|
|
|
|
tmrRegistradorMOV = new AsyncTaskTimerModel("tmrRegistrador_" + T_Code.Mov.ToString(), tmrRegistradorMOV_Tick, OIDCanService.TaxaAmostragem);
|
|
tmrRegistradorMOV.Start();
|
|
|
|
tmrRegistradorDIR = new AsyncTaskTimerModel("tmrRegistrador_" + T_Code.Dir.ToString(), tmrRegistradorDIR_Tick, MKS057DCanService.TaxaAmostragem);
|
|
tmrRegistradorDIR.Start();
|
|
}
|
|
}
|
|
|
|
public void PararRegistrador()
|
|
{
|
|
tmrRegistrador?.Dispose();
|
|
tmrRegistradorMOV?.Dispose();
|
|
tmrRegistradorDIR?.Dispose();
|
|
}
|
|
|
|
public async Task tmrRegistrador_Tick()
|
|
{
|
|
var op = Variaveis.OperacaoEmAndamento;
|
|
tmrRegistrador.SetInterval(_TaxaAmostragem);
|
|
|
|
if (!op.Simulando)
|
|
{
|
|
VelocidadeMedia = FuncoesMatematicas.ConverteKmhParaMs(Modulos.Where(x => x.Conectado && x.MovMotor.ComandoLigado).DefaultIfEmpty().Average(x => x?.MovMotor?.VelocidadeInstantanea ?? 0));
|
|
}
|
|
|
|
var UltimaDirecao = op.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov)?.UltimaDirecao ?? Direcao.Parado;
|
|
if (UltimaDirecao != Direcao.Parado)
|
|
{
|
|
//double tempo = _TaxaAmostragem / 1000.0;
|
|
DateTime agora = DateTime.Now;
|
|
double tempo = UltimoTickRegistrador == DateTime.MinValue ? 0 : (agora - UltimoTickRegistrador).TotalSeconds;
|
|
UltimoTickRegistrador = agora;
|
|
|
|
double distancia = tempo * VelocidadeMedia;
|
|
DistanciaPercorridaTotal += distancia;
|
|
DistanciaPercorridaParcial += ((UltimaDirecao == Direcao.Frente ? 1 : UltimaDirecao == Direcao.Tras ? -1 : 0) * distancia);
|
|
DistanciaPercorridaOperacao += distancia;
|
|
TempoEmAtividade += tempo;
|
|
}
|
|
}
|
|
|
|
|
|
//private DateTime _ultimoEnvioControleMov = DateTime.MinValue;
|
|
//private DateTime _ultimoRegistroLogMov = DateTime.MinValue;
|
|
//private static readonly TimeSpan IntervaloControleMov = TimeSpan.FromSeconds(1);
|
|
//private static readonly TimeSpan IntervaloLogMov = TimeSpan.FromSeconds(1);
|
|
//private async Task tmrRegistradorMOV_Tick()
|
|
//{
|
|
// var op = Variaveis.OperacaoEmAndamento;
|
|
//
|
|
// if (Variaveis.Fechando)
|
|
// return;
|
|
//
|
|
// DateTime agora = DateTime.Now;
|
|
//
|
|
// if (!OIDCanService.Iniciado && SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Mov))
|
|
// {
|
|
// foreach (var leitura in OIDCanService.DadosLeitura.Where(x => x.UltimoComandoRecebido.AddSeconds(10) < agora))
|
|
// {
|
|
// OIDCanService.RequisitarDado(
|
|
// leitura.EnderecoTx,
|
|
// leitura.EnderecoRx,
|
|
// OIDCanService.OidHandler.OidParametros.CodErro
|
|
// );
|
|
// }
|
|
//
|
|
// tmrRegistradorMOV.SetInterval(3000);
|
|
// return;
|
|
// }
|
|
//
|
|
// bool deveEnviarControle = _ultimoEnvioControleMov == DateTime.MinValue || agora - _ultimoEnvioControleMov >= IntervaloControleMov;
|
|
//
|
|
// bool deveRegistrarLog = _ultimoRegistroLogMov == DateTime.MinValue || agora - _ultimoRegistroLogMov >= IntervaloLogMov;
|
|
//
|
|
// bool enviouControle = false;
|
|
// bool registrouLog = false;
|
|
//
|
|
// var controleMov = deveEnviarControle ? op.Controle.TiposControle?.FirstOrDefault(x => x.Tipo == T_Code.Mov) : null;
|
|
//
|
|
// foreach (var modulo in Modulos)
|
|
// {
|
|
// if (!modulo.MovMotor.Inicializado)
|
|
// continue;
|
|
//
|
|
// byte addrTx = modulo.MovMotor._EnderecoCAN_Tx;
|
|
// byte addrRx = modulo.MovMotor._EnderecoCAN_Rx;
|
|
//
|
|
// /*
|
|
// * Esse continua em todo tick.
|
|
// * O OIDCanService já segura throttle, pendência e rodízio.
|
|
// */
|
|
// OIDCanService.RequisitarProximoDado(addrTx, addrRx);
|
|
//
|
|
// /*
|
|
// * Desligado por enquanto para aliviar CAN.
|
|
// */
|
|
// // modulo.MovMotor.RequisitarDadosSensoresExternos();
|
|
//
|
|
// /*
|
|
// * Controle só a cada 1s.
|
|
// * Se o EnviarComandoControle já tiver dedupe interno, melhor ainda.
|
|
// */
|
|
// if (deveEnviarControle && controleMov != null)
|
|
// {
|
|
// modulo.MovMotor.EnviarComandoControle(controleMov.UltimaDirecao);
|
|
// enviouControle = true;
|
|
// }
|
|
//
|
|
// /*
|
|
// * Essa leitura é local, pode deixar no tick.
|
|
// */
|
|
// modulo.MovMotor.ConfigFreio.Leitura = modulo.MovMotor.Leitura?.Freado ?? false;
|
|
//
|
|
// /*
|
|
// * Log só a cada 1s para não virar serragem de JSON.
|
|
// */
|
|
// if (deveRegistrarLog)
|
|
// {
|
|
// op.DispMvd.Dados.RegistrarLogMov(modulo);
|
|
// registrouLog = true;
|
|
// }
|
|
// }
|
|
//
|
|
// if (enviouControle)
|
|
// _ultimoEnvioControleMov = agora;
|
|
//
|
|
// if (registrouLog)
|
|
// _ultimoRegistroLogMov = agora;
|
|
//
|
|
// tmrRegistradorMOV.SetInterval(OIDCanService.TaxaAmostragem);
|
|
//
|
|
// await Task.CompletedTask;
|
|
//}
|
|
private DateTime _ultimoEnvioControleMov = DateTime.MinValue;
|
|
private DateTime _ultimoRegistroLogMov = DateTime.MinValue;
|
|
private static readonly TimeSpan IntervaloControleMov = TimeSpan.FromSeconds(1);
|
|
private static readonly TimeSpan IntervaloLogMov = TimeSpan.FromSeconds(1);
|
|
private async Task tmrRegistradorMOV_Tick()
|
|
{
|
|
var op = Variaveis.OperacaoEmAndamento;
|
|
|
|
if (Variaveis.Fechando)
|
|
return;
|
|
|
|
DateTime agora = DateTime.Now;
|
|
|
|
if (!OIDCanService.Iniciado && SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Mov))
|
|
{
|
|
foreach (var leitura in OIDCanService.DadosLeitura.Where(x => x.UltimoComandoRecebido.AddSeconds(10) < agora))
|
|
{
|
|
OIDCanService.RequisitarDado(
|
|
leitura.EnderecoTx,
|
|
leitura.EnderecoRx,
|
|
OIDCanService.OidHandler.OidParametros.CodErro
|
|
);
|
|
}
|
|
|
|
tmrRegistradorMOV.SetInterval(3000);
|
|
return;
|
|
}
|
|
|
|
bool deveEnviarControle =
|
|
_ultimoEnvioControleMov == DateTime.MinValue ||
|
|
agora - _ultimoEnvioControleMov >= IntervaloControleMov;
|
|
|
|
bool deveRegistrarLog =
|
|
_ultimoRegistroLogMov == DateTime.MinValue ||
|
|
agora - _ultimoRegistroLogMov >= IntervaloLogMov;
|
|
|
|
bool enviouControle = false;
|
|
bool registrouLog = false;
|
|
|
|
var controleMov = deveEnviarControle ? op.Controle.TiposControle?.FirstOrDefault(x => x.Tipo == T_Code.Mov) : null;
|
|
|
|
/*
|
|
* Uma única tentativa global por tick.
|
|
* O OIDCanService escolhe o driver e o parâmetro mais adequado.
|
|
*/
|
|
OIDCanService.AtualizarDados();
|
|
|
|
foreach (var modulo in Modulos)
|
|
{
|
|
if (!modulo.MovMotor.Inicializado)
|
|
continue;
|
|
|
|
/*
|
|
* Não chamar RequisitarProximoDado aqui.
|
|
* O polling agora é centralizado em AtualizarDados().
|
|
*/
|
|
|
|
if (deveEnviarControle && controleMov != null)
|
|
{
|
|
modulo.MovMotor.EnviarComandoControle(controleMov.UltimaDirecao);
|
|
|
|
enviouControle = true;
|
|
}
|
|
|
|
modulo.MovMotor.ConfigFreio.Leitura = modulo.MovMotor.Leitura?.Freado ?? false;
|
|
|
|
if (deveRegistrarLog)
|
|
{
|
|
op.DispMvd.Dados.RegistrarLogMov(modulo);
|
|
registrouLog = true;
|
|
}
|
|
}
|
|
|
|
if (enviouControle)
|
|
_ultimoEnvioControleMov = agora;
|
|
|
|
if (registrouLog)
|
|
_ultimoRegistroLogMov = agora;
|
|
|
|
tmrRegistradorMOV.SetInterval(OIDCanService.TaxaAmostragem);
|
|
|
|
await Task.CompletedTask;
|
|
}
|
|
|
|
|
|
private DateTime _ultimoEnvioControleDir = DateTime.MinValue;
|
|
private DateTime _ultimoSensoresExternosDir = DateTime.MinValue;
|
|
private static readonly TimeSpan IntervaloControleDir = TimeSpan.FromMilliseconds(250);
|
|
private static readonly TimeSpan IntervaloSensoresExternosDir = TimeSpan.FromMilliseconds(500);
|
|
private async Task tmrRegistradorDIR_Tick()
|
|
{
|
|
var op = Variaveis.OperacaoEmAndamento;
|
|
|
|
if (Variaveis.Fechando)
|
|
return;
|
|
|
|
DateTime agora = DateTime.Now;
|
|
|
|
if (!MKS057DCanService.Iniciado && SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Dir))
|
|
{
|
|
foreach (var leitura in MKS057DCanService.DadosLeitura.Where(x => x.UltimoComandoRecebido.AddSeconds(10) < agora))
|
|
{
|
|
/*
|
|
* Poke leve para tentar recuperar leitura.
|
|
* O MKS057DCanService agora já segura throttle interno.
|
|
*/
|
|
MKS057DCanService.RequisitarDado(
|
|
leitura.EnderecoTx,
|
|
leitura.EnderecoRx,
|
|
MKS057DCanService.MksHandler.MksFuncCode.PulsosRecebidos
|
|
);
|
|
}
|
|
|
|
tmrRegistradorDIR.SetInterval(1000);
|
|
await Task.CompletedTask;
|
|
return;
|
|
}
|
|
|
|
bool deveEnviarControle = _ultimoEnvioControleDir == DateTime.MinValue || agora - _ultimoEnvioControleDir >= IntervaloControleDir;
|
|
|
|
bool deveRequisitarSensoresExternos = _ultimoSensoresExternosDir == DateTime.MinValue || agora - _ultimoSensoresExternosDir >= IntervaloSensoresExternosDir;
|
|
|
|
bool enviouControle = false;
|
|
bool requisitouSensoresExternos = false;
|
|
|
|
var controleDir = deveEnviarControle ? op.Controle.TiposControle?.FirstOrDefault(x => x.Tipo == T_Code.Dir) : null;
|
|
|
|
foreach (var modulo in Modulos)
|
|
{
|
|
if (modulo?.DirMotor == null || !modulo.DirMotor.Inicializado)
|
|
continue;
|
|
|
|
byte addrTx = modulo.DirMotor._EnderecoCAN_Tx;
|
|
byte addrRx = modulo.DirMotor._EnderecoCAN_Rx;
|
|
|
|
/*
|
|
* Agora é igual ao MOV/OID:
|
|
* o service escolhe PulsosRecebidos, IO, RPM, ErroAcumulado etc.
|
|
* com throttle, cursor e prioridade de referenciamento.
|
|
*/
|
|
MKS057DCanService.RequisitarProximoDado(addrTx, addrRx);
|
|
|
|
/*
|
|
* Se isso também gera CAN, melhor não chamar em todo tick.
|
|
* Se for leitura local/barata, pode voltar para todo tick.
|
|
*/
|
|
if (deveRequisitarSensoresExternos)
|
|
{
|
|
modulo.DirMotor.RequisitarDadosSensoresExternos();
|
|
requisitouSensoresExternos = true;
|
|
}
|
|
|
|
/*
|
|
* Reenvio de controle direcional.
|
|
*
|
|
* Não precisa mais reenviar no ritmo da TaxaAmostragem.
|
|
* O MKS057DCanService já tem dedupe curto, mas ainda assim
|
|
* é melhor não transformar posição em metralhadora CAN.
|
|
*/
|
|
if (!MKS057DCanService.Referenciando && deveEnviarControle && controleDir != null && !modulo.DirMotor.AtingiuAnguloSP)
|
|
{
|
|
modulo.DirMotor.EnviarComandoControle(controleDir.UltimaDirecao);
|
|
enviouControle = true;
|
|
}
|
|
|
|
modulo.DirMotor.AtualizarSaudeSeguimentoAngular(agora);
|
|
}
|
|
|
|
if (enviouControle)
|
|
_ultimoEnvioControleDir = agora;
|
|
|
|
if (requisitouSensoresExternos)
|
|
_ultimoSensoresExternosDir = agora;
|
|
|
|
tmrRegistradorDIR.SetInterval(MKS057DCanService.TaxaAmostragem);
|
|
|
|
await Task.CompletedTask;
|
|
}
|
|
|
|
public void AtualizarDadosSensoresExternos(S_Code componente, int id_num)
|
|
{
|
|
switch (componente)
|
|
{
|
|
case S_Code.sNTC:
|
|
{
|
|
var mod = Modulos.FirstOrDefault(x => x.MovMotor.SensorTemperaturaMotor?.ID_Num == id_num);
|
|
if (mod != null)
|
|
mod.MovMotor.AtualizarDadosSensoresExternos();
|
|
break;
|
|
}
|
|
case S_Code.sMAG:
|
|
{
|
|
var mod = Modulos.FirstOrDefault(x => x.DirMotor.SensorAnguloReal?.ID_Num == id_num);
|
|
if (mod != null)
|
|
mod.DirMotor.AtualizarDadosSensoresExternos();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public async Task ExecutarMovimentoDirecionalCombinado(Direcao DirecaoAtual)
|
|
{
|
|
var op = Variaveis.OperacaoEmAndamento;
|
|
|
|
if (DirecaoAtual == Direcao.Parado)
|
|
{
|
|
foreach (var Modulo in Modulos)
|
|
{
|
|
Modulo.MovMotor.EnviarComandoControle(Direcao.Parado);
|
|
}
|
|
|
|
await Task.Delay(1000);
|
|
}
|
|
|
|
switch (op.Controle.TipoMovimento)
|
|
{
|
|
case TipoMovimentoDirecional.RotacionarNoEixo:
|
|
case TipoMovimentoDirecional.MovimentoLateral:
|
|
|
|
foreach (var Modulo in Modulos.Where(x => x.DirMotor.Inicializado && !x.DirMotor.PosicaoTipoMovimentoConcluido(DirecaoAtual)))
|
|
{
|
|
Modulo.DirMotor.EnviarComandoControle(DirecaoAtual);
|
|
}
|
|
|
|
DateTime Agora = DateTime.Now;
|
|
bool Sucesso = Modulos.All(x => x.DirMotor.PosicaoTipoMovimentoConcluido(DirecaoAtual));
|
|
while (Agora.AddMilliseconds(5000) > DateTime.Now && !Sucesso)
|
|
{
|
|
await Task.Delay(100);
|
|
Sucesso = Modulos.All(x => x.DirMotor.PosicaoTipoMovimentoConcluido(DirecaoAtual));
|
|
}
|
|
|
|
if (Sucesso && DirecaoAtual != Direcao.Parado)
|
|
{
|
|
op.Controle.PercentualVelocidadeSP = 20;
|
|
foreach (var Modulo in Modulos)
|
|
{
|
|
Modulo.MovMotor.EnviarComandoControle(
|
|
DirecaoAtual == Direcao.Direita ? Direcao.Frente :
|
|
DirecaoAtual == Direcao.Esquerda ? Direcao.Tras :
|
|
Direcao.Parado
|
|
);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
public async Task<bool> RealizarReferenciamentoDirecional(List<string> ModsReferenciar = null)
|
|
{
|
|
if (!MKS057DCanService.Referenciando)
|
|
{
|
|
var op = Variaveis.OperacaoEmAndamento;
|
|
|
|
TipoMovimentoDirecional tipoControle = op.Controle.TipoMovimento;
|
|
|
|
op.DefinirTipoMovimentoControle(TipoMovimentoDirecional.Diagnostico);
|
|
var ModsRef = Modulos.Where(x => x.DirMotor.Comandar && x.DirMotor.Inicializado && (ModsReferenciar != null ? ModsReferenciar.Contains(x.DirMotor.Mod_ID) : true)).ToList();
|
|
foreach (var Modulo in ModsRef)
|
|
{
|
|
Task.Run(async () => await Modulo.DirMotor.ReferenciaMotor());
|
|
}
|
|
|
|
bool ReferenciamentoConcluido() => !MKS057DCanService.Referenciando;
|
|
await FuncoesGlobais.AguardarCondicaoAsync(ReferenciamentoConcluido, 2 * 1000 * 60, 1000);
|
|
op.DefinirTipoMovimentoControle(tipoControle);
|
|
}
|
|
|
|
return Modulos.All(x => x.DirMotor.Referenciado);
|
|
}
|
|
|
|
public List<Task> RealizarCalibragemMovAsync(bool forcar)
|
|
{
|
|
var op = Variaveis.OperacaoEmAndamento;
|
|
|
|
List<Task> tasks = new List<Task>();
|
|
var DispMvd = op.DispMvd;
|
|
if (DispMvd != null)
|
|
{
|
|
var mc = op.Sensoriamento.Operacao.ModsCalibragem;
|
|
if (!mc.ContainsKey(T_Code.Mov))
|
|
mc.Add(T_Code.Mov, new Dictionary<string, bool>());
|
|
var calMov = mc[T_Code.Mov];
|
|
foreach (var Modulo in DispMvd.Dados.Modulos)
|
|
{
|
|
calMov.TryGetValue(Modulo.Modulo_ID, out var cal);
|
|
if (!forcar && cal && calMov[Modulo.Modulo_ID]) continue;
|
|
|
|
bool ok = Modulo.MovMotor?.Inicializado == true;
|
|
|
|
op.MarcarModuloCalibrado(T_Code.Mov, Modulo.Modulo_ID, ok);
|
|
|
|
if (!ok)
|
|
{
|
|
Variaveis.MostrarLog($"[MovimentacaoUnificadaModel] [RealizarCalibragemMovAsync] MOV {Modulo.Modulo_ID} não inicializado.");
|
|
op.Sensoriamento.InserirLog(T_Code.Mov, StatusModulo.Alerta, 50, $"MOV {Modulo.Modulo_ID} não inicializado.", id: Modulo.Modulo_ID);
|
|
}
|
|
}
|
|
|
|
DispMvd.Dados.MovPronto = DispMvd.Dados.Modulos.All(x => x.MovMotor.Inicializado);
|
|
}
|
|
return tasks;
|
|
}
|
|
|
|
public List<Task> RealizarCalibragemDirAsync(bool forcar)
|
|
{
|
|
var op = Variaveis.OperacaoEmAndamento;
|
|
|
|
List<Task> tasks = new List<Task>();
|
|
|
|
var dispMvd = op?.DispMvd;
|
|
|
|
if (dispMvd?.Dados?.Modulos == null)
|
|
return tasks;
|
|
|
|
dispMvd.Dados.DirPronto = dispMvd.Dados.Modulos.All(x => x.DirMotor.Inicializado);
|
|
|
|
var modsRef = dispMvd.Dados.Modulos
|
|
.ToList();
|
|
|
|
foreach (var modulo in modsRef)
|
|
{
|
|
if (!forcar && op.ModuloEstaCalibrado(T_Code.Dir, modulo.Modulo_ID))
|
|
continue;
|
|
|
|
op.MarcarModuloCalibrado(T_Code.Dir, modulo.Modulo_ID, false);
|
|
|
|
if (!modulo.DirMotor.Inicializado)
|
|
{
|
|
Variaveis.MostrarLog($"[MovimentacaoUnificadaModel] [RealizarCalibragemDirAsync] DIR {modulo.Modulo_ID} não inicializado.");
|
|
op.Sensoriamento.InserirLog(T_Code.Dir, StatusModulo.Alerta, 50, $"DIR {modulo.Modulo_ID} não inicializado.", id: modulo.Modulo_ID);
|
|
continue;
|
|
}
|
|
|
|
op.DefinirTipoMovimentoControle(TipoMovimentoDirecional.Diagnostico);
|
|
|
|
tasks.Add(Task.Run(async () =>
|
|
{
|
|
try
|
|
{
|
|
await modulo.DirMotor.ReferenciaMotor();
|
|
|
|
op.MarcarModuloCalibrado(T_Code.Dir, modulo.Modulo_ID, true);
|
|
|
|
Variaveis.MostrarLog($"[MovimentacaoUnificadaModel] [RealizarCalibragemDirAsync] Referenciamento do módulo {modulo.Modulo_ID} concluído com sucesso!");
|
|
op.Sensoriamento.InserirLog(T_Code.Dir, StatusModulo.Operante, 100, $"Referenciamento do módulo {modulo.Modulo_ID} concluído com sucesso!", id: modulo.Modulo_ID);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
op.MarcarModuloCalibrado(T_Code.Dir, modulo.Modulo_ID, false);
|
|
|
|
Variaveis.MostrarLog($"[MovimentacaoUnificadaModel] [RealizarCalibragemDirAsync] Erro no referenciamento do módulo {modulo.Modulo_ID}: {ex.Message}");
|
|
op.Sensoriamento.InserirLog(T_Code.Dir, StatusModulo.Falha, 0, $"Erro no referenciamento do módulo {modulo.Modulo_ID}: {ex.Message}", id: modulo.Modulo_ID);
|
|
}
|
|
}));
|
|
}
|
|
|
|
return tasks;
|
|
}
|
|
|
|
public void AtualizarDadosFreio()
|
|
{
|
|
foreach (var Mod in Modulos)
|
|
{
|
|
Mod.MovMotor?.ConfigFreio?.AtualizarDados();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public class ModuloMvdModel
|
|
{
|
|
public string Modulo_ID { get; set; }
|
|
public bool Disponivel { get; set; }
|
|
public bool RequisitarDados { get; set; } = false;
|
|
|
|
public bool Conectado
|
|
{
|
|
get
|
|
{
|
|
return MovMotor.Inicializado || DirMotor.Inicializado;
|
|
}
|
|
}
|
|
|
|
public MovimentacaoModel MovMotor { get; set; }
|
|
public DirecionalModel DirMotor { get; set; }
|
|
|
|
public static PinoutDataModel Pinout { get; set; }
|
|
public static List<FuncoesPinout> Funcoes { get; set; } = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.TX,
|
|
FuncoesPinout.RX,
|
|
FuncoesPinout.ModbusDI,
|
|
FuncoesPinout.ModbusRO,
|
|
FuncoesPinout.ModbusDE_RE
|
|
};
|
|
|
|
}
|
|
|
|
}
|