adicionado logica para confirmar continuacao da operacao de acordo com autonomia

This commit is contained in:
Diego Freitas 2025-12-10 13:37:47 -03:00
parent f00ca573b8
commit 7b9b815308
50 changed files with 2686 additions and 2213 deletions

4
.gitignore vendored
View File

@ -50,6 +50,10 @@ Thumbs.db
# Ignorar arquivos de build
AgroBase/AgroBase/obj/
AgroBase/AgroBase/bin/
AgroBase/AgroMnitor/obj/
AgroBase/AgroMnitor/bin/
AgroBase/OperationControl/obj/
AgroBase/OperationControl/bin/
Python/OAK/datasets/venv/
Python/OAK/datasets/oak-1/dataset/

Binary file not shown.

View File

@ -75,7 +75,8 @@
Bat = 119,
Npc = 120,
Ipb = 121,
Can = 122
Can = 122,
Trj = 123
}
public enum F_Code

View File

@ -767,8 +767,12 @@ namespace AgroBase
if (Bico != null)
{
//Console.WriteLine($"Bico {Bico.Posicao} atualizado de {Bico.ComandoAtuar} para {Status}");
if (Status != null) Bico.ComandoAtuar = (bool)Status;
if (Valor != null) Bico.AnguloControle = (int)Valor;
if (Status != null)
{
Bico.ComandoAtuar = (bool)Status;
if (Bico.ComandoAtuar) Bico.Atuacoes++;
}
(id_num, posicao, data) = Bico.ProtocoloComando();
}
break;

View File

@ -30,7 +30,9 @@ namespace AgroBase.Models.Modules
{
get
{
return DadosLeitura.Conectado;
DateTime Agora = DateTime.Now;
bool modConectado = DadosLeitura.UltimoComandoRespondido.AddMilliseconds(TempoLimiteConexao) > Agora;
return modConectado;
}
}
public bool ConexaoAtiva
@ -330,9 +332,9 @@ namespace AgroBase.Models.Modules
{
Descricao = "Offset",
Enviar = true,
Escalar = false,
Escalar = true,
QtdBytes = 2,
Valor = "1895800"
Valor = "32.5"
}
},
ValoresLeituras = new List<SensorValoresLeituraModel>()

View File

@ -33,7 +33,9 @@ namespace AgroBase.Models.Modules
{
get
{
return DadosLeitura.Conectado;
DateTime Agora = DateTime.Now;
bool modConectado = DadosLeitura.UltimoComandoRespondido.AddMilliseconds(TempoLimiteConexao) > Agora;
return modConectado;
}
}
public bool ConexaoAtiva

View File

@ -1525,7 +1525,7 @@ namespace AgroBase.Models
{
case BotoesJoystick.Share: // Requisitar parametros da operacao
var topico = Variaveis.MqttServiceBase.Topicos.FirstOrDefault(x => x.Topico == VariaveisEquipamento.TopicoMqttParametros.Replace("<id>", VariaveisEquipamento.Parametros.serial_number));
var msg = JsonConvert.SerializeObject(Variaveis.OperacaoEmAndamento.Parametros);
string msg = JsonConvert.SerializeObject(Variaveis.OperacaoEmAndamento.Parametros);
Task.Run(async () => await Variaveis.MqttServiceBase.PublishAsync(topico, msg));
break;
case BotoesJoystick.Options: // Operacao nao iniciada, carrega todos os parametros compeltos
@ -1560,6 +1560,13 @@ namespace AgroBase.Models
if (Variaveis.OperacaoEmAndamento.Iniciado)
Task.Run(async () => await Variaveis.OperacaoEmAndamento.FinalizarOperacao());
break;
case BotoesJoystick.R1: // Libera a operacao interrompida mediante supervisao humana
if (!(Variaveis.OperacaoEmAndamento.Trajetoria?.AutonomiaCorredor?.Liberado ?? false))
{
(bool b_liberada, bool h_liberado) = ((bool, bool))controleBase._comp_value;
Variaveis.OperacaoEmAndamento.Trajetoria?.AtualizarDadosAutonomiaCorredor(bat_liberada: b_liberada, herb_liberado: h_liberado);
}
break;
}
return;
}
@ -1688,7 +1695,8 @@ namespace AgroBase.Models
else
{
topico = Variaveis.MqttServiceBase.Topicos.FirstOrDefault(x => x.Topico == VariaveisEquipamento.TopicoMqttTelemetria.Replace("<id>", VariaveisEquipamento.Parametros.serial_number));
msg = JsonConvert.SerializeObject(Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura);
var data = Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.Clone();
msg = JsonConvert.SerializeObject(data);
}
if (topico != null && !string.IsNullOrEmpty(msg))
{
@ -2154,7 +2162,7 @@ namespace AgroBase.Models
return new OperacaoControleModel()
{
Angulo = Angulo,
BicosAtuados = BicosAtuados.Select(x => x.Clone()).ToList(),
BicosAtuados = new List<AtuadorBicoModel>(BicosAtuados ?? new List<AtuadorBicoModel>()),
Direcao = Direcao,
PercentualVelocidadeSP = PercentualVelocidadeSP,
_tipoMovimento = _tipoMovimento,
@ -2362,6 +2370,20 @@ namespace AgroBase.Models
LPorMinuto = _Reservatorio.LPorMinuto,
TempoEstimadoRestanteMinutos = _Reservatorio.TempoEstimadoMinutosPulverizando,
DistanciaEstimadaRestanteMetros = _Reservatorio.DistanciaEstimadaRestantePulverizando_m,
Bicos = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BicosPulverizadores.Select(Bico => new AtuBicoSensoriamentoLogModel()
{
ID = Bico.ID,
Inicializado = Bico.Inicializado,
Comandar = Bico.Comandar,
Atuado = Bico.ComandoAtuar,
MediaNivelFluxo = Bico.MediaNivelFluxo,
Posicao = Bico.Posicao,
StatusBico = Bico.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor == Estado.Ligado,
Atuacoes = Bico.Atuacoes,
TempoAtuado = Bico.TempoAtuado,
AnguloAbertura = Bico.AnguloAbertura,
AnguloControle = Bico.AnguloControle,
}).ToList(),
} : new OperacaoSensoriamentoLogAtuModel();
var dadosMovimentacao = _DispMvd != null ? new OperacaoSensoriamentoLogMovModel()
@ -2472,6 +2494,7 @@ namespace AgroBase.Models
DistanciaErroMapaCana = _Trajetoria?.DistanciaErroMapaPlantacao ?? 0,
PrimeiroPontoDentroMapa = _Trajetoria?.PrimeiroPontoDentroMapa?.Clone() ?? new GPSModel(),
PrimeiroPontoDentroCana = _Trajetoria?.PrimeiroPontoDentroCana?.Clone() ?? new GPSModel(),
AutonomiaCooredor = _Trajetoria?.AutonomiaCorredor?.Clone(),
};
var dadosGps = GPSService.UltimaLeitura.Clone();
@ -2640,6 +2663,7 @@ namespace AgroBase.Models
public double TempoEstimadoRestanteMinutos { get; set; }
public double DistanciaEstimadaRestanteMetros { get; set; }
public Dictionary<string, bool> Iniciados { get; set; }
public List<AtuBicoSensoriamentoLogModel> Bicos { get; set; }
public DateTime UltimoComandoRespondido { get; set; }
public OperacaoSensoriamentoLogAtuModel Clone()
@ -2671,7 +2695,8 @@ namespace AgroBase.Models
LPorMetro = LPorMetro,
LPorMinuto = LPorMinuto,
TempoEstimadoRestanteMinutos = TempoEstimadoRestanteMinutos,
DistanciaEstimadaRestanteMetros = DistanciaEstimadaRestanteMetros
DistanciaEstimadaRestanteMetros = DistanciaEstimadaRestanteMetros,
Bicos = new List<AtuBicoSensoriamentoLogModel>(Bicos ?? new List<AtuBicoSensoriamentoLogModel>())
};
}
}
@ -2828,6 +2853,8 @@ namespace AgroBase.Models
public GPSModel PrimeiroPontoDentroCana { get; set; }
public double DistanciaErroMapaCana { get; set; }
public AutonomiaCorredorModel AutonomiaCooredor { get; set; }
public OperacaoSensoriamentoLogTrajetoriaModel Clone()
{
return new OperacaoSensoriamentoLogTrajetoriaModel()
@ -2861,7 +2888,8 @@ namespace AgroBase.Models
QtdPontos = QtdPontos,
PrimeiroPontoDentroCana = PrimeiroPontoDentroCana.Clone(),
PrimeiroPontoDentroMapa = PrimeiroPontoDentroMapa.Clone(),
DistanciaErroMapaCana = DistanciaErroMapaCana
DistanciaErroMapaCana = DistanciaErroMapaCana,
AutonomiaCooredor = AutonomiaCooredor.Clone()
};
}
}
@ -2944,6 +2972,8 @@ namespace AgroBase.Models
public double MediaNivelFluxo { get; set; }
public int Atuacoes { get; set; }
public double TempoAtuado { get; set; }
public double AnguloAbertura { get; set; }
public double AnguloControle { get; set; }
}
public class CamSoloSensoriamentoLogModel

View File

@ -32,6 +32,8 @@ namespace AgroBase.Models
#endregion
public DateTime UltimaAtualizacaoDados { get; set; } = DateTime.MinValue;
public AutonomiaCorredorModel AutonomiaCorredor = new AutonomiaCorredorModel();
[JsonProperty]
public double TempoEntreLeituras { get; private set; }
private void AtualizarTempoEntreLeituras()
@ -191,11 +193,15 @@ namespace AgroBase.Models
if ((CorredorAtual?.Idx ?? 0) != idxNovoCorredor)
{
CorredorAtual?.AtualizarDados();
AtualizarDadosAutonomiaCorredor(idxCorredor: idxNovoCorredor);
}
CorredorAtual = _Corredores[idxNovoCorredor];
CorredorAtual.AtualizarDados();
if (AutonomiaCorredor.Liberado)
{
CorredorAtual = _Corredores[idxNovoCorredor];
CorredorAtual.AtualizarDados();
}
}
public DirecaoCarroRua DirecaoCaminho
{
@ -634,6 +640,8 @@ namespace AgroBase.Models
{
if (!_TrajetoriaFixaDefinida) return;
AtualizarDadosAutonomiaCorredor();
AtualizarTempoEntreLeituras();
AtualizarDistanciaMaximaEntreLeituras();
@ -645,6 +653,8 @@ namespace AgroBase.Models
DefinirPontoAtual();
AtualizarCorredorAtual();
//if (AutonomiaCorredor.Liberado)
DefinirProximoPonto();
if (PontoAtual == null) goto Inicio;
@ -835,7 +845,15 @@ namespace AgroBase.Models
}
}
public void AtualizarDadosAutonomiaCorredor(int? idxCorredor = null, bool? bat_liberada = null, bool? herb_liberado = null)
{
if (idxCorredor == null) idxCorredor = CorredorAtual?.Idx ?? 0;
if (bat_liberada == null) bat_liberada = Variaveis.OperacaoEmAndamento.Simulando;
if (herb_liberado == null) herb_liberado = Variaveis.OperacaoEmAndamento.Simulando;
AutonomiaCorredor.AtualizarDados((int)idxCorredor, (bool)bat_liberada, (bool)herb_liberado);
}
public void LoopAtualizaDados()
{
@ -1753,7 +1771,8 @@ namespace AgroBase.Models
if (qtdPontos == 1)
{
//DistanciaTrajeto = pontoAtual.Aproximando ? pontoAtual.DistanciaAtual : -pontoAtual.DistanciaAtual;
DistanciaTrajeto = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Trajetoria._TrajetoriaDinamica.First().Posicao, Posicao);
//DistanciaTrajeto = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Trajetoria._TrajetoriaDinamica.First().Posicao, Posicao);
DistanciaTrajeto = GPSUtils.DistanciaEntrePontos(Variaveis.OperacaoEmAndamento.Trajetoria._TrajetoriaFixa.Where(x => !x.Visitado).First().Posicao, Posicao);
return;
}
@ -1833,4 +1852,130 @@ namespace AgroBase.Models
}
}
public enum AutonomiaCorredorStatus
{
Desconhecido = 0,
OkCompleto, // Bateria + herbicida suficientes pra entrar e pulverizar
OkSomenteTransito, // Bateria ok, herbicida insuficiente pra pulverizar tudo
OkSupervisionado, // Liberado manualmente
Critico // Nem a bateria garante atravessar com segurança
}
public class AutonomiaCorredorModel
{
public AutonomiaCorredorStatus Status { get; private set; }
private bool _liberado =>
Status == AutonomiaCorredorStatus.OkCompleto ||
Status == AutonomiaCorredorStatus.OkSomenteTransito ||
Status == AutonomiaCorredorStatus.OkSupervisionado;
public bool Liberado { get; private set; }
public double DistanciaCorredor_m { get; private set; }
public double DistanciaSeguraBateria_m { get; private set; }
public double DistanciaSeguraHerbicida_m { get; private set; }
private Dictionary<int, AutonomiaCorredorModel> CorredoresLiberados { get; set; } = new Dictionary<int, AutonomiaCorredorModel>();
// Flags de conveniência
public bool BateriaSuficiente => DistanciaSeguraBateria_m >= DistanciaCorredor_m;
public bool HerbicidaSuficiente => DistanciaSeguraHerbicida_m >= DistanciaCorredor_m;
// Texto pra UI/log
public string Motivo { get; private set; } = "";
public void AtualizarDados(int idxCorredor, bool bateria_liberada, bool reservatorio_liberado)
{
if (Variaveis.OperacaoEmAndamento.Trajetoria?._Corredores?.Count <= idxCorredor)
return;
double distanciaCorredor = Variaveis.OperacaoEmAndamento.Trajetoria._Corredores[idxCorredor]?.DistanciaTotal ?? 0;
var _Bateria = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.ContadorCarga;
var _Reservatorio = Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.ContadorCarga;
DistanciaCorredor_m = distanciaCorredor;
DistanciaSeguraBateria_m = _Bateria?.DistanciaEstimadaRestante_m ?? 0;
DistanciaSeguraHerbicida_m = _Reservatorio?.DistanciaEstimadaRestantePulverizando_m ?? 0;
bool bateriaOk = BateriaSuficiente && (_Bateria?.Iniciado ?? false);
bool herbOk = HerbicidaSuficiente && (_Reservatorio?.Iniciado ?? false);
bool exigirPulverizacaoTotal = Variaveis.OperacaoEmAndamento.Parametros?.ModulosMandatorios?.Any(x => x.Dispositivo == T_Code.Atu && x.Mandatorio && x.Utilizar) ?? false;
List<AutonomiaCorredorStatus> status_mods = new List<AutonomiaCorredorStatus>();
string _motivo = "";
string _motivo_bat = "Bateria " + (bateriaOk ? "suficiente" : "insuficiente") + $". Distância segura: {DistanciaSeguraBateria_m:F1} m, corredor: {distanciaCorredor:F1} m";
string _motivo_herb = "Herbicida " + (herbOk ? "suficiente" : "insuficiente") + $" para pulverizar o corredor. Distância segura pulverizando: {DistanciaSeguraHerbicida_m:F1} m, corredor: {distanciaCorredor:F1} m";
if (!bateriaOk)
{
status_mods.Add(!bateria_liberada ? AutonomiaCorredorStatus.Critico : AutonomiaCorredorStatus.OkSupervisionado);
if (bateria_liberada) _motivo_bat = $"Liberação humana: {_motivo_bat}";
_motivo += _motivo_bat;
}
if (!herbOk)
{
if (exigirPulverizacaoTotal)
status_mods.Add(!reservatorio_liberado ? AutonomiaCorredorStatus.Critico : AutonomiaCorredorStatus.OkSupervisionado);
else
status_mods.Add(AutonomiaCorredorStatus.OkSomenteTransito);
if (reservatorio_liberado) _motivo_herb = $"Liberação humana: {_motivo_herb}";
_motivo += (string.IsNullOrEmpty(_motivo) ? "" : "; ") + _motivo_herb;
}
Status =
status_mods.Contains(AutonomiaCorredorStatus.Critico) ? AutonomiaCorredorStatus.Critico :
status_mods.Contains(AutonomiaCorredorStatus.OkSupervisionado) ? AutonomiaCorredorStatus.OkSupervisionado :
status_mods.Contains(AutonomiaCorredorStatus.OkSomenteTransito) ? AutonomiaCorredorStatus.OkSomenteTransito :
AutonomiaCorredorStatus.OkCompleto;
var res = new AutonomiaCorredorModel()
{
Liberado = _liberado,
Motivo = $"Corredor {idxCorredor + 1}: " + (string.IsNullOrEmpty(_motivo) ? "Liberado" : $"{_motivo}"),
Status = Status,
DistanciaCorredor_m = DistanciaCorredor_m,
DistanciaSeguraBateria_m = DistanciaSeguraBateria_m,
DistanciaSeguraHerbicida_m = DistanciaSeguraHerbicida_m,
};
bool addLog = false;
if (CorredoresLiberados.ContainsKey(idxCorredor))
{
if (CorredoresLiberados[idxCorredor].Liberado == false && _liberado)
{
CorredoresLiberados[idxCorredor] = res;
addLog = true;
}
}
else
{
CorredoresLiberados.Add(idxCorredor, res);
addLog = true;
}
if (addLog)
{
Variaveis.OperacaoEmAndamento.Parametros.DadosLeitura.InserirLog(T_Code.Trj, _liberado ? StatusModulo.Operante : StatusModulo.Alerta, _liberado ? 100 : 0, res.Motivo);
}
Liberado = CorredoresLiberados[idxCorredor].Liberado;
Motivo = CorredoresLiberados[idxCorredor].Motivo;
}
public AutonomiaCorredorModel Clone()
{
return new AutonomiaCorredorModel()
{
Liberado = Liberado,
Motivo = Motivo,
Status = Status,
DistanciaCorredor_m = DistanciaCorredor_m,
DistanciaSeguraBateria_m = DistanciaSeguraBateria_m,
DistanciaSeguraHerbicida_m = DistanciaSeguraHerbicida_m,
};
}
}
}

View File

@ -144,6 +144,10 @@ namespace AgroBase.Services.Operadores
dist_dir = _t.DistanciaDireita,
angulo = _t.AnguloMedioCorredor,
pontos_restantes = _t.CorredorAtual.QtdPontos - pontoComparar.idxPontoCorredor,
liberado = _t.AutonomiaCooredor.Liberado,
motivo = _t.AutonomiaCooredor.Motivo,
bateria_ok = _t.AutonomiaCooredor.BateriaSuficiente,
herbicida_ok = _t.AutonomiaCooredor.HerbicidaSuficiente
},
} : null
),
@ -594,6 +598,16 @@ namespace AgroBase.Services.Operadores
("last_ec", DadosCan.UltimoErroCritico)
);
var DadosTrj = _Sensoriamento?.Trajetoria;
RedisService.AtualizarCampos(RedisService.ModKey(Enums.T_Code.Trj),
("timestamp", agora),
("carregado", DadosTrj?.QtdPontos > 0),
("liberado", DadosTrj?.AutonomiaCooredor?.Liberado ?? false),
("bateria_ok", DadosTrj?.AutonomiaCooredor?.BateriaSuficiente ?? false),
("herbicida_ok", DadosTrj?.AutonomiaCooredor?.HerbicidaSuficiente ?? false),
("motivo", DadosTrj?.AutonomiaCooredor?.Motivo)
);
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -18,6 +18,7 @@ def main():
from health_worker.modulos.livox import ModuloLivox
from health_worker.modulos.ponte_ip import ModuloIPBribge
from health_worker.modulos.can import ModuloCAN
from health_worker.modulos.trajetoria import ModuloTrajetorira
from health_worker.config import mostrar_log
from shared.contexto_global_redis import ContextoGlobalRedis, CmdKey, CtxKey
@ -33,6 +34,7 @@ def main():
T_Code.Lvx: ModuloLivox(),
T_Code.Ipb: ModuloIPBribge(),
T_Code.Can: ModuloCAN(),
T_Code.Trj: ModuloTrajetorira(),
}
def loop_ativo():

View File

@ -206,8 +206,10 @@ class ModuloAtuador(ModuloDiagnosticoBase):
cond_op_mod = []
penalidade_percentual_herbicida = 0
if sensor_massa_ativado:
_contexto = ContextoGlobalRedis.get_contexto()
herbicida_suficiente_corredor = _contexto.get("Trajetoria", {}).get("CorredorAtual", {}).get("herbicida_ok", True)
percent_atual = round(_contexto.get("Gerais", {}).get("percentual_reservatorio", 0.0), 2)
percent_min = ContextoGlobalRedis.get_equipamento().get("percentual_reservatorio_min", 5.0)
percent_atual = round(ContextoGlobalRedis.get_contexto().get("Gerais", {}).get("percentual_reservatorio", 0.0), 2)
if percent_atual < percent_min:
penalidade_percentual_herbicida = 50
cond_op_mod.append({
@ -222,6 +224,14 @@ class ModuloAtuador(ModuloDiagnosticoBase):
"severidade": 30,
"descricao": f"Nível do reservatório de herbicida baixo!"
})
if not herbicida_suficiente_corredor:
penalidade_percentual_herbicida = 21
_motivo_herb = _contexto.get("Trajetoria", {}).get("CorredorAtual", {}).get("motivo", "Herbicida insuficiente")
cond_op_mod.append({
"valor": percent_atual,
"severidade": 30,
"descricao": _motivo_herb
})
else:
cond_op_mod.append({
"valor": 0,

View File

@ -146,8 +146,10 @@ class ModuloSensoriamento(ModuloDiagnosticoBase):
cond_op_mod = []
penalidade_percentual_bateria = 0
if sensor_bateria_ativado:
_contexto = ContextoGlobalRedis.get_contexto()
bateria_suficiente_corredor = _contexto.get("Trajetoria", {}).get("CorredorAtual", {}).get("bateria_ok", True)
percent_atual = _contexto.get("Gerais", {}).get("percentual_bateria", 0.0)
percent_min = ContextoGlobalRedis.get_equipamento().get("percentual_tensao_bateria_min", 5.0)
percent_atual = ContextoGlobalRedis.get_contexto().get("Gerais", {}).get("percentual_bateria", 0.0)
if percent_atual < percent_min:
penalidade_percentual_bateria = 70
cond_op_mod.append({
@ -162,6 +164,14 @@ class ModuloSensoriamento(ModuloDiagnosticoBase):
"severidade": 30,
"descricao": f"Nível da bateria baixo!"
})
if not bateria_suficiente_corredor:
penalidade_percentual_bateria = 25
_motivo_bat = _contexto.get("Trajetoria", {}).get("CorredorAtual", {}).get("motivo", "Bateria insuficiente")
cond_op_mod.append({
"valor": percent_atual,
"severidade": 30,
"descricao": _motivo_bat
})
else:
cond_op_mod.append({
"valor": 0,

View File

@ -205,12 +205,14 @@ class ContextoGlobalRedis:
@classmethod
def _atualizar_operacao_liberada(cls):
_operacao = cls.get_operacao()
_contexto = cls.get_contexto()
# 🔹 Conjuntos de módulos
modulos_mandatorios = set(_operacao.get("modulos_mandatorios", []))
modulos_opcionais = set(_operacao.get("modulos_opcionais", []))
emergencia = _operacao.get("emergencia", False)
pausa = _operacao.get("pausa", False)
trajetoria_liberada = _contexto.get("Trajetoria", {}).get("CorredorAtual", {}).get("liberado", False)
modulos_presentes = set()
status_modulos = []
@ -371,7 +373,14 @@ class ContextoGlobalRedis:
pausa_ok = False
motivos_dos_modulos_mandatorios.append(f"Operação pausada.")
liberou = (base_ok and parametros_ok and emergencia_ok and pausa_ok) or debug_mode
trajetoria_ok = True
if not trajetoria_liberada:
trajetoria_ok = False
_motivo_traj = _contexto.get("Trajetoria", {}).get("CorredorAtual", {}).get("motivo")
if _motivo_traj:
motivos_dos_modulos_mandatorios.append(_motivo_traj)
liberou = (base_ok and parametros_ok and emergencia_ok and pausa_ok and trajetoria_ok) or debug_mode
cls.atualizar_ctx_dict(
CtxKey.DadosOperacao,

View File

@ -74,7 +74,8 @@ class T_Code(IntEnum):
Bat = 119,
Npc = 120,
Ipb = 121,
Can = 122
Can = 122,
Trj = 123
class ParametrosOperacao(IntEnum):
CameraSolo = 1

View File

@ -331,6 +331,17 @@ namespace OperationControl.Models
});
}
public static void EnviarConfirmacaoHumanaTrajetoria(bool bat_liberada, bool herb_liberado)
{
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()
{
Momento = DateTime.Now,
Dispositivo = AgroBase.Models.Enums.T_Code.Mod,
Tecla = AgroBase.Models.Enums.BotoesJoystick.R1,
_comp_value = (bat_liberada, herb_liberado)
});
}
public static void RequisitarParametrosOperacao()
{
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()

View File

@ -153,6 +153,7 @@
<Label x:Name="lblDiagnosticos_NPC" Content="🔒NCP" Style="{StaticResource RoundedLabel}" Height="21" Width="40" Canvas.Left="202" Canvas.Top="244" HorizontalAlignment="Center" VerticalAlignment="Top"/>
<Label x:Name="lblDiagnosticos_CAN" Content="🔒CAN" Style="{StaticResource RoundedLabel}" Height="21" Width="40" Canvas.Left="398" Canvas.Top="192" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Label x:Name="lblDiagnosticos_IPB" Content="🔒LAN" Style="{StaticResource RoundedLabel}" Height="21" Width="40" Canvas.Left="398" Canvas.Top="218" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Label x:Name="lblDiagnosticos_TRJ" Content="🔒TRAJ" Style="{StaticResource RoundedLabel}" Height="21" Width="40" Canvas.Left="398" Canvas.Top="244" HorizontalAlignment="Center" VerticalAlignment="Top"/>
<Label x:Name="lblDiagnosticos_ATU_BOMBA" Tag="sBMB" Content="🔒BMB" Style="{StaticResource RoundedLabel}" Height="21" Width="40" Canvas.Left="202" Canvas.Top="309" HorizontalAlignment="Center" VerticalAlignment="Top"/>
<Label x:Name="lblDiagnosticos_ATU" Tag="sMOD" Content="🔒ATU" Style="{StaticResource RoundedLabel}" Height="21" Width="40" Canvas.Left="202" Canvas.Top="349" HorizontalAlignment="Center" VerticalAlignment="Top"/>
<Label x:Name="lblDiagnosticos_ATU_PRSLN" Tag="sPRS" Content="🔒PRS" Style="{StaticResource RoundedLabel}" Height="21" Width="40" Canvas.Left="202" Canvas.Top="386" HorizontalAlignment="Center" VerticalAlignment="Top"/>
@ -523,6 +524,61 @@
</UniformGrid>
</StackPanel>
<!-- Painel especifico de TRJ -->
<StackPanel x:Name="panelOpcoes_Trajetoria" Grid.Row="0" Visibility="Collapsed">
<StackPanel Orientation="Horizontal">
<Label Content="Status do trabalho"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="5">
<CheckBox x:Name="chbTrajetoria_BatLiberada" Content="Bateria Liberada" Margin="5"/>
<CheckBox x:Name="chbTrajetoria_HerbLiberado" Content="Pulverizador Liberado" Margin="5"/>
<Button x:Name="btnTrajetoria_Confirmar" Content="Confirmar" Width="60" Height="20" Margin="5 0 5 0" Click="btnTrajetoria_Confirmar_Click"/>
</StackPanel>
<!-- “Cartõezinhos” de status -->
<UniformGrid Rows="2" Columns="3" Margin="0,0,0,0">
<Border BorderBrush="Gray" BorderThickness="1" Margin="2" Padding="3">
<StackPanel>
<TextBlock Text="Distancia Corredor" FontSize="9" FontWeight="Bold"/>
<TextBlock x:Name="txtTrajetoria_DistCorredor" FontSize="10" Text="0,00 m"/>
</StackPanel>
</Border>
<Border BorderBrush="Gray" BorderThickness="1" Margin="2" Padding="3">
<StackPanel>
<TextBlock Text="Distancia Segura Bateria" FontSize="9" FontWeight="Bold"/>
<TextBlock x:Name="txtTrajetoria_DistBateria" FontSize="10" Text="0,00 m"/>
</StackPanel>
</Border>
<Border BorderBrush="Gray" BorderThickness="1" Margin="2" Padding="3">
<StackPanel>
<TextBlock Text="Distancia Segura Pulverizador" FontSize="9" FontWeight="Bold"/>
<TextBlock x:Name="txtTrajetoria_DistPulverizador" FontSize="10" Text="0,00 m"/>
</StackPanel>
</Border>
<Border BorderBrush="Gray" BorderThickness="1" Margin="2" Padding="3">
<StackPanel>
<TextBlock Text="Status" FontSize="9" FontWeight="Bold"/>
<TextBlock x:Name="txtTrajetoria_Status" FontSize="10" Text="OkCompleto"/>
</StackPanel>
</Border>
<Border BorderBrush="Gray" BorderThickness="1" Margin="2" Padding="3">
<StackPanel>
<TextBlock Text="Bateria Suficiente" FontSize="9" FontWeight="Bold"/>
<TextBlock x:Name="txtTrajetoria_BatOk" FontSize="10" Text="Sim"/>
</StackPanel>
</Border>
<Border BorderBrush="Gray" BorderThickness="1" Margin="2" Padding="3">
<StackPanel>
<TextBlock Text="Herbicida Suficiente" FontSize="9" FontWeight="Bold"/>
<TextBlock x:Name="txtTrajetoria_HerbOk" FontSize="10" Text="Sim"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
</Grid>
</TabItem>
@ -597,7 +653,7 @@
<Border Name="brdMapaInfo" BorderBrush="Black" BorderThickness="1" Height="26" Width="980" Canvas.Top="878" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="465,898,0,0">
<Canvas>
<Label x:Name="lblMapaInfo_Debug" Content="Próximo Ponto: 0 | Parado | Distância próximo ponto: 0,00 m | Distância ponto anterior: 0,00 m | Corredor: Fora | Margem: Não | Disância Esquerda: 0 cm | Distância Direita: 0 cm | Status: Parado" FontSize="9" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="1"/>
<Label x:Name="lblMapaInfo_Debug" Content="Status: Desconhecido | Próximo Ponto: 0 | Parado | Distância próximo ponto: 0,00 m | Distância ponto anterior: 0,00 m | Corredor: Fora | Margem: Não | Carro: Parado" FontSize="9" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="1"/>
</Canvas>
</Border>

View File

@ -19,6 +19,7 @@ using AgroBase.Models.Operadores;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Threading;
using AgroBase.Models.Operacoes;
namespace OperationControl.Windows
{
@ -410,20 +411,47 @@ namespace OperationControl.Windows
continue;
// Procura a saúde desse módulo
var saude = dados.DadosLeitura.ModulosSaude?.FirstOrDefault(x => x.modulo == modulo);
if (saude == null && false)
var _saude = dados.DadosLeitura.ModulosSaude?.FirstOrDefault(x => x.modulo == modulo);
if (_saude == null && false)
continue;
var individual = saude?.saude_individual?.FirstOrDefault(x => x.label == mod_label);
var individual = _saude?.saude_individual?.FirstOrDefault(x => x.label == mod_label);
bool em_uso = mod_label != "" ? dados.DadosLeitura.ModulosMandatorios?.FirstOrDefault(x => x.Dispositivo == modulo)?.ComponentesEmUso?.Any(x => x.Key == mod_label && x.Value) ?? false : dados.ModulosMandatorios?.Any(x => x.Dispositivo == modulo && x.Utilizar) ?? false;
// Aplica cor de acordo com o status
AplicarStatusModuloNaLabel(lbl, individual?.status ?? saude?.status ?? AgroBase.Models.Enums.StatusModulo.Desconectado, em_uso);
AplicarStatusModuloNaLabel(lbl, individual?.status ?? _saude?.status ?? AgroBase.Models.Enums.StatusModulo.Desconectado, em_uso);
if (lbl.Name == _labelModuloSelecionado.Name)
{
PreencherAbaAcompanhamento(false);
PreencherAbaOpcoes(false);
var rover = VariaveisControleOperacao.RoverEmFoco;
var saude = rover?.DadosLeitura?.ModulosSaude?.FirstOrDefault(x => x.modulo == modulo);
PreencherAbaCondicoesOperacionais(saude?.condicoes_operacionais);
var logs = rover?.DadosLeitura?.Logs?.Where(x => x.Dispositivo == modulo);
if (!string.IsNullOrEmpty(mod_label))
logs = logs?.Where(x => x.ID == mod_label);
else
logs = logs?.Where(x => x.ID == null);
PreencherAbaLogs(logs);
}
}
PreencherAbaAcompanhamento(false);
PreencherAbaOpcoes(false);
/*(var modulo, var label, var s_code, var iniciado) = GetModuleData(_labelModuloSelecionado);
if (modulo == AgroBase.Models.Enums.T_Code.Vzo)
return;
var rover = VariaveisControleOperacao.RoverEmFoco;
var saude = rover?.DadosLeitura?.ModulosSaude?.FirstOrDefault(x => x.modulo == modulo);
PreencherAbaCondicoesOperacionais(saude?.condicoes_operacionais);
var logs = rover?.DadosLeitura?.Logs?.Where(x => x.Dispositivo == modulo);
if (!string.IsNullOrEmpty(label))
logs = logs?.Where(x => x.ID == label);
else
logs = logs?.Where(x => x.ID == null);
PreencherAbaLogs(logs);*/
}
private void AplicarStatusModuloNaLabel(Label lbl, AgroBase.Models.Enums.StatusModulo status, bool mandatorio, bool icone = true)
@ -528,6 +556,14 @@ namespace OperationControl.Windows
case AgroBase.Models.Enums.T_Code.Gps:
iniciado = rover.DadosLeitura?.DispositivosMapeados?.FirstOrDefault(x => x.Dispositivo == modulo)?.Saude > 0;
break;
case AgroBase.Models.Enums.T_Code.Bat:
iniciado = rover.DadosLeitura?.Bateria?.Iniciado ?? false;
mod_label = "Bateria";
break;
case AgroBase.Models.Enums.T_Code.Trj:
iniciado = rover.DadosLeitura?.Trajetoria?.QtdPontos > 0;
mod_label = "Trajetória";
break;
}
}
@ -600,10 +636,13 @@ namespace OperationControl.Windows
DateTime mom = rover.DadosLeitura?.Momento ?? DateTime.MinValue;
double can_latencia = (ucr - mom).TotalMilliseconds;
AgroBase.Models.Enums.StatusModulo _status = individual?.status ?? saude?.status ?? AgroBase.Models.Enums.StatusModulo.Desconectado;
double _saude = individual?.saude ?? saude?.saude ?? 0;
lblSaude_Descricao.Content = $"Módulo {modulo} {label}";
lblSaude_Iniciado.Content = (iniciado ? "Iniciado" : "Não Iniciado");
lblSaude_Iniciado.Foreground = new SolidColorBrush(iniciado ? System.Windows.Media.Colors.Green : System.Windows.Media.Colors.Red);
lblSaude_Status.Content = $"{individual?.status ?? saude?.status ?? AgroBase.Models.Enums.StatusModulo.Desconectado} (Saúde {individual?.saude ?? saude?.saude ?? 0}%)";
lblSaude_Status.Content = $"{_status} (Saúde {_saude}%)";
lblSaude_CAN.Content = $"CAN {can_latencia:0} ms";
lblSaude_Latencia.Content = $"Latência {dispositivo?.Latencia ?? 0} ms";
lblSaude_Impedimento.Text = $"Impedimento: {motivos ?? "Nenhum"}";
@ -622,9 +661,9 @@ namespace OperationControl.Windows
PreencherAbaOpcoes(true);
var logs = rover.DadosLeitura?.Logs?.Where(x => x.Dispositivo == modulo);
if (!string.IsNullOrEmpty(label))
logs = logs.Where(x => x.ID == label);
logs = logs?.Where(x => x.ID == label);
else
logs = logs.Where(x => x.ID == null);
logs = logs?.Where(x => x.ID == null);
PreencherAbaLogs(logs);
}
@ -968,6 +1007,7 @@ namespace OperationControl.Windows
panelOpcoes_Bomba.Visibility = Visibility.Collapsed;
panelOpcoes_Direcional.Visibility = Visibility.Collapsed;
panelOpcoes_GPS.Visibility = Visibility.Collapsed;
panelOpcoes_Trajetoria.Visibility = Visibility.Collapsed;
}
switch (modulo)
@ -1066,6 +1106,21 @@ namespace OperationControl.Windows
txtGps_DistBase.Text = (Variaveis.GpsService.IsConnected ? AgroBase.Models.GPSUtils.DistanciaEntrePontos(dados ?? new AgroBase.Models.GPSModel(), Variaveis.GpsService.UltimaLeitura) : 0).ToString();
txtGps_Orientacao.Text = (dados?.OrientacaoReal ?? 0).ToString();
break;
}
case AgroBase.Models.Enums.T_Code.Trj:
{
panelOpcoes_Trajetoria.Visibility = Visibility.Visible;
var dados = rover?.Trajetoria?.AutonomiaCooredor;
txtTrajetoria_DistCorredor.Text = $"{dados?.DistanciaCorredor_m ?? 0:0.00} m";
txtTrajetoria_DistBateria.Text = $"{dados?.DistanciaSeguraBateria_m ?? 0:0.00} m";
txtTrajetoria_DistPulverizador.Text = $"{dados?.DistanciaSeguraHerbicida_m ?? 0:0.00} m";
txtTrajetoria_Status.Text = $"{dados?.Status ?? AgroBase.Models.AutonomiaCorredorStatus.Desconhecido}";
txtTrajetoria_BatOk.Text = (dados?.BateriaSuficiente ?? false) ? "Sim" : "Não";
txtTrajetoria_HerbOk.Text = (dados?.HerbicidaSuficiente ?? false) ? "Sim" : "Não";
btnTrajetoria_Confirmar.IsEnabled = !(dados?.Liberado ?? false);
break;
}
default:
@ -1226,6 +1281,26 @@ namespace OperationControl.Windows
#endregion
#region Trajetoria
private void btnTrajetoria_Confirmar_Click(object sender, RoutedEventArgs e)
{
(var modulo, var label, var s_code, var iniciado) = GetModuleData(_labelModuloSelecionado);
if (modulo != AgroBase.Models.Enums.T_Code.Trj)
return;
bool bat_liberada = chbTrajetoria_BatLiberada.IsChecked ?? false;
bool herb_liberado = chbTrajetoria_HerbLiberado.IsChecked ?? false;
string motivo = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Trajetoria?.AutonomiaCooredor?.Motivo ?? "";
if ((bat_liberada || herb_liberado) && MessageBox.Show("Confirmação", $"Tem certeza que deseja liberar a entrada do equipamento na próxima rua?\r\n{motivo}", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
return;
VariaveisControleOperacao.EnviarConfirmacaoHumanaTrajetoria(bat_liberada, herb_liberado);
}
#endregion
private void btnSaude_Salvar_Click(object sender, RoutedEventArgs e)
{
(var modulo, var label, var s_code, var iniciado) = GetModuleData(_labelModuloSelecionado);
@ -1483,15 +1558,14 @@ namespace OperationControl.Windows
private void AtualizarDadosTela_Mapa(AgroBase.Models.OperacaoSensoriamentoLogTrajetoriaModel Trajetoria)
{
lblMapaInfo_Debug.Content = $"" +
$"Status: {Trajetoria.AutonomiaCooredor.Status} | " +
$"Próximo Ponto: {Trajetoria.ProximoPonto.idxPonto} | " +
(Trajetoria.ProximoPonto.Aproximando ? "Aproximando" : "Afastando") + " | " +
$"Distância próximo ponto: {Trajetoria.ProximoPonto.DistanciaAtual.ToString("0.00")} m | " +
$"Distância ponto anterior: {Trajetoria.PontoAtual.DistanciaAtual.ToString("0.00")} m | " +
$"Corredor: " + (Trajetoria.CorredorAtual.Dentro ? "Dentro" : "Fora") + " | " +
$"Margem: " + (Trajetoria.NaMargemDoCorredor ? "Sim" : "Não") + " | " +
$"Disância Esquerda: {(Trajetoria.DistanciaEsquerda * 100.0).ToString("0.00")} cm | " +
$"Distância Direita: {(Trajetoria.DistanciaDireita * 100.0).ToString("0.00")} cm | " +
$"Status: {Trajetoria.StatusCarro}";
$"Carro: {Trajetoria.StatusCarro}";
double erroLateral = (Trajetoria.DistanciaEsquerda - Trajetoria.DistanciaDireita) / 2.0 * 100.0;
AtualizarDadosTela_IMU(erro_lateral: erroLateral);
@ -1648,20 +1722,20 @@ namespace OperationControl.Windows
ATU.LarguraRuaCm = 100.0;
ATU.ErroLateralCm = erroLateral;
if (ATU.QtdBicos != dados?.Controle?.BicosAtuados?.Count)
if (ATU.QtdBicos != dados?.Atuador?.Bicos?.Count)
{
ATU.QtdBicos = dados?.Controle?.BicosAtuados?.Count ?? AgroBase.Models.VariaveisEquipamento.QuantidadeBicosPulverizadores;
ATU.QtdBicos = dados?.Atuador?.Bicos?.Count ?? AgroBase.Models.VariaveisEquipamento.QuantidadeBicosPulverizadores;
}
foreach (var bico in ATU.Bicos)
{
var _bc = dados?.Controle?.BicosAtuados?.FirstOrDefault(x => (x.Posicao - 1) == bico.Index);
var _bc = dados?.Atuador?.Bicos?.FirstOrDefault(x => (x.Posicao - 1) == bico.Index);
if (_bc == null) continue;
bico.OpeningAngle = _bc.AnguloAbertura;
bico.AnguloControle = _bc.AnguloControle;
bico.IsCommandOn = _bc.ComandoAtuar;
bico.IsSpraying = (AgroBase.Models.Enums.Estado)(_bc.ValoresLeituras.FirstOrDefault(x => x.funcao == AgroBase.Models.Modules.FuncoesPinout.EstadoLeitura)?.atual?.valor ?? AgroBase.Models.Enums.Estado.Desligado) == AgroBase.Models.Enums.Estado.Ligado;
bico.IsCommandOn = _bc.Atuado;
bico.IsSpraying = _bc.StatusBico;
bico.Vazao = _bc.MediaNivelFluxo;
bico.Atuacoes = _bc.Atuacoes;
bico.TempoAtuado = _bc.TempoAtuado / 1000.0;
@ -1859,7 +1933,10 @@ namespace OperationControl.Windows
}
}
#endregion
}

View File

@ -14,7 +14,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("OperationControl")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+bd8069c54554e0251ed143bf93aabe93c52f19a2")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+f00ca573b84dec7ec0480b27c59fff929843d108")]
[assembly: System.Reflection.AssemblyProductAttribute("OperationControl")]
[assembly: System.Reflection.AssemblyTitleAttribute("OperationControl")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
bcf738967f77ebf630bc6d19737a8d4412f54220daac0759437ffecc63b6b0d9
56d6e1cf6cf76b55ff13c37e9c61d67174ed3ad16c911065b6426a33cec3a17f

View File

@ -1,4 +1,4 @@

C:\ZendionInc\agrobot_base\AgroBase\OperationControl\obj\Debug\net8.0-windows7.0\GeneratedInternalTypeHelper.g.cs
FC:\ZendionInc\agrobot_base\AgroBase\OperationControl\Controls\AttitudeIndicator.xaml;;
FC:\ZendionInc\agrobot_base\AgroBase\OperationControl\Controls\GstVideoView.xaml;;