melhoria na saude do atuador, bicos com ou sem movimento
This commit is contained in:
parent
64fce863d5
commit
c9f3bd69d7
|
|
@ -135,7 +135,7 @@ namespace AgroBase.Forms
|
|||
* Hoje pode ficar comentado se UDP não for usado no rover,
|
||||
* mas o método fica aqui no lugar certo do lifecycle.
|
||||
*/
|
||||
Variaveis.IniciarUDP();
|
||||
//Variaveis.IniciarUDP();
|
||||
|
||||
APIService.IniciarRotinas();
|
||||
VersionamentoService.IniciarRotinas();
|
||||
|
|
|
|||
|
|
@ -764,7 +764,7 @@ namespace AgroBase.Models.Modules
|
|||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 2,
|
||||
analise_health = true,
|
||||
maximo = 100,
|
||||
maximo = 120,
|
||||
minimo = 0,
|
||||
nominal = 0,
|
||||
unidade_medida = "mL/s"
|
||||
|
|
@ -1181,6 +1181,7 @@ namespace AgroBase.Models.Modules
|
|||
Componente = S_Code.sBIC,
|
||||
Posicao = posicao,
|
||||
Inicializado = false,
|
||||
ComMovimento = false,
|
||||
AnguloNeutro = 90,
|
||||
AnguloControle = 90,
|
||||
AnguloAbertura = 30,
|
||||
|
|
@ -2074,6 +2075,7 @@ namespace AgroBase.Models.Modules
|
|||
public int Posicao { get; set; }
|
||||
public S_Code Componente { get; set; } = S_Code.sBIC;
|
||||
public bool AtuacaoNivelAlto { get; set; }
|
||||
public bool ComMovimento { get; set; }
|
||||
public double AnguloNeutro { get; set; }
|
||||
public double AnguloControle { get; set; }
|
||||
public double AnguloAbertura { get; set; }
|
||||
|
|
@ -2250,8 +2252,12 @@ namespace AgroBase.Models.Modules
|
|||
AtuacaoNivelAlto = AtuacaoNivelAlto,
|
||||
Atuacoes = Atuacoes,
|
||||
ComandoAtuar = ComandoAtuar,
|
||||
ComMovimento = ComMovimento,
|
||||
AnguloAbertura = AnguloAbertura,
|
||||
AnguloControle = AnguloControle,
|
||||
UltimoAnguloDesejado = UltimoAnguloDesejado,
|
||||
UltimoComandoEnviado = UltimoComandoEnviado,
|
||||
UltimoStatusDesejado = UltimoStatusDesejado,
|
||||
Inicializado = Inicializado,
|
||||
Mandatorio = Mandatorio,
|
||||
Componente = Componente,
|
||||
|
|
|
|||
|
|
@ -602,9 +602,9 @@ namespace AgroBase.Models.Modules
|
|||
posicao = CanMessagePosicaoDados.Dados1,
|
||||
indice = 1,
|
||||
analise_health = true,
|
||||
maximo = 2200,
|
||||
minimo = 1000,
|
||||
nominal = 1700,
|
||||
maximo = 2500,
|
||||
minimo = 400,
|
||||
nominal = 700,
|
||||
unidade_medida = "mA"
|
||||
},
|
||||
new SensorValoresLeituraModel()
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ using System.Drawing;
|
|||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -30,15 +29,16 @@ namespace AgroBase.Models
|
|||
{
|
||||
get
|
||||
{
|
||||
return tmrLogs.Interval;
|
||||
return _tmrLogsOperacao.Interval;
|
||||
}
|
||||
set
|
||||
{
|
||||
tmrLogs.SetInterval((int)value);
|
||||
_tmrLogsOperacao.SetInterval((int)value);
|
||||
}
|
||||
}
|
||||
private static AsyncTaskTimerModel tmrLogs;
|
||||
private AsyncTaskTimerModel _tmrLogsOperacao;
|
||||
private int idxLog = 0;
|
||||
private readonly SemaphoreSlim _salvarLogsGate = new SemaphoreSlim(1, 1);
|
||||
public double tmrLeiturasInterval
|
||||
{
|
||||
get
|
||||
|
|
@ -55,8 +55,13 @@ namespace AgroBase.Models
|
|||
|
||||
public OperacaoModel()
|
||||
{
|
||||
tmrLogs?.Dispose();
|
||||
tmrLogs = new AsyncTaskTimerModel("tmrLogs", tmrLogs_Tick, 1000);
|
||||
Variaveis.MostrarLog("[OperacaoModel.ctor] StackTrace: " + Environment.StackTrace);
|
||||
|
||||
Variaveis.MostrarLog(
|
||||
$"[OperacaoModel.ctor] Nova instância. Hash={GetHashCode()}, " +
|
||||
$"OperacaoAtual={Variaveis.OperacaoEmAndamento?.ID}, " +
|
||||
$"HashAtual={Variaveis.OperacaoEmAndamento?.GetHashCode()}"
|
||||
);
|
||||
|
||||
tmrLeituras?.Dispose();
|
||||
tmrLeituras = new AsyncTaskTimerModel("tmrLeitura", tmrLeituras_Tick, 500);
|
||||
|
|
@ -200,8 +205,6 @@ namespace AgroBase.Models
|
|||
|
||||
if (CarregarModulos)
|
||||
{
|
||||
tmrLogs?.Stop();
|
||||
|
||||
var SenConectado = (DispositivosService<SensoriamentoModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Sen);
|
||||
var AtuConectado = (DispositivosService<AtuadorModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Atu);
|
||||
var MvdConectado = (DispositivosService<MovimentacaoUnificadaModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Mvd);
|
||||
|
|
@ -1059,7 +1062,7 @@ namespace AgroBase.Models
|
|||
|
||||
op.Sensoriamento.UltimoRegistroLog = agora;
|
||||
op.idxLog = 0;
|
||||
tmrLogs?.Start();
|
||||
op.IniciarTimerLogsOperacao();
|
||||
|
||||
await op.RealizarCalibragemInicialAsync(true);
|
||||
|
||||
|
|
@ -1087,9 +1090,9 @@ namespace AgroBase.Models
|
|||
|
||||
op.Sensoriamento.Operacao.DataFim = DateTime.Now;
|
||||
|
||||
tmrLogs?.Stop();
|
||||
op.PararTimerLogsOperacao();
|
||||
|
||||
op.SalvarLogs(false);
|
||||
op.SalvarLogs(true);
|
||||
|
||||
op.Sensoriamento.Operacao.Finalizando = false;
|
||||
op.Trajetoria?.AutonomiaCorredor?.Parar();
|
||||
|
|
@ -1194,6 +1197,33 @@ namespace AgroBase.Models
|
|||
}
|
||||
|
||||
|
||||
private void IniciarTimerLogsOperacao()
|
||||
{
|
||||
_tmrLogsOperacao?.Stop();
|
||||
_tmrLogsOperacao?.Dispose();
|
||||
|
||||
_tmrLogsOperacao = new AsyncTaskTimerModel($"tmrLogs_{ID}", tmrLogs_Tick, 1000);
|
||||
|
||||
_tmrLogsOperacao.Start();
|
||||
|
||||
Variaveis.MostrarLog($"[OperacaoModel.IniciarTimerLogsOperacao] Timer de logs iniciado. Operacao={ID}, Hash={GetHashCode()}");
|
||||
}
|
||||
|
||||
private void PararTimerLogsOperacao()
|
||||
{
|
||||
try
|
||||
{
|
||||
_tmrLogsOperacao?.Stop();
|
||||
|
||||
Variaveis.MostrarLog($"[OperacaoModel.PararTimerLogsOperacao] Timer de logs parado. Operacao={ID}, Hash={GetHashCode()}, idxLog={idxLog}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Variaveis.MostrarLog("[OperacaoModel.PararTimerLogsOperacao] Erro ao parar timer de logs: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static string DeserializarDadosOperacao(string caminho, string arquivo)
|
||||
{
|
||||
string pastaBase = Path.GetDirectoryName(caminho) ?? "";
|
||||
|
|
@ -2628,7 +2658,24 @@ namespace AgroBase.Models
|
|||
{
|
||||
var op = this;
|
||||
|
||||
if (op.Sensoriamento.Operacao.OperacaoIniciada)
|
||||
if (!ReferenceEquals(Variaveis.OperacaoEmAndamento, op))
|
||||
{
|
||||
Variaveis.MostrarLog($"[OperacaoModel.tmrLogs_Tick] Timer órfão parado. TimerHash={GetHashCode()}, OperacaoTimer={ID}, OperacaoAtual={Variaveis.OperacaoEmAndamento?.ID}");
|
||||
|
||||
PararTimerLogsOperacao();
|
||||
return;
|
||||
}
|
||||
|
||||
if (op.Sensoriamento?.Operacao?.OperacaoIniciada != true)
|
||||
return;
|
||||
|
||||
if (!await _salvarLogsGate.WaitAsync(0))
|
||||
{
|
||||
Variaveis.MostrarLog($"[OperacaoModel.tmrLogs_Tick] Tick ignorado porque SalvarLogs ainda está em execução. Operacao={ID}, idxLog={idxLog}");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
op.SalvarLogs(false);
|
||||
|
||||
|
|
@ -2639,9 +2686,13 @@ namespace AgroBase.Models
|
|||
|
||||
if (op.idxLog % 5 == 0 && !op.Sensoriamento.Operacao.Calibrando)
|
||||
{
|
||||
Task.Run(async () => await op.RealizarCalibragemInicialAsync(false));
|
||||
_ = Task.Run(async () => await op.RealizarCalibragemInicialAsync(false));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_salvarLogsGate.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public void SalvarLogs(bool Fim)
|
||||
|
|
@ -3594,6 +3645,7 @@ namespace AgroBase.Models
|
|||
Atuacoes = bico.Atuacoes,
|
||||
TempoAtuado = bico.TempoAtuado,
|
||||
AnguloAbertura = bico.AnguloAbertura,
|
||||
ComMovimento = bico.ComMovimento,
|
||||
AnguloControle = bico.AnguloControle
|
||||
}).ToList()
|
||||
};
|
||||
|
|
@ -4649,7 +4701,7 @@ namespace AgroBase.Models
|
|||
DadosPerformance = dadosPerformance,
|
||||
LivoxLidar = dadosLivox,
|
||||
CoolerControl = dadosCooler,
|
||||
Logs = Logs != null ? Logs.Where(x => x?.Momento >= ultimoRegistroLog).ToList() : new List<OperacaoSensoriamentoLogErrosModel>(),
|
||||
Logs = Logs != null ? Logs.Where(x => x != null && x.Momento > ultimoRegistroLog).ToList() : new List<OperacaoSensoriamentoLogErrosModel>(),
|
||||
UltimoRegistroLog = ultimoRegistroLog,
|
||||
};
|
||||
|
||||
|
|
@ -5108,6 +5160,7 @@ namespace AgroBase.Models
|
|||
public int Atuacoes { get; set; }
|
||||
public double TempoAtuado { get; set; }
|
||||
public double AnguloAbertura { get; set; }
|
||||
public bool ComMovimento { get; set; }
|
||||
public double AnguloControle { get; set; }
|
||||
|
||||
public AtuadorBicoLogModel Clone()
|
||||
|
|
@ -5124,6 +5177,7 @@ namespace AgroBase.Models
|
|||
Atuacoes = Atuacoes,
|
||||
TempoAtuado = TempoAtuado,
|
||||
AnguloAbertura = AnguloAbertura,
|
||||
ComMovimento = ComMovimento,
|
||||
AnguloControle = AnguloControle
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -610,8 +610,7 @@ namespace AgroBase.Services
|
|||
return;
|
||||
}
|
||||
|
||||
var agitador =
|
||||
op?.DispAtu?.Dados?.AgitadorDeCalda;
|
||||
var agitador = op?.DispAtu?.Dados?.AgitadorDeCalda;
|
||||
|
||||
if (!(agitador?.Inicializado ?? false))
|
||||
return;
|
||||
|
|
@ -634,32 +633,20 @@ namespace AgroBase.Services
|
|||
!operacaoConcluida &&
|
||||
PulverizadorLiberado;
|
||||
|
||||
bool bicosAtuando =
|
||||
op.DispAtu?.Dados?.BicosPulverizadores?
|
||||
.Any(x =>
|
||||
x.Comandar &&
|
||||
x.ComandoAtuar)
|
||||
?? false;
|
||||
bool bicosAtuando = op.DispAtu?.Dados?.BicosPulverizadores?.Any(x => x.Comandar && x.ComandoAtuar) ?? false;
|
||||
|
||||
double potenciaFinal = 0;
|
||||
DateTime agora = DateTime.Now;
|
||||
|
||||
if (
|
||||
operacaoAtiva &&
|
||||
!_agitadorOperacaoAtivaAnterior
|
||||
)
|
||||
if (operacaoAtiva && !_agitadorOperacaoAtivaAnterior)
|
||||
{
|
||||
_agitadorBoostAte =
|
||||
agora.AddMilliseconds(
|
||||
AtuAgitadorBoostRetomadaMs
|
||||
);
|
||||
_agitadorBoostAte = agora.AddMilliseconds(AtuAgitadorBoostRetomadaMs);
|
||||
|
||||
_agitadorUltimaTroca = agora;
|
||||
_agitadorIntermitenteLigado = true;
|
||||
}
|
||||
|
||||
bool emBoost =
|
||||
agora < _agitadorBoostAte;
|
||||
bool emBoost = agora < _agitadorBoostAte;
|
||||
|
||||
switch (modo)
|
||||
{
|
||||
|
|
@ -672,18 +659,15 @@ namespace AgroBase.Services
|
|||
{
|
||||
if (emBoost)
|
||||
{
|
||||
potenciaFinal =
|
||||
AtuAgitadorPotenciaBoost;
|
||||
potenciaFinal = AtuAgitadorPotenciaBoost;
|
||||
}
|
||||
else if (bicosAtuando)
|
||||
{
|
||||
potenciaFinal =
|
||||
AtuAgitadorPotenciaContinua;
|
||||
potenciaFinal = AtuAgitadorPotenciaContinua;
|
||||
}
|
||||
else
|
||||
{
|
||||
potenciaFinal =
|
||||
AtuAgitadorPotenciaManutencao;
|
||||
potenciaFinal = AtuAgitadorPotenciaManutencao;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -697,44 +681,27 @@ namespace AgroBase.Services
|
|||
}
|
||||
else if (emBoost)
|
||||
{
|
||||
potenciaFinal =
|
||||
AtuAgitadorPotenciaBoost;
|
||||
potenciaFinal = AtuAgitadorPotenciaBoost;
|
||||
}
|
||||
else
|
||||
{
|
||||
int tempoAtualMs =
|
||||
_agitadorIntermitenteLigado
|
||||
? AtuAgitadorTempoLigadoMs
|
||||
: AtuAgitadorTempoDesligadoMs;
|
||||
int tempoAtualMs = _agitadorIntermitenteLigado ? AtuAgitadorTempoLigadoMs : AtuAgitadorTempoDesligadoMs;
|
||||
|
||||
if (
|
||||
(agora - _agitadorUltimaTroca)
|
||||
.TotalMilliseconds >=
|
||||
tempoAtualMs
|
||||
)
|
||||
if ((agora - _agitadorUltimaTroca).TotalMilliseconds >= tempoAtualMs)
|
||||
{
|
||||
_agitadorIntermitenteLigado =
|
||||
!_agitadorIntermitenteLigado;
|
||||
_agitadorIntermitenteLigado = !_agitadorIntermitenteLigado;
|
||||
|
||||
_agitadorUltimaTroca = agora;
|
||||
}
|
||||
|
||||
potenciaFinal =
|
||||
_agitadorIntermitenteLigado
|
||||
? AtuAgitadorPotenciaIntermitente
|
||||
: 0;
|
||||
potenciaFinal = _agitadorIntermitenteLigado ? AtuAgitadorPotenciaIntermitente : 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
potenciaFinal =
|
||||
Math.Min(
|
||||
potenciaFinal,
|
||||
PotenciaLimitePorNivel(PercentualAtual)
|
||||
);
|
||||
potenciaFinal = Math.Min(potenciaFinal, PotenciaLimitePorNivel(PercentualAtual));
|
||||
|
||||
potenciaFinal =
|
||||
Clamp(potenciaFinal, 0, 100);
|
||||
potenciaFinal = Clamp(potenciaFinal, 0, 100);
|
||||
|
||||
/*
|
||||
* Este método é a fonte de verdade do agitador.
|
||||
|
|
@ -742,12 +709,9 @@ namespace AgroBase.Services
|
|||
agitador.PotenciaSP = potenciaFinal;
|
||||
agitador.PressaoSP = -1;
|
||||
|
||||
agitador.ComandoAtuar =
|
||||
agitador.Comandar &&
|
||||
potenciaFinal > 0;
|
||||
agitador.ComandoAtuar = agitador.Comandar && potenciaFinal > 0;
|
||||
|
||||
_agitadorOperacaoAtivaAnterior =
|
||||
operacaoAtiva;
|
||||
_agitadorOperacaoAtivaAnterior = operacaoAtiva;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -969,6 +969,7 @@ namespace AgroBase.Services.Operadores
|
|||
estado_leitura = bico._EstadoLeitura,
|
||||
angulo_leitura = bico._AnguloBicoLeitura,
|
||||
|
||||
com_movimento = bico.ComMovimento,
|
||||
angulo_neutro = bico.AnguloNeutro,
|
||||
angulo_controle = bico.AnguloControle,
|
||||
angulo_abertura = bico.AnguloAbertura,
|
||||
|
|
|
|||
|
|
@ -57,54 +57,121 @@ public sealed class UdpReliableChannel : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
public void Start(int localPort)
|
||||
public bool Start(int localPort)
|
||||
{
|
||||
if (_udp != null) return;
|
||||
lock (_sockLock)
|
||||
{
|
||||
if (_udp != null || _running || _stopping)
|
||||
return true;
|
||||
|
||||
_seqTx = 0; // opcional
|
||||
_lastSeqRx = 0; // importante
|
||||
_running = true;
|
||||
try
|
||||
{
|
||||
_seqTx = 0;
|
||||
_lastSeqRx = 0;
|
||||
_running = true;
|
||||
_stopping = false;
|
||||
|
||||
_udp = new UdpClient(localPort);
|
||||
_udp.Client.ReceiveBufferSize = 1 << 20;
|
||||
_udp.Client.SendBufferSize = 1 << 20;
|
||||
_udp = new UdpClient(localPort);
|
||||
_udp.Client.ReceiveBufferSize = 1 << 20;
|
||||
_udp.Client.SendBufferSize = 1 << 20;
|
||||
|
||||
_rxThread = new Thread(RxLoop) { IsBackground = true, Name = "UdpReliableChannel.Rx" };
|
||||
_rxThread.Start();
|
||||
_rxThread = new Thread(RxLoop)
|
||||
{
|
||||
IsBackground = true,
|
||||
Name = "UdpReliableChannel.Rx"
|
||||
};
|
||||
|
||||
if (EnableHeartbeat)
|
||||
StartHeartbeat();
|
||||
_rxThread.Start();
|
||||
|
||||
if (EnableHeartbeat)
|
||||
StartHeartbeat();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
_running = false;
|
||||
_stopping = false;
|
||||
|
||||
try { _udp?.Close(); } catch { }
|
||||
try { _udp?.Dispose(); } catch { }
|
||||
|
||||
_udp = null;
|
||||
_rxThread = null;
|
||||
|
||||
// 10048 = address already in use
|
||||
if (ex.SocketErrorCode == SocketError.AddressAlreadyInUse)
|
||||
{
|
||||
// Não relança. Quem chamou decide tentar depois.
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_running = false;
|
||||
_stopping = false;
|
||||
|
||||
try { _udp?.Close(); } catch { }
|
||||
try { _udp?.Dispose(); } catch { }
|
||||
|
||||
_udp = null;
|
||||
_rxThread = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
UdpClient udpParaFechar = null;
|
||||
Thread threadParaAguardar = null;
|
||||
|
||||
lock (_sockLock)
|
||||
{
|
||||
if (_stopping)
|
||||
return;
|
||||
|
||||
_stopping = true;
|
||||
_running = false;
|
||||
|
||||
udpParaFechar = _udp;
|
||||
threadParaAguardar = _rxThread;
|
||||
}
|
||||
|
||||
// pare heartbeat antes de matar socket
|
||||
StopHeartbeat();
|
||||
|
||||
try { _udp?.Close(); } catch { }
|
||||
try { _udp?.Dispose(); } catch { }
|
||||
try { udpParaFechar?.Close(); } catch { }
|
||||
try { udpParaFechar?.Dispose(); } catch { }
|
||||
|
||||
try
|
||||
{
|
||||
if (_rxThread != null && _rxThread.IsAlive)
|
||||
_rxThread.Join(2000); // ou sem timeout se preferir travar até fechar
|
||||
if (
|
||||
threadParaAguardar != null &&
|
||||
threadParaAguardar.IsAlive &&
|
||||
Thread.CurrentThread.ManagedThreadId != threadParaAguardar.ManagedThreadId
|
||||
)
|
||||
{
|
||||
threadParaAguardar.Join(1000);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
lock (_sockLock)
|
||||
{
|
||||
_udp = null;
|
||||
_rxThread = null;
|
||||
if (ReferenceEquals(_udp, udpParaFechar))
|
||||
_udp = null;
|
||||
|
||||
if (ReferenceEquals(_rxThread, threadParaAguardar))
|
||||
_rxThread = null;
|
||||
|
||||
_lastSeqRx = 0;
|
||||
|
||||
foreach (var kv in _pendingAck)
|
||||
kv.Value.TrySetResult(false);
|
||||
|
||||
_pendingAck.Clear();
|
||||
|
||||
_stopping = false;
|
||||
|
|
|
|||
|
|
@ -554,27 +554,38 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
def _avaliar_comando_bico(self, item, ctx, motivos, condicoes):
|
||||
dados = item["dados"]
|
||||
label = dados.get("label")
|
||||
|
||||
comando_presente = (
|
||||
"comando_atuar" in dados or
|
||||
"estado_desejado" in dados or
|
||||
"status_desejado_fisico" in dados or
|
||||
"ultimo_status_desejado" in dados
|
||||
)
|
||||
|
||||
comando = self._estado_desejado_ligado(dados)
|
||||
estado = self._get(dados, "estado_leitura", self._campo_atual(dados, "EstadoLeitura", 0))
|
||||
estado_on = self._estado_ligado(estado)
|
||||
|
||||
angulo = self._float(
|
||||
self._get(dados, "angulo_leitura", self._campo_atual(dados, "ServoAnguloLeitura", 0)),
|
||||
0,
|
||||
)
|
||||
usa_servo = dados.get("com_movimento", False)
|
||||
|
||||
angulo_neutro = self._float(dados.get("angulo_neutro", 90), 90)
|
||||
angulo_controle = self._float(dados.get("angulo_controle", dados.get("angulo_sp", 90)), 90)
|
||||
angulo_desejado = self._float(
|
||||
dados.get("angulo_desejado", angulo_controle if comando else angulo_neutro),
|
||||
angulo_controle if comando else angulo_neutro,
|
||||
)
|
||||
angulo = None
|
||||
angulo_desejado = None
|
||||
angulo_neutro = None
|
||||
angulo_controle = None
|
||||
|
||||
if usa_servo:
|
||||
angulo = self._float(
|
||||
self._get(dados, "angulo_leitura", self._campo_atual(dados, "ServoAnguloLeitura", 0)),
|
||||
0,
|
||||
)
|
||||
|
||||
angulo_neutro = self._float(dados.get("angulo_neutro", 90), 90)
|
||||
angulo_controle = self._float(dados.get("angulo_controle", dados.get("angulo_sp", 90)), 90)
|
||||
|
||||
angulo_desejado = self._float(
|
||||
dados.get("angulo_desejado", angulo_controle if comando else angulo_neutro),
|
||||
angulo_controle if comando else angulo_neutro,
|
||||
)
|
||||
|
||||
ultimo_comando_ms = self._float(dados.get("ultimo_comando_ms", 999999), 999999)
|
||||
tem_idade_comando = ultimo_comando_ms < 900000
|
||||
|
|
@ -585,13 +596,16 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
return 92, {
|
||||
"comando_disponivel": False,
|
||||
"estado_on": estado_on,
|
||||
"usa_servo": usa_servo,
|
||||
"angulo": angulo,
|
||||
"angulo_desejado": angulo_desejado,
|
||||
}
|
||||
|
||||
if tem_idade_comando and ultimo_comando_ms < self.COMANDO_GRACE_MS:
|
||||
return 96, {
|
||||
"comando_atuar": comando,
|
||||
"estado_on": estado_on,
|
||||
"usa_servo": usa_servo,
|
||||
"angulo": angulo,
|
||||
"angulo_desejado": angulo_desejado,
|
||||
"ultimo_comando_ms": ultimo_comando_ms,
|
||||
|
|
@ -634,32 +648,36 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
|
||||
score = min(score, 25 if severidade > 90 else 65)
|
||||
|
||||
erro_ang = abs(angulo - angulo_desejado)
|
||||
if usa_servo and angulo is not None and angulo_desejado is not None:
|
||||
erro_ang = abs(angulo - angulo_desejado)
|
||||
|
||||
if erro_ang > self.ANGULO_TOL_BICO_GRAUS and (comando or estado_on):
|
||||
motivos.append(f"Ângulo do bico distante do desejado ({angulo:.1f}°/{angulo_desejado:.1f}°)")
|
||||
condicoes.append({
|
||||
"label": "Ângulo bico",
|
||||
"valor": angulo,
|
||||
"severidade": min(75, max(30, int(erro_ang * 3))),
|
||||
"classe": "processo",
|
||||
"descricao": f"Ângulo do bico {label} distante do desejado",
|
||||
"acoes": [
|
||||
"Verificar servo/posição mecânica do bico.",
|
||||
"Conferir neutro e ângulo de abertura configurados.",
|
||||
],
|
||||
})
|
||||
score = min(score, 78)
|
||||
if erro_ang > self.ANGULO_TOL_BICO_GRAUS and (comando or estado_on):
|
||||
motivos.append(f"Ângulo do bico distante do desejado ({angulo:.1f}°/{angulo_desejado:.1f}°)")
|
||||
condicoes.append({
|
||||
"label": "Ângulo bico",
|
||||
"valor": angulo,
|
||||
"severidade": min(75, max(30, int(erro_ang * 3))),
|
||||
"classe": "processo",
|
||||
"descricao": f"Ângulo do bico {label} distante do desejado",
|
||||
"acoes": [
|
||||
"Verificar servo/posição mecânica do bico.",
|
||||
"Conferir neutro e ângulo de abertura configurados.",
|
||||
],
|
||||
})
|
||||
score = min(score, 78)
|
||||
|
||||
return int(max(0, min(100, round(score)))), {
|
||||
"comando_disponivel": True,
|
||||
"comando_atuar": comando,
|
||||
"estado_on": estado_on,
|
||||
"usa_servo": usa_servo,
|
||||
"angulo": angulo,
|
||||
"angulo_desejado": angulo_desejado,
|
||||
"angulo_neutro": angulo_neutro,
|
||||
"angulo_controle": angulo_controle,
|
||||
"ultimo_comando_ms": ultimo_comando_ms,
|
||||
}
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Bombas
|
||||
# ============================================================
|
||||
|
|
|
|||
|
|
@ -350,23 +350,15 @@ namespace OperationControl.Models
|
|||
HeartbeatPayload = new byte[] { 0 }
|
||||
};
|
||||
|
||||
channel.Start(
|
||||
VariaveisPortas.Ethernet_UDP_TX
|
||||
);
|
||||
channel.Start(VariaveisPortas.Ethernet_UDP_TX);
|
||||
|
||||
UdpChannel = channel;
|
||||
|
||||
ControlSenderDir = new ManualControlSender(
|
||||
UdpChannel,
|
||||
(byte)AgroBase.Models.Enums.T_Code.Dir
|
||||
);
|
||||
ControlSenderDir = new ManualControlSender(UdpChannel, (byte)AgroBase.Models.Enums.T_Code.Dir);
|
||||
|
||||
ControlSenderDir.Start();
|
||||
|
||||
ControlSenderMov = new ManualControlSender(
|
||||
UdpChannel,
|
||||
(byte)AgroBase.Models.Enums.T_Code.Mov
|
||||
);
|
||||
ControlSenderMov = new ManualControlSender(UdpChannel, (byte)AgroBase.Models.Enums.T_Code.Mov);
|
||||
|
||||
ControlSenderMov.Start();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue