revisão contador de carga e cooler control
This commit is contained in:
parent
eee7bacc54
commit
e230176950
|
|
@ -1141,12 +1141,16 @@ namespace AgroBase.Forms.Operacoes
|
||||||
|
|
||||||
lblPercentualBateria.Text = $"Bateria {Log.Bateria.PercentualBateria.ToString("0.00")}%";
|
lblPercentualBateria.Text = $"Bateria {Log.Bateria.PercentualBateria.ToString("0.00")}%";
|
||||||
FuncoesGlobais.PreencheValorProgressBar(pgbPercentualBateria, Log.Bateria.PercentualBateria);
|
FuncoesGlobais.PreencheValorProgressBar(pgbPercentualBateria, Log.Bateria.PercentualBateria);
|
||||||
lblBateriaConsumida.Text = $"Consumido {Log.Bateria.PercentualBateriaConsumida.ToString("0.00")}%";
|
|
||||||
FuncoesGlobais.PreencheValorProgressBar(pgbPercentualReservatorio, LogAtu.PercentualReservatorio);
|
lblBateriaConsumida.Text = $"Consumido {Log.Bateria.PercentualBateriaConsumidaOperacao.ToString("0.00")}%";
|
||||||
|
FuncoesGlobais.PreencheValorProgressBar(pgbBateriaConsumida, Log.Bateria.PercentualBateriaConsumidaOperacao);
|
||||||
|
|
||||||
lblPercentualReservatorio.Text = $"Reservatório {LogAtu.PercentualReservatorio.ToString("0.00")}%";
|
lblPercentualReservatorio.Text = $"Reservatório {LogAtu.PercentualReservatorio.ToString("0.00")}%";
|
||||||
FuncoesGlobais.PreencheValorProgressBar(pgbHerbicidaConsumido, percentualHerbicidaConsumido);
|
FuncoesGlobais.PreencheValorProgressBar(pgbPercentualReservatorio, LogAtu.PercentualReservatorio);
|
||||||
|
|
||||||
lblHerbicidaConsumido.Text = $"Consumido {herbicidaConsumido.ToString("0.00")} ml";
|
lblHerbicidaConsumido.Text = $"Consumido {herbicidaConsumido.ToString("0.00")} ml";
|
||||||
FuncoesGlobais.PreencheValorProgressBar(pgbBateriaConsumida, Log.Bateria.PercentualBateriaConsumida);
|
FuncoesGlobais.PreencheValorProgressBar(pgbHerbicidaConsumido, percentualHerbicidaConsumido);
|
||||||
|
|
||||||
txtTempoMovimento.Text = FuncoesGlobais.ConverterSegundosParaHHmmss((int)Log.Movimentacao.TempoMovimentoSegs);
|
txtTempoMovimento.Text = FuncoesGlobais.ConverterSegundosParaHHmmss((int)Log.Movimentacao.TempoMovimentoSegs);
|
||||||
txtStatusOperacao.Text = Log.StatusOperacao.ToString();
|
txtStatusOperacao.Text = Log.StatusOperacao.ToString();
|
||||||
txtStatusCarro.Text = $"{Log.Trajetoria.StatusCarro}";
|
txtStatusCarro.Text = $"{Log.Trajetoria.StatusCarro}";
|
||||||
|
|
|
||||||
|
|
@ -834,13 +834,13 @@ namespace AgroBase
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void EnviarComandoSensoriamento(S_Code Componente, string ID, dynamic Status, bool Forcar = false)
|
public static void EnviarComandoSensoriamento(S_Code Componente, string ID, dynamic Status) //, bool Forcar = false
|
||||||
{
|
{
|
||||||
var DispSen = Variaveis.OperacaoEmAndamento.DispSen;
|
var DispSen = Variaveis.OperacaoEmAndamento.DispSen;
|
||||||
if (!DispSen.Dados.Conectado)
|
if (!DispSen.Dados.Conectado)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!Forcar)
|
if (false) // !Forcar
|
||||||
{
|
{
|
||||||
bool componente_em_uso = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Sen && (x.ComponentesEmUso?.ContainsKey(ID) ?? false) && x.ComponentesEmUso[ID].Item2);
|
bool componente_em_uso = Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Sen && (x.ComponentesEmUso?.ContainsKey(ID) ?? false) && x.ComponentesEmUso[ID].Item2);
|
||||||
if (!componente_em_uso)
|
if (!componente_em_uso)
|
||||||
|
|
|
||||||
|
|
@ -626,7 +626,7 @@ namespace AgroBase.Models.Modules
|
||||||
{
|
{
|
||||||
if (EnviarComando && UltimoEnvio.AddMilliseconds(DelayEnvio) < DateTime.Now && Servo != null)
|
if (EnviarComando && UltimoEnvio.AddMilliseconds(DelayEnvio) < DateTime.Now && Servo != null)
|
||||||
{
|
{
|
||||||
GeneralJoystick.EnviarComandoSensoriamento(Servo.Componente, Servo.ID, AnguloControle, Forcar: true);
|
GeneralJoystick.EnviarComandoSensoriamento(Servo.Componente, Servo.ID, AnguloControle);
|
||||||
UltimoEnvio = DateTime.Now;
|
UltimoEnvio = DateTime.Now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ using System.Globalization;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using static AgroBase.Services.LoRaEspService;
|
using static AgroBase.Services.LoRaEspService;
|
||||||
using AgroBase.Services.Operadores;
|
using AgroBase.Services.Operadores;
|
||||||
using AgroBase.Models.Operadores;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace AgroBase.Models.Modules
|
namespace AgroBase.Models.Modules
|
||||||
|
|
|
||||||
|
|
@ -1184,6 +1184,7 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
Controle.Reiniciar();
|
Controle.Reiniciar();
|
||||||
ControleAnterior.Reiniciar();
|
ControleAnterior.Reiniciar();
|
||||||
|
DispSen?.Dados?.ContadorCarga?.IniciarOperacao();
|
||||||
|
|
||||||
GPSTrajetoria = new List<GPSModel>();
|
GPSTrajetoria = new List<GPSModel>();
|
||||||
|
|
||||||
|
|
@ -1219,6 +1220,7 @@ namespace AgroBase.Models
|
||||||
|
|
||||||
Variaveis.OperacaoEmAndamento.Finalizando = false;
|
Variaveis.OperacaoEmAndamento.Finalizando = false;
|
||||||
Variaveis.OperacaoEmAndamento.Trajetoria?.AutonomiaCorredor?.Parar();
|
Variaveis.OperacaoEmAndamento.Trajetoria?.AutonomiaCorredor?.Parar();
|
||||||
|
Variaveis.OperacaoEmAndamento.DispSen?.Dados?.ContadorCarga?.FinalizarOperacao();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReiniciarOperacao(bool daBase)
|
public void ReiniciarOperacao(bool daBase)
|
||||||
|
|
@ -1812,7 +1814,7 @@ namespace AgroBase.Models
|
||||||
}
|
}
|
||||||
|
|
||||||
S_Code comp = get_comp(controleBase._comp_id);
|
S_Code comp = get_comp(controleBase._comp_id);
|
||||||
GeneralJoystick.EnviarComandoSensoriamento(comp, controleBase._comp_id, controleBase._comp_value, Forcar: true);
|
GeneralJoystick.EnviarComandoSensoriamento(comp, controleBase._comp_id, controleBase._comp_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2788,12 +2790,12 @@ namespace AgroBase.Models
|
||||||
BmsLigado = _Bateria.BmsLigado,
|
BmsLigado = _Bateria.BmsLigado,
|
||||||
_dt = _Bateria._dt,
|
_dt = _Bateria._dt,
|
||||||
PercentualBateria = _Bateria.PercentualBateria,
|
PercentualBateria = _Bateria.PercentualBateria,
|
||||||
PercentualBateriaConsumida = _Bateria.PercentualConsumido,
|
PercentualBateriaConsumida = _Bateria.PercentualConsumidoTotal,
|
||||||
|
PercentualBateriaConsumidaOperacao = _Bateria.PercentualConsumidoOperacao,
|
||||||
TempoEstimadoRestanteMinutos = _Bateria.TempoEstimadoMinutos,
|
TempoEstimadoRestanteMinutos = _Bateria.TempoEstimadoMinutos,
|
||||||
CorrenteInstantanea = _Bateria.CorrenteInstantanea,
|
CorrenteInstantanea = _Bateria.CorrenteInstantanea,
|
||||||
TensaoInstantanea = _Bateria.TensaoInstantanea,
|
TensaoInstantanea = _Bateria.TensaoInstantanea,
|
||||||
PotenciaInstantanea = _Bateria.PotenciaInstantanea,
|
PotenciaInstantanea = _Bateria.PotenciaInstantanea,
|
||||||
EnergiaConsumida_Wh = _Bateria.EnergiaConsumida_Wh,
|
|
||||||
WhPorMetro = _Bateria.WhPorMetro,
|
WhPorMetro = _Bateria.WhPorMetro,
|
||||||
DistanciaEstimadaRestanteMetros = _Bateria.DistanciaEstimadaRestante_m,
|
DistanciaEstimadaRestanteMetros = _Bateria.DistanciaEstimadaRestante_m,
|
||||||
Temperatura = _Bateria.Temperatura,
|
Temperatura = _Bateria.Temperatura,
|
||||||
|
|
@ -3143,10 +3145,10 @@ namespace AgroBase.Models
|
||||||
public double _dt { get; set; }
|
public double _dt { get; set; }
|
||||||
public double PercentualBateria { get; set; }
|
public double PercentualBateria { get; set; }
|
||||||
public double PercentualBateriaConsumida { get; set; }
|
public double PercentualBateriaConsumida { get; set; }
|
||||||
|
public double PercentualBateriaConsumidaOperacao { get; set; }
|
||||||
public double CorrenteInstantanea { get; set; }
|
public double CorrenteInstantanea { get; set; }
|
||||||
public double TensaoInstantanea { get; set; }
|
public double TensaoInstantanea { get; set; }
|
||||||
public double PotenciaInstantanea { get; set; }
|
public double PotenciaInstantanea { get; set; }
|
||||||
public double EnergiaConsumida_Wh { get; set; }
|
|
||||||
public double WhPorMetro { get; set; }
|
public double WhPorMetro { get; set; }
|
||||||
public double TempoEstimadoRestanteMinutos { get; set; }
|
public double TempoEstimadoRestanteMinutos { get; set; }
|
||||||
public double DistanciaEstimadaRestanteMetros { get; set; }
|
public double DistanciaEstimadaRestanteMetros { get; set; }
|
||||||
|
|
@ -3165,7 +3167,6 @@ namespace AgroBase.Models
|
||||||
CorrenteInstantanea = CorrenteInstantanea,
|
CorrenteInstantanea = CorrenteInstantanea,
|
||||||
TensaoInstantanea = TensaoInstantanea,
|
TensaoInstantanea = TensaoInstantanea,
|
||||||
PotenciaInstantanea = PotenciaInstantanea,
|
PotenciaInstantanea = PotenciaInstantanea,
|
||||||
EnergiaConsumida_Wh = EnergiaConsumida_Wh,
|
|
||||||
WhPorMetro = WhPorMetro,
|
WhPorMetro = WhPorMetro,
|
||||||
TempoEstimadoRestanteMinutos = TempoEstimadoRestanteMinutos,
|
TempoEstimadoRestanteMinutos = TempoEstimadoRestanteMinutos,
|
||||||
DistanciaEstimadaRestanteMetros = DistanciaEstimadaRestanteMetros,
|
DistanciaEstimadaRestanteMetros = DistanciaEstimadaRestanteMetros,
|
||||||
|
|
|
||||||
|
|
@ -33,23 +33,9 @@ namespace AgroBase.Services
|
||||||
|
|
||||||
public bool AlertaTemperaturaCritica { get; private set; }
|
public bool AlertaTemperaturaCritica { get; private set; }
|
||||||
|
|
||||||
private SensorReleModel ReleCoolerEntrada
|
private SensorReleModel ReleCoolerEntrada => Variaveis.OperacaoEmAndamento.DispSen?.Dados?.Reles?.FirstOrDefault(x => x.ID == "RLCIN" && x.Inicializado && x.Controlar);
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var sRLE = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.Reles?.FirstOrDefault(x => x.ID == "RLCIN" && x.Inicializado && x.Controlar);
|
|
||||||
return sRLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private SensorReleModel ReleCoolerSaida
|
private SensorReleModel ReleCoolerSaida => Variaveis.OperacaoEmAndamento.DispSen?.Dados?.Reles?.FirstOrDefault(x => x.ID == "RLCOUT" && x.Inicializado && x.Controlar);
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var sRLE = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.Reles?.FirstOrDefault(x => x.ID == "RLCOUT" && x.Inicializado && x.Controlar);
|
|
||||||
return sRLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public CoolerControlService()
|
public CoolerControlService()
|
||||||
{
|
{
|
||||||
|
|
@ -169,11 +155,11 @@ namespace AgroBase.Services
|
||||||
{
|
{
|
||||||
if (ReleCoolerEntrada != null && CoolerEntradaEstadoRele != CoolerEntradaEstado)
|
if (ReleCoolerEntrada != null && CoolerEntradaEstadoRele != CoolerEntradaEstado)
|
||||||
{
|
{
|
||||||
GeneralJoystick.EnviarComandoSensoriamento(ReleCoolerEntrada.Componente, ReleCoolerEntrada.ID, CoolerEntradaEstado, true);
|
GeneralJoystick.EnviarComandoSensoriamento(ReleCoolerEntrada.Componente, ReleCoolerEntrada.ID, CoolerEntradaEstado);
|
||||||
}
|
}
|
||||||
if (ReleCoolerSaida != null && CoolerSaidaEstadoRele != CoolerSaidaEstado)
|
if (ReleCoolerSaida != null && CoolerSaidaEstadoRele != CoolerSaidaEstado)
|
||||||
{
|
{
|
||||||
GeneralJoystick.EnviarComandoSensoriamento(ReleCoolerSaida.Componente, ReleCoolerSaida.ID, CoolerSaidaEstado, true);
|
GeneralJoystick.EnviarComandoSensoriamento(ReleCoolerSaida.Componente, ReleCoolerSaida.ID, CoolerSaidaEstado);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,133 +8,249 @@ namespace AgroBase.Services
|
||||||
{
|
{
|
||||||
public class CoulombCounterService
|
public class CoulombCounterService
|
||||||
{
|
{
|
||||||
public CoulombCounterService(double _max_Amp, double w_m_base = 0.1167) // 3 km/h ~ 350 wh
|
public CoulombCounterService(double max_Ah, double w_m_base = 0.1167)
|
||||||
{
|
{
|
||||||
double coulombsMax = _max_Amp * 3600;
|
CargaMaxima_C = max_Ah * 3600.0; // Ah -> Coulombs
|
||||||
CargaMaxima = coulombsMax;
|
|
||||||
WhPorMetroBase = w_m_base;
|
WhPorMetroBase = w_m_base;
|
||||||
//double consumo = (Variaveis.OperacaoEmAndamento.DispSen?.Dados?.BateriaCargaConsumida ?? 0);
|
|
||||||
//Consumido = consumo < CargaMaxima ? consumo : 0;
|
|
||||||
Consumido = 0;
|
|
||||||
CargaAtual = CargaMaxima - Consumido;
|
|
||||||
//double consumoW = (Variaveis.OperacaoEmAndamento.DispSen?.Dados?.BateriaCargaConsumidaWatts ?? 0);
|
|
||||||
//ConsumidoWatts = consumoW;
|
|
||||||
|
|
||||||
// Autonomia
|
Iniciado = false;
|
||||||
MargemSegurancaAutonomia = 0.30; // 30% de margem padrão
|
BmsLigado = false;
|
||||||
EnergiaConsumida_Wh = 0;
|
|
||||||
_energiaConsumidaAnterior_Wh = 0;
|
_estadoInicializado = false;
|
||||||
_distanciaTotalMetrosAnterior = 0;
|
_ultimaLeituraIntegrada = null;
|
||||||
|
|
||||||
|
CargaAtual_C = 0;
|
||||||
|
ConsumidoTotal_C = 0;
|
||||||
|
EnergiaConsumidaTotal_Wh = 0;
|
||||||
|
|
||||||
|
_socInicialInstancia = 0;
|
||||||
|
_cargaInicialInstancia_C = 0;
|
||||||
|
|
||||||
|
_socInicialOperacao = 0;
|
||||||
|
_cargaInicioOperacao_C = 0;
|
||||||
|
_consumidoTotalNoInicioOperacao_C = 0;
|
||||||
|
_energiaTotalNoInicioOperacao_Wh = 0;
|
||||||
|
|
||||||
|
MargemSegurancaAutonomia = 0.30;
|
||||||
|
|
||||||
|
ResetarHistoricosAutonomia();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double TempoEstimadoMinutos { get; private set; }
|
|
||||||
private const int BufferSize = 30; // últimos 3 segundos se chamada a cada 100ms
|
|
||||||
private readonly Queue<double> _historicoCorrente = new Queue<double>();
|
|
||||||
|
|
||||||
public bool Iniciado { get; private set; }
|
public bool Iniciado { get; private set; }
|
||||||
public bool BmsLigado { get; set; }
|
public bool BmsLigado { get; private set; }
|
||||||
private double CargaMaxima { get; set; }
|
|
||||||
private double CargaAtual { get; set; }
|
private bool _estadoInicializado;
|
||||||
public double CargaAtualAmp
|
private DateTime? _ultimaLeituraIntegrada;
|
||||||
|
|
||||||
|
// Capacidade e estado absoluto do pack
|
||||||
|
private double CargaMaxima_C { get; set; } // Coulombs
|
||||||
|
private double CargaAtual_C { get; set; } // Coulombs
|
||||||
|
|
||||||
|
// Snapshot inicial da instância
|
||||||
|
private double _socInicialInstancia { get; set; }
|
||||||
|
private double _cargaInicialInstancia_C { get; set; }
|
||||||
|
|
||||||
|
// Acumuladores totais desde a criação da instância
|
||||||
|
private double ConsumidoTotal_C { get; set; }
|
||||||
|
public double ConsumidoTotal_Ah => ConsumidoTotal_C / 3600.0;
|
||||||
|
|
||||||
|
public double PercentualConsumidoTotal
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return CargaAtual / 3600.0;
|
if (CargaMaxima_C <= 0) return 0;
|
||||||
|
double calc = (ConsumidoTotal_C / CargaMaxima_C) * 100.0;
|
||||||
|
return FuncoesMatematicas.Clamp(calc, 0, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private double Consumido { get; set; }
|
|
||||||
public double _Consumido
|
public double EnergiaConsumidaTotal_Wh { get; private set; }
|
||||||
|
|
||||||
|
// Snapshot do início da operação
|
||||||
|
private double _socInicialOperacao { get; set; }
|
||||||
|
private double _cargaInicioOperacao_C { get; set; }
|
||||||
|
private double _consumidoTotalNoInicioOperacao_C { get; set; }
|
||||||
|
private double _energiaTotalNoInicioOperacao_Wh { get; set; }
|
||||||
|
public bool OperacaoAtiva { get; private set; }
|
||||||
|
public bool OperacaoFinalizada { get; private set; }
|
||||||
|
|
||||||
|
private double _consumidoTotalNoFimOperacao_C;
|
||||||
|
private double _energiaTotalNoFimOperacao_Wh;
|
||||||
|
|
||||||
|
// Derivados da operação
|
||||||
|
public double ConsumidoOperacao_C
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Consumido;
|
if (!OperacaoAtiva && !OperacaoFinalizada)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
double referenciaFim = OperacaoFinalizada
|
||||||
|
? _consumidoTotalNoFimOperacao_C
|
||||||
|
: ConsumidoTotal_C;
|
||||||
|
|
||||||
|
return Math.Max(0, referenciaFim - _consumidoTotalNoInicioOperacao_C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public double ConsumidoAmp
|
public double ConsumidoOperacao_Ah => ConsumidoOperacao_C / 3600.0;
|
||||||
|
|
||||||
|
public double PercentualConsumidoOperacao
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Consumido / 3600.0;
|
if (CargaMaxima_C <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
double calc = (ConsumidoOperacao_C / CargaMaxima_C) * 100.0;
|
||||||
|
return FuncoesMatematicas.Clamp(calc, 0, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double PercentualConsumidoOperacaoDaCargaInicial
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!OperacaoAtiva && !OperacaoFinalizada)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (_cargaInicioOperacao_C <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
double calc = (ConsumidoOperacao_C / _cargaInicioOperacao_C) * 100.0;
|
||||||
|
return FuncoesMatematicas.Clamp(calc, 0, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double EnergiaConsumidaOperacao_Wh
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!OperacaoAtiva && !OperacaoFinalizada)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
double referenciaFim = OperacaoFinalizada
|
||||||
|
? _energiaTotalNoFimOperacao_Wh
|
||||||
|
: EnergiaConsumidaTotal_Wh;
|
||||||
|
|
||||||
|
return Math.Max(0, referenciaFim - _energiaTotalNoInicioOperacao_Wh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Estado atual
|
||||||
public double PercentualAtual
|
public double PercentualAtual
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return (CargaAtual / CargaMaxima) * 100;
|
if (CargaMaxima_C <= 0) return 0;
|
||||||
}
|
return FuncoesMatematicas.Clamp((CargaAtual_C / CargaMaxima_C) * 100.0, 0, 100);
|
||||||
}
|
|
||||||
public double PercentualConsumido
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
double calc = (Consumido / CargaMaxima) * 100;
|
|
||||||
calc = FuncoesMatematicas.Clamp(calc, 0, 100);
|
|
||||||
return calc;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double CargaAtualAmp => CargaAtual_C / 3600.0;
|
||||||
public double PercentualBateria { get; private set; }
|
public double PercentualBateria { get; private set; }
|
||||||
public double EnergiaConsumida_Wh { get; set; }
|
public double Temperatura { get; private set; }
|
||||||
public double _dt { get; private set; }
|
|
||||||
public double CorrenteInstantanea { get; private set; }
|
public double CorrenteInstantanea { get; private set; }
|
||||||
public double TensaoInstantanea { get; private set; }
|
public double TensaoInstantanea { get; private set; }
|
||||||
public double PotenciaInstantanea { get; private set; }
|
public double PotenciaInstantanea { get; private set; }
|
||||||
|
public double TempoEstimadoMinutos { get; private set; }
|
||||||
|
public double _dt { get; private set; }
|
||||||
|
|
||||||
public double WhRestante
|
public double WhRestante
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
// Exemplo: usar uma tensão nominal do pack
|
double tensaoReferencia = TensaoInstantanea > 0
|
||||||
double tensaoNominal = VariaveisEquipamento.TensaoMaximaBateria;
|
? TensaoInstantanea
|
||||||
return CargaAtualAmp * tensaoNominal; // Ah * V = Wh
|
: VariaveisEquipamento.TensaoMaximaBateria;
|
||||||
|
|
||||||
|
return CargaAtualAmp * tensaoReferencia;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public double Temperatura { get; private set; }
|
|
||||||
|
|
||||||
|
// Histórico para suavização de corrente
|
||||||
|
private const int BufferSize = 30;
|
||||||
|
private readonly Queue<double> _historicoCorrente = new Queue<double>();
|
||||||
|
|
||||||
|
// Autonomia
|
||||||
public double WhPorMetro { get; private set; }
|
public double WhPorMetro { get; private set; }
|
||||||
public double WhPorMetroBase { get; set; } // configurado externamente
|
public double WhPorMetroBase { get; set; }
|
||||||
public double WhPorMetroHistorico { get; private set; }
|
public double WhPorMetroHistorico { get; private set; }
|
||||||
|
|
||||||
public double WhPorMetroReferencia
|
public double WhPorMetroReferencia
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (WhPorMetro > 0) return WhPorMetro;
|
if (WhPorMetro > 0) return WhPorMetro;
|
||||||
if (WhPorMetroHistorico > 0) return WhPorMetroHistorico;
|
if (WhPorMetroHistorico > 0) return WhPorMetroHistorico;
|
||||||
return WhPorMetroBase; // pode ser 0 se você não configurar
|
return WhPorMetroBase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double DistanciaMaximaTeorica_m { get; private set; }
|
public double DistanciaMaximaTeorica_m { get; private set; }
|
||||||
public double DistanciaMaximaSegura_m { get; private set; }
|
public double DistanciaMaximaSegura_m { get; private set; }
|
||||||
public double DistanciaEstimadaRestante_m { get; private set; }
|
public double DistanciaEstimadaRestante_m { get; private set; }
|
||||||
public double MargemSegurancaAutonomia { get; set; }
|
public double MargemSegurancaAutonomia { get; set; }
|
||||||
private const double JanelaAutonomia_m = 50.0; // metros analisados na média
|
|
||||||
|
private const double JanelaAutonomia_m = 50.0;
|
||||||
private readonly Queue<double> _historicoDeltaDist_m = new Queue<double>();
|
private readonly Queue<double> _historicoDeltaDist_m = new Queue<double>();
|
||||||
private readonly Queue<double> _historicoDeltaWh = new Queue<double>();
|
private readonly Queue<double> _historicoDeltaWh = new Queue<double>();
|
||||||
private double _somaDistanciaJanela_m;
|
private double _somaDistanciaJanela_m;
|
||||||
private double _somaEnergiaJanela_Wh;
|
private double _somaEnergiaJanela_Wh;
|
||||||
private double _distanciaTotalMetrosAnterior;
|
private double _distanciaTotalMetrosAnterior;
|
||||||
private double _energiaConsumidaAnterior_Wh;
|
private double _energiaConsumidaAnterior_Wh_Total;
|
||||||
|
|
||||||
|
public void IniciarOperacao()
|
||||||
|
{
|
||||||
|
if (!_estadoInicializado)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_socInicialOperacao = PercentualBateria;
|
||||||
|
_cargaInicioOperacao_C = CargaAtual_C;
|
||||||
|
_consumidoTotalNoInicioOperacao_C = ConsumidoTotal_C;
|
||||||
|
_energiaTotalNoInicioOperacao_Wh = EnergiaConsumidaTotal_Wh;
|
||||||
|
|
||||||
|
_consumidoTotalNoFimOperacao_C = 0;
|
||||||
|
_energiaTotalNoFimOperacao_Wh = 0;
|
||||||
|
|
||||||
|
OperacaoAtiva = true;
|
||||||
|
OperacaoFinalizada = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FinalizarOperacao()
|
||||||
|
{
|
||||||
|
if (!OperacaoAtiva)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_consumidoTotalNoFimOperacao_C = ConsumidoTotal_C;
|
||||||
|
_energiaTotalNoFimOperacao_Wh = EnergiaConsumidaTotal_Wh;
|
||||||
|
|
||||||
|
OperacaoAtiva = false;
|
||||||
|
OperacaoFinalizada = true;
|
||||||
|
}
|
||||||
|
|
||||||
public void AtualizarConsumo(double distanciaTotalMetrosAtual)
|
public void AtualizarConsumo(double distanciaTotalMetrosAtual)
|
||||||
{
|
{
|
||||||
var DalyBms = DalyBMSService.DadosLeitura;
|
var dalyBms = DalyBMSService.DadosLeitura;
|
||||||
bool bms_iniciado = DalyBms?.Iniciado ?? false;
|
bool bms_iniciado = dalyBms?.Iniciado ?? false;
|
||||||
DateTime? bms_ultima_leitura = DalyBms?.UltimoComandoRecebido;
|
DateTime? bms_ultima_leitura = dalyBms?.UltimoComandoRecebido;
|
||||||
double bms_tensao = DalyBms?.Pack?.TensaoTotal_V ?? 0;
|
double bms_tensao = dalyBms?.Pack?.TensaoTotal_V ?? 0;
|
||||||
double bms_corrente = DalyBms?.Pack?.Corrente_A ?? 0;
|
double bms_corrente = dalyBms?.Pack?.Corrente_A ?? 0;
|
||||||
double bms_potencia = bms_tensao * bms_corrente;
|
double bms_soc = dalyBms?.Pack?.SOC_percent ?? 0;
|
||||||
double bms_soc = DalyBms?.Pack?.SOC_percent ?? 0;
|
double bms_tmp = dalyBms?.TemperaturaMax ?? 0;
|
||||||
double bms_tmp = DalyBms?.TemperaturaMax ?? 0;
|
|
||||||
|
|
||||||
var Sensor = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.Sensores?.FirstOrDefault(x => x.ID == "AB36V");
|
var sensor = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.Sensores?.FirstOrDefault(x => x.ID == "AB36V");
|
||||||
bool sen_iniciado = Sensor?.Inicializado ?? false;
|
bool sen_iniciado = sensor?.Inicializado ?? false;
|
||||||
DateTime? sen_ultima_leitura = Sensor?.UltimaLeitura;
|
DateTime? sen_ultima_leitura = sensor?.UltimaLeitura;
|
||||||
double sen_dt = Sensor?.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Corrente)?.atual?.dt ?? 0;
|
double sen_tensao = sensor?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Tensao)?.atual?.valor ?? 0;
|
||||||
double sen_tensao = Sensor?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Tensao)?.atual?.valor ?? 0;
|
double sen_corrente = (sensor?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Corrente)?.atual?.valor ?? 0) / 1000.0;
|
||||||
double sen_corrente = (Sensor?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Corrente)?.atual?.valor ?? 0) / 1000.0;
|
double sen_soc = Math.Round(
|
||||||
double sen_potencia = Sensor?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia)?.atual?.valor ?? 0;
|
FuncoesMatematicas.Map(
|
||||||
double sen_soc = Math.Round(FuncoesMatematicas.Map(sen_tensao, VariaveisEquipamento.TensaoMinimaBateria, VariaveisEquipamento.TensaoMaximaBateria, 0.0, 100.0), 2);
|
sen_tensao,
|
||||||
double sen_tmp = Sensor?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Temperatura)?.atual?.valor ?? 0;
|
VariaveisEquipamento.TensaoMinimaBateria,
|
||||||
|
VariaveisEquipamento.TensaoMaximaBateria,
|
||||||
|
0.0,
|
||||||
|
100.0), 2);
|
||||||
|
double sen_tmp = sensor?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Temperatura)?.atual?.valor ?? 0;
|
||||||
|
|
||||||
Iniciado = bms_iniciado || sen_iniciado;
|
Iniciado = bms_iniciado || sen_iniciado;
|
||||||
BmsLigado = bms_iniciado;
|
BmsLigado = bms_iniciado;
|
||||||
|
|
@ -142,157 +258,161 @@ namespace AgroBase.Services
|
||||||
if (!Iniciado)
|
if (!Iniciado)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//_dt = Sensor.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Corrente)?.atual?.dt ?? 0;
|
DateTime? leituraAtual = BmsLigado ? bms_ultima_leitura : sen_ultima_leitura;
|
||||||
_dt = (DateTime.Now - ((BmsLigado ? bms_ultima_leitura : sen_ultima_leitura) ?? DateTime.Now)).TotalSeconds;
|
|
||||||
TensaoInstantanea = BmsLigado ? bms_tensao : sen_tensao;
|
TensaoInstantanea = BmsLigado ? bms_tensao : sen_tensao;
|
||||||
CorrenteInstantanea = BmsLigado ? bms_corrente : sen_corrente;
|
CorrenteInstantanea = BmsLigado ? bms_corrente : sen_corrente;
|
||||||
PotenciaInstantanea = BmsLigado ? bms_potencia : sen_potencia;
|
PotenciaInstantanea = TensaoInstantanea * CorrenteInstantanea;
|
||||||
PercentualBateria = BmsLigado ? bms_soc : sen_soc;
|
PercentualBateria = FuncoesMatematicas.Clamp(BmsLigado ? bms_soc : sen_soc, 0, 100);
|
||||||
Temperatura = BmsLigado ? bms_tmp : sen_tmp;
|
Temperatura = BmsLigado ? bms_tmp : sen_tmp;
|
||||||
PercentualBateria = FuncoesMatematicas.Clamp(PercentualBateria, 0, 100);
|
|
||||||
|
|
||||||
// Verifique se as datas são válidas (não MinValue, MaxValue ou valores anômalos)
|
if (!leituraAtual.HasValue || leituraAtual.Value == DateTime.MinValue)
|
||||||
if (_dt == 0 || _dt > 10)
|
return;
|
||||||
|
|
||||||
|
// Primeira leitura válida da instância
|
||||||
|
if (!_estadoInicializado)
|
||||||
{
|
{
|
||||||
Console.WriteLine("[COULOMB COUNTER] Leitura inválida detectada.");
|
_socInicialInstancia = PercentualBateria;
|
||||||
|
_cargaInicialInstancia_C = CargaMaxima_C * (PercentualBateria / 100.0);
|
||||||
|
CargaAtual_C = _cargaInicialInstancia_C;
|
||||||
|
|
||||||
|
ConsumidoTotal_C = 0;
|
||||||
|
EnergiaConsumidaTotal_Wh = 0;
|
||||||
|
|
||||||
|
_ultimaLeituraIntegrada = leituraAtual.Value;
|
||||||
|
_estadoInicializado = true;
|
||||||
|
|
||||||
|
_dt = 0;
|
||||||
|
AtualizarAutonomia(distanciaTotalMetrosAtual);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- COULOMB COUNTING (igual ao que já tinha, só com pequenos cuidados) ---
|
// Só integra se chegou leitura nova
|
||||||
double deltaCoulombs = CorrenteInstantanea * _dt; // A * s
|
if (_ultimaLeituraIntegrada.HasValue && leituraAtual.Value <= _ultimaLeituraIntegrada.Value)
|
||||||
|
{
|
||||||
|
_dt = 0;
|
||||||
|
AtualizarAutonomia(distanciaTotalMetrosAtual);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Consumido += deltaCoulombs;
|
_dt = (leituraAtual.Value - _ultimaLeituraIntegrada.Value).TotalSeconds;
|
||||||
if (Consumido < 0) Consumido = 0;
|
_ultimaLeituraIntegrada = leituraAtual.Value;
|
||||||
if (Consumido > CargaMaxima) Consumido = CargaMaxima;
|
|
||||||
|
|
||||||
CargaAtual = CargaMaxima - Consumido;
|
if (_dt <= 0 || _dt > 10)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[COULOMB COUNTER] dt inválido: {_dt:F3}s");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// --- ENERGIA ACUMULADA (Wh) ---
|
// Assumindo descarga positiva. Se no Daly a descarga vier negativa, inverter aqui.
|
||||||
double potenciaInst_W = TensaoInstantanea * CorrenteInstantanea; // W
|
double correnteDescarga_A = Math.Max(0, CorrenteInstantanea);
|
||||||
double deltaEnergia_Wh = potenciaInst_W * _dt / 3600.0; // Wh
|
|
||||||
|
|
||||||
EnergiaConsumida_Wh += deltaEnergia_Wh;
|
double deltaCoulombs = correnteDescarga_A * _dt;
|
||||||
//EnergiaConsumida_Wh = Sensor.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Energia)?.atual?.valor ?? 0;
|
ConsumidoTotal_C += deltaCoulombs;
|
||||||
|
ConsumidoTotal_C = FuncoesMatematicas.Clamp(ConsumidoTotal_C, 0, CargaMaxima_C);
|
||||||
|
|
||||||
// --- HISTÓRICO P/ TEMPO ESTIMADO ---
|
// Estado absoluto do pack sempre baseado no total da instância
|
||||||
_historicoCorrente.Enqueue(CorrenteInstantanea);
|
double cargaAtualCalculada = _cargaInicialInstancia_C - ConsumidoTotal_C;
|
||||||
|
CargaAtual_C = FuncoesMatematicas.Clamp(cargaAtualCalculada, 0, CargaMaxima_C);
|
||||||
|
|
||||||
|
double deltaEnergia_Wh = PotenciaInstantanea * _dt / 3600.0;
|
||||||
|
if (deltaEnergia_Wh > 0)
|
||||||
|
EnergiaConsumidaTotal_Wh += deltaEnergia_Wh;
|
||||||
|
|
||||||
|
_historicoCorrente.Enqueue(correnteDescarga_A);
|
||||||
if (_historicoCorrente.Count > BufferSize)
|
if (_historicoCorrente.Count > BufferSize)
|
||||||
_historicoCorrente.Dequeue();
|
_historicoCorrente.Dequeue();
|
||||||
|
|
||||||
double correnteMedia = _historicoCorrente.Average();
|
double correnteMedia = _historicoCorrente.Count > 0
|
||||||
|
? _historicoCorrente.Average()
|
||||||
|
: 0;
|
||||||
|
|
||||||
if (TensaoInstantanea > VariaveisEquipamento.TensaoMinimaBateria && correnteMedia > 0)
|
if (correnteMedia > 0 && CargaAtualAmp > 0)
|
||||||
{
|
TempoEstimadoMinutos = (CargaAtualAmp / correnteMedia) * 60.0;
|
||||||
TempoEstimadoMinutos = (CargaAtualAmp / correnteMedia) * 60;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
TempoEstimadoMinutos = 0;
|
TempoEstimadoMinutos = 0;
|
||||||
}
|
|
||||||
|
|
||||||
AtualizarAutonomia(distanciaTotalMetrosAtual);
|
AtualizarAutonomia(distanciaTotalMetrosAtual);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Atualiza os cálculos de autonomia em função da distância total percorrida.
|
|
||||||
///
|
|
||||||
/// IMPORTANTE:
|
|
||||||
/// - distanciaTotalMetrosAtual deve ser o "total rodado" acumulado em metros (odometria / MPC / motores).
|
|
||||||
/// - Aqui dentro calculamos o delta de distância e o delta de energia desde a última chamada.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="distanciaTotalMetrosAtual">Distância total percorrida até o momento (em metros).</param>
|
|
||||||
private void AtualizarAutonomia(double distanciaTotalMetrosAtual)
|
private void AtualizarAutonomia(double distanciaTotalMetrosAtual)
|
||||||
{
|
{
|
||||||
if (!Iniciado)
|
if (!_estadoInicializado)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Cálculo dos deltas
|
double deltaDist_m = Math.Max(0, distanciaTotalMetrosAtual - _distanciaTotalMetrosAnterior);
|
||||||
double deltaDist_m = distanciaTotalMetrosAtual - _distanciaTotalMetrosAnterior;
|
|
||||||
double deltaWh = EnergiaConsumida_Wh - _energiaConsumidaAnterior_Wh;
|
|
||||||
|
|
||||||
// Atualiza referências para próxima chamada
|
|
||||||
_distanciaTotalMetrosAnterior = distanciaTotalMetrosAtual;
|
_distanciaTotalMetrosAnterior = distanciaTotalMetrosAtual;
|
||||||
_energiaConsumidaAnterior_Wh = EnergiaConsumida_Wh;
|
|
||||||
|
|
||||||
// ---------- 1) ATUALIZAÇÃO DA JANELA (SÓ SE ANDOU) ----------
|
double energiaTotalAtual_Wh = EnergiaConsumidaTotal_Wh;
|
||||||
|
double deltaWh = Math.Max(0, energiaTotalAtual_Wh - _energiaConsumidaAnterior_Wh_Total);
|
||||||
|
_energiaConsumidaAnterior_Wh_Total = energiaTotalAtual_Wh;
|
||||||
|
|
||||||
if (deltaDist_m > 0 && deltaWh >= 0)
|
if (deltaDist_m > 0 && deltaWh >= 0)
|
||||||
{
|
{
|
||||||
// Alimenta a janela móvel
|
|
||||||
_historicoDeltaDist_m.Enqueue(deltaDist_m);
|
_historicoDeltaDist_m.Enqueue(deltaDist_m);
|
||||||
_historicoDeltaWh.Enqueue(deltaWh);
|
_historicoDeltaWh.Enqueue(deltaWh);
|
||||||
|
|
||||||
_somaDistanciaJanela_m += deltaDist_m;
|
_somaDistanciaJanela_m += deltaDist_m;
|
||||||
_somaEnergiaJanela_Wh += deltaWh;
|
_somaEnergiaJanela_Wh += deltaWh;
|
||||||
|
|
||||||
// Mantém a janela com no máximo JanelaAutonomia_m metros
|
|
||||||
while (_somaDistanciaJanela_m > JanelaAutonomia_m && _historicoDeltaDist_m.Count > 0)
|
while (_somaDistanciaJanela_m > JanelaAutonomia_m && _historicoDeltaDist_m.Count > 0)
|
||||||
{
|
{
|
||||||
double dOld = _historicoDeltaDist_m.Dequeue();
|
_somaDistanciaJanela_m -= _historicoDeltaDist_m.Dequeue();
|
||||||
double whOld = _historicoDeltaWh.Dequeue();
|
_somaEnergiaJanela_Wh -= _historicoDeltaWh.Dequeue();
|
||||||
|
|
||||||
_somaDistanciaJanela_m -= dOld;
|
|
||||||
_somaEnergiaJanela_Wh -= whOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calcula Wh/m médio da janela
|
|
||||||
if (_somaDistanciaJanela_m > 0 && _somaEnergiaJanela_Wh > 0)
|
|
||||||
{
|
|
||||||
WhPorMetro = _somaEnergiaJanela_Wh / _somaDistanciaJanela_m;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WhPorMetro = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WhPorMetro > 0)
|
|
||||||
{
|
|
||||||
// EMA simples
|
|
||||||
double alpha = 0.2; // suavização
|
|
||||||
if (WhPorMetroHistorico <= 0)
|
|
||||||
WhPorMetroHistorico = WhPorMetro;
|
|
||||||
else
|
|
||||||
WhPorMetroHistorico = WhPorMetroHistorico * (1 - alpha) + WhPorMetro * alpha;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// se deltaDist_m <= 0, só não atualiza a janela, mas continua
|
|
||||||
|
|
||||||
// ---------- 2) CÁLCULO DA AUTONOMIA (SEMPRE QUE POSSÍVEL) ----------
|
if (_somaDistanciaJanela_m > 0.5)
|
||||||
double consumoRef_WhPorMetro = WhPorMetroReferencia;
|
WhPorMetroHistorico = _somaEnergiaJanela_Wh / _somaDistanciaJanela_m;
|
||||||
|
|
||||||
if (consumoRef_WhPorMetro > 0 && WhRestante > 0)
|
WhPorMetro = WhPorMetroHistorico > 0 ? WhPorMetroHistorico : WhPorMetroBase;
|
||||||
|
|
||||||
|
if (WhPorMetroReferencia > 0)
|
||||||
{
|
{
|
||||||
DistanciaMaximaTeorica_m = WhRestante / consumoRef_WhPorMetro;
|
DistanciaMaximaTeorica_m = WhRestante / WhPorMetroReferencia;
|
||||||
|
DistanciaMaximaSegura_m = DistanciaMaximaTeorica_m * (1.0 - MargemSegurancaAutonomia);
|
||||||
double margem = FuncoesMatematicas.Clamp(MargemSegurancaAutonomia, 0.0, 0.9);
|
DistanciaEstimadaRestante_m = DistanciaMaximaSegura_m;
|
||||||
DistanciaMaximaSegura_m = DistanciaMaximaTeorica_m * (1.0 - margem);
|
|
||||||
if (DistanciaMaximaSegura_m < 0)
|
|
||||||
DistanciaMaximaSegura_m = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DistanciaMaximaTeorica_m = 0;
|
DistanciaMaximaTeorica_m = 0;
|
||||||
DistanciaMaximaSegura_m = 0;
|
DistanciaMaximaSegura_m = 0;
|
||||||
|
DistanciaEstimadaRestante_m = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Distância estimada restante = distância segura
|
|
||||||
DistanciaEstimadaRestante_m = DistanciaMaximaSegura_m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private void ResetarHistoricosAutonomia()
|
||||||
/// Permite restaurar o valor consumido (em Ah) de um log salvo, por exemplo.
|
|
||||||
/// Atualiza também CargaAtual.
|
|
||||||
/// </summary>
|
|
||||||
public void AtualizarValorConsumido(double _consumo_Ah)
|
|
||||||
{
|
{
|
||||||
double coulombsConsumidos = _consumo_Ah * 3600;
|
_historicoCorrente.Clear();
|
||||||
Consumido = FuncoesMatematicas.Clamp(coulombsConsumidos, 0, CargaMaxima);
|
|
||||||
CargaAtual = CargaMaxima - Consumido;
|
_historicoDeltaDist_m.Clear();
|
||||||
|
_historicoDeltaWh.Clear();
|
||||||
|
_somaDistanciaJanela_m = 0;
|
||||||
|
_somaEnergiaJanela_Wh = 0;
|
||||||
|
|
||||||
|
_distanciaTotalMetrosAnterior = 0;
|
||||||
|
_energiaConsumidaAnterior_Wh_Total = EnergiaConsumidaTotal_Wh;
|
||||||
|
|
||||||
|
WhPorMetro = 0;
|
||||||
|
WhPorMetroHistorico = 0;
|
||||||
|
DistanciaMaximaTeorica_m = 0;
|
||||||
|
DistanciaMaximaSegura_m = 0;
|
||||||
|
DistanciaEstimadaRestante_m = 0;
|
||||||
|
|
||||||
|
TempoEstimadoMinutos = 0;
|
||||||
|
_dt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AtualizarValorConsumidoTotal(double consumoTotal_Ah)
|
||||||
|
{
|
||||||
|
double coulombsConsumidos = consumoTotal_Ah * 3600.0;
|
||||||
|
ConsumidoTotal_C = FuncoesMatematicas.Clamp(coulombsConsumidos, 0, CargaMaxima_C);
|
||||||
|
|
||||||
|
if (_estadoInicializado)
|
||||||
|
{
|
||||||
|
double cargaAtualCalculada = _cargaInicialInstancia_C - ConsumidoTotal_C;
|
||||||
|
CargaAtual_C = FuncoesMatematicas.Clamp(cargaAtualCalculada, 0, CargaMaxima_C);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Helper para o Manager/Health: indica se, com a situação atual,
|
|
||||||
/// o robô consegue percorrer uma certa distância em metros.
|
|
||||||
/// </summary>
|
|
||||||
public bool ConseguePercorrer(double distanciaRequerida_m)
|
public bool ConseguePercorrer(double distanciaRequerida_m)
|
||||||
{
|
{
|
||||||
if (distanciaRequerida_m <= 0)
|
if (distanciaRequerida_m <= 0)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue