ajustes no lora e mpc
This commit is contained in:
parent
c510f8a9b6
commit
35202470c3
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -226,7 +226,7 @@ namespace AgroBase.Forms.IHM
|
|||
var lora = Variaveis.LoraService;
|
||||
lbl.ForeColor = modDesconectado || lora == null
|
||||
? Color.Black
|
||||
: lora.Conectado && !lora.Conectado
|
||||
: lora.Conectado && !lora.Configurado
|
||||
? Color.Gold
|
||||
: lora.Configurado
|
||||
? Color.DarkGreen
|
||||
|
|
@ -367,7 +367,10 @@ namespace AgroBase.Forms.IHM
|
|||
string modId = lbl.Name.Split('_').Length == 4 ? lbl.Name.Split('_')[3] : "";
|
||||
if (Sensor == S_Code.sLRA)
|
||||
{
|
||||
//saudeIndividual = saudeGeral?.saude_individual.FirstOrDefault(x => x.id == )
|
||||
saudeIndividual = new ManagerWorkerMessageResponseModulosPendentesSaudeModel()
|
||||
{
|
||||
status = Variaveis.LoraService.Configurado ? StatusModulo.Operante : Variaveis.LoraService.Conectado ? StatusModulo.Alerta : StatusModulo.Falha,
|
||||
};
|
||||
}
|
||||
else if (Sensor == S_Code.sFRO)
|
||||
{
|
||||
|
|
@ -413,7 +416,7 @@ namespace AgroBase.Forms.IHM
|
|||
{
|
||||
status = saudeIndividual.status;
|
||||
saude = saudeIndividual.saude;
|
||||
erros = string.Join(Environment.NewLine, saudeIndividual.motivos);
|
||||
erros = string.Join(Environment.NewLine, saudeIndividual.motivos ?? new List<string>());
|
||||
}
|
||||
|
||||
string msg =
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
lblRPM.Text = _Sensoriamento.Movimentacao.RPMMedio.ToString("0") + " rpm";
|
||||
lblVelocidade.Text = (_Sensoriamento.Movimentacao.VelocidadeMedia * 3.6).ToString("0.00");
|
||||
|
||||
bool atuadorAtivado = Variaveis.OperacaoEmAndamento.DispAtu.Dados.ConexaoAtiva;
|
||||
bool atuadorAtivado = Variaveis.OperacaoEmAndamento.DispAtu.Dados.Conectado;
|
||||
chbPulverizador.Enabled = atuadorAtivado;
|
||||
if (!atuadorAtivado)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1710,6 +1710,8 @@ namespace AgroBase.Models.Modules
|
|||
loRaService.Conectado = false;
|
||||
loRaService.Configurado = false;
|
||||
loRaService.ParametrosGet.UltimaLeitura = DateTime.MinValue;
|
||||
VisualWorkerService.DadosLeitura.CameraFrames = new Dictionary<CameraFrameType, OAKCameraFrameModel>();
|
||||
WeedWorkerService.DadosLeitura.CameraFrames = new Dictionary<CameraFrameType, OAKCameraFrameModel>();
|
||||
|
||||
ReiniciarLeituras(Dados);
|
||||
}
|
||||
|
|
@ -1819,7 +1821,7 @@ namespace AgroBase.Models.Modules
|
|||
config.AddRange(sensoresConfig);
|
||||
|
||||
// Adicionar configurações do LoRa
|
||||
if (false && (!loRaService.Conectado || !loRaService.Configurado || configurarTodos))
|
||||
if (!loRaService.Conectado || !loRaService.Configurado || configurarTodos)
|
||||
{
|
||||
var loraConfig = loRaService.ProtocoloConfiguracao(Pinout, Conectar);
|
||||
config.AddRange(loraConfig);
|
||||
|
|
@ -2886,7 +2888,7 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
bool Conectado = data[2] == 1;
|
||||
bool Configurado = data[3] == 1;
|
||||
//Console.WriteLine($"[LRA] Resposta {ID_Num} recebida. Conectado={Conectado}, Configurado={Configurado}");
|
||||
Console.WriteLine($"[LRA] Resposta {ID_Num} recebida. Conectado={Conectado}, Configurado={Configurado}");
|
||||
loraService.Conectado = Conectado;
|
||||
loraService.Configurado = Configurado;
|
||||
break;
|
||||
|
|
@ -2918,6 +2920,7 @@ namespace AgroBase.Models.Modules
|
|||
default:
|
||||
{
|
||||
DadosLoRaParse tipoDado = (DadosLoRaParse)posicao;
|
||||
Console.WriteLine($"[LRA] Dados recebidos ({tipoDado.ToString()}). " + string.Join(" ", data));
|
||||
switch (tipoDado)
|
||||
{
|
||||
case DadosLoRaParse.ComandoControle:
|
||||
|
|
|
|||
|
|
@ -977,6 +977,11 @@ namespace AgroBase.Models
|
|||
_ControleAnterior.PercentualVelocidadeSP = _Controle.PercentualVelocidadeSP;
|
||||
_ControleAnterior.Direcao = _Controle.Direcao;
|
||||
|
||||
RedisService.AtualizarCampos(
|
||||
CtxKey.DadosControle,
|
||||
("velocidade_sp_ant", _Controle.PercentualVelocidadeSP)
|
||||
);
|
||||
|
||||
Protocolos = new List<string>()
|
||||
{
|
||||
_Controle.Direcao.ToString() + ";" + _Controle.RPM_SP.ToString()
|
||||
|
|
@ -1013,6 +1018,12 @@ namespace AgroBase.Models
|
|||
_ControleAnterior.Angulo = _Controle.Angulo;
|
||||
_ControleAnterior.Direcao = _Controle.Direcao;
|
||||
|
||||
RedisService.AtualizarCampos(
|
||||
CtxKey.DadosControle,
|
||||
("angulo_sp_ant", _Controle.Angulo),
|
||||
("tipo_movimento_direcional_ant", _Controle.TipoMovimento)
|
||||
);
|
||||
|
||||
Protocolos = new List<string>()
|
||||
{
|
||||
_Controle.Direcao.ToString() + ";" + _Controle.Angulo.ToString()
|
||||
|
|
@ -1262,7 +1273,7 @@ namespace AgroBase.Models
|
|||
Variaveis.OperacaoEmAndamento.idxLog++;
|
||||
|
||||
|
||||
if (Variaveis.OperacaoEmAndamento.idxLog % 5 == 0)
|
||||
if (Variaveis.OperacaoEmAndamento.idxLog % 10 == 0)
|
||||
{
|
||||
Variaveis.LoraService.EnviarDadosParaBase();
|
||||
}
|
||||
|
|
@ -1753,7 +1764,7 @@ namespace AgroBase.Models
|
|||
PercentualErvasTerreno = _DispAtu.Dados.PercentualErvasTerreno,
|
||||
HerbicidaPorErva = HerbicidaPorErva,
|
||||
ErvasNoRadar = WeedWorkerService.DadosLeitura?.Analise?.ervas_no_radar ?? false,
|
||||
PercentualErvasNoRadar = WeedWorkerService.DadosLeitura?.Analise?.estatisticas?.erva?.frac_global ?? 0,
|
||||
PercentualErvasNoRadar = WeedWorkerService.DadosLeitura?.Analise?.estatisticas?.erva?.ema_global ?? 0,
|
||||
PercentualReservatorio = FuncoesMatematicas.Clamp(_DispAtu.Dados.PercentualReservatorio, 0, 100),
|
||||
VolumeReservatorio = _DispAtu.Dados.VolumeReservatorio,
|
||||
PressaoLinha = _DispAtu.Dados.PressaoLinha,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using System.Text;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static AgroBase.Models.Enums;
|
||||
using static AgroBase.Services.LoRaEspService;
|
||||
|
||||
namespace AgroBase.Services
|
||||
{
|
||||
|
|
@ -320,6 +321,10 @@ namespace AgroBase.Services
|
|||
{
|
||||
Mensagens.Add(novaMensagem);
|
||||
MostrarLog($"Mensagem adicionada na fila. ID: {novaMensagem.IdTx}, Data: {FuncoesGlobais.ConverterComandoBytesParaTexto(novaMensagem.DataTx)}", idTx);
|
||||
//if (dados[1] == Variaveis.ID_Num_sLRA)
|
||||
//{
|
||||
// Console.WriteLine($"{DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff")} - MENSAGEM LORA ADICIONADO NA FILA CAN, FUNC_CODE: {((CanMessagePosicaoDados)dados[0]).ToString()} ({((DadosLoRaParse)dados[0]).ToString()}) " + string.Join(" ", dados));
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -228,6 +228,10 @@ namespace AgroBase.Services
|
|||
{
|
||||
MensagensPendentes.Add(novaMensagem);
|
||||
MostrarLog($"Mensagem adicionada na fila. ID: {novaMensagem.IdTx}, Data: {FuncoesGlobais.ConverterComandoBytesParaTexto(novaMensagem.DataTx)}", idTx);
|
||||
//if (payload[0] == Variaveis.ID_Num_sLRA)
|
||||
//{
|
||||
// Console.WriteLine($"{DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff")} - MENSAGEM LORA ADICIONADO NA FILA CAN, FUNC_CODE: {((CanMessagePosicaoDados)payload[1]).ToString()} ({((DadosLoRaParse)payload[1]).ToString()})" + string.Join(" ", payload));
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace AgroBase.Services
|
|||
ParametrosSet.tranModeAndWorCycle
|
||||
};
|
||||
|
||||
//Console.WriteLine($"Parametros de configuracao LoRa: {FuncoesGlobais.ConverterComandoBytesParaTexto(config2.ToArray())}");
|
||||
Console.WriteLine($"Parametros de configuracao LoRa: {FuncoesGlobais.ConverterComandoBytesParaTexto(config2.ToArray())}");
|
||||
|
||||
return new List<(int, CanMessagePosicaoDados, byte[])>()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ namespace AgroBase.Services
|
|||
_long.AddRange(CompactarCoordenada(Gps.Longitude)); // 6 bytes
|
||||
|
||||
List<byte> _gerais = new List<byte>();
|
||||
_long.AddRange(CanPrefix(DadosLoRaParse.GpsGerais));
|
||||
_gerais.AddRange(CanPrefix(DadosLoRaParse.GpsGerais));
|
||||
_gerais.AddRange(CompactarDecimal(Gps.Altitude)); // 2 bytes
|
||||
_gerais.AddRange(CompactarDecimal(Gps.Velocidade)); // 2 bytes
|
||||
_gerais.AddRange(CompactarDecimal(Gps.OrientacaoReal)); // 2 bytes
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace AgroBase.Services
|
|||
{
|
||||
get
|
||||
{
|
||||
return VersionamentoService.ArquivoScript(Enums.TipoArquivoVersionado.Script_GreenDetector).NomeArquivoLocal;
|
||||
return VersionamentoService.ArquivoScript(Enums.TipoArquivoVersionado.Script_WeedDetector).NomeArquivoLocal;
|
||||
}
|
||||
}
|
||||
public static string ScriptStreetDetector
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
1.1AB07E887ACCA305058EEAB9053C96DC531C2C5C067AB4F30AFA2B31F1EDD966
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"description": "Microsoft CRLSet",
|
||||
"name": "MicrosoftCRLSet",
|
||||
"version": "6498.2024.12.2"
|
||||
}
|
||||
Binary file not shown.
|
|
@ -20,7 +20,14 @@
|
|||
"padded_top_topics_start_index": 0,
|
||||
"taxonomy_version": 0,
|
||||
"top_topics_and_observing_domains": [ ]
|
||||
}, {
|
||||
"calculation_time": "13401820180888621",
|
||||
"config_version": 0,
|
||||
"model_version": "0",
|
||||
"padded_top_topics_start_index": 0,
|
||||
"taxonomy_version": 0,
|
||||
"top_topics_and_observing_domains": [ ]
|
||||
} ],
|
||||
"hex_encoded_hmac_key": "40F346D3248C3AFDF2BEE1FE496DBD32F7CED6E5AE98B881ABC421AA7E7B5642",
|
||||
"next_scheduled_calculation_time": "13401819543885718"
|
||||
"next_scheduled_calculation_time": "13402424980889204"
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,3 +1,3 @@
|
|||
2025/09/05-16:00:23.061 940 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
|
||||
2025/09/05-16:00:23.067 940 Recovering log #3
|
||||
2025/09/05-16:00:23.070 940 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
|
||||
2025/09/08-16:31:17.388 11ec Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
|
||||
2025/09/08-16:31:17.394 11ec Recovering log #3
|
||||
2025/09/08-16:31:17.398 11ec Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
2025/09/05-15:33:19.570 47c8 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
|
||||
2025/09/05-15:33:19.578 47c8 Recovering log #3
|
||||
2025/09/05-15:33:19.582 47c8 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
|
||||
2025/09/08-16:13:12.809 9cc Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
|
||||
2025/09/08-16:13:12.816 9cc Recovering log #3
|
||||
2025/09/08-16:13:12.819 9cc Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"net":{"http_server_properties":{"servers":[{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13401661076733928","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":139822},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:6a8:5d00:ecfc:7de1:4083:8c14","used_quic":true},"version":5},"network_qualities":{"CAASABiAgICA+P////8B":"4G","CAESABiAgICA+P////8B":"4G","CAISABiAgICA+P////8B":"4G","CAYSABiAgICA+P////8B":"Offline"}}}
|
||||
{"net":{"http_server_properties":{"servers":[{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13401919905758592","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":12274},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:6a8:5d00:3:b137:22ef:9d9c","used_quic":true},"version":5},"network_qualities":{"CAASABiAgICA+P////8B":"4G","CAESABiAgICA+P////8B":"4G","CAISABiAgICA+P////8B":"4G","CAYSABiAgICA+P////8B":"Offline"}}}
|
||||
|
|
@ -1 +1 @@
|
|||
{"sts":[{"expiry":1788608154.333512,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1757072154.333517}],"version":2}
|
||||
{"sts":[{"expiry":1788891588.105686,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1757355588.105689}],"version":2}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,3 +1,3 @@
|
|||
2025/09/05-16:50:13.785 940 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
|
||||
2025/09/05-16:50:13.786 940 Recovering log #3
|
||||
2025/09/05-16:50:13.789 940 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
|
||||
2025/09/08-17:01:10.553 11ec Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
|
||||
2025/09/08-17:01:10.555 11ec Recovering log #3
|
||||
2025/09/08-17:01:10.558 11ec Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
2025/09/05-15:39:06.299 47c8 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
|
||||
2025/09/05-15:39:06.300 47c8 Recovering log #3
|
||||
2025/09/05-15:39:06.304 47c8 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
|
||||
2025/09/08-16:14:02.023 9cc Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
|
||||
2025/09/08-16:14:02.024 9cc Recovering log #3
|
||||
2025/09/08-16:14:02.026 9cc Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
2025/09/05-16:00:22.989 1b60 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
|
||||
2025/09/05-16:00:22.991 1b60 Recovering log #7
|
||||
2025/09/05-16:00:22.991 1b60 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log
|
||||
2025/09/08-16:31:17.316 42c4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
|
||||
2025/09/08-16:31:17.318 42c4 Recovering log #7
|
||||
2025/09/08-16:31:17.318 42c4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
2025/09/05-15:33:19.486 5698 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
|
||||
2025/09/05-15:33:19.488 5698 Recovering log #7
|
||||
2025/09/05-15:33:19.488 5698 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log
|
||||
2025/09/08-16:13:12.733 2a9c Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
|
||||
2025/09/08-16:13:12.736 2a9c Recovering log #7
|
||||
2025/09/08-16:13:12.736 2a9c Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000007.log
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
{"hashes":{"00AF3F07B5ABB71F6D30337E1EEF62FA280F06EF19485C0CF6B72171F92CCC0A":{"appid":"kpfehajjjbbcifeehjgfgnabifknmdad","fp":"1.00AF3F07B5ABB71F6D30337E1EEF62FA280F06EF19485C0CF6B72171F92CCC0A"},"1AB07E887ACCA305058EEAB9053C96DC531C2C5C067AB4F30AFA2B31F1EDD966":{"appid":"oankkpibpaokgecfckkdkgaoafllipag","fp":"1.1AB07E887ACCA305058EEAB9053C96DC531C2C5C067AB4F30AFA2B31F1EDD966"},"452064dcff76e03e0e81b4bb3c48ab1c432e040094f7546c7261a90d4a1c1bbf":{"appid":"fgbafbciocncjfbbonhocjaohoknlaco","fp":""},"4B81B4DF3AD971287E1AE02C449344FCFA5D20431DE17B2BA8854CC9CDCE4089":{"appid":"ahmaebgpfccdhgidjaidaoojjcijckba","fp":"1.4B81B4DF3AD971287E1AE02C449344FCFA5D20431DE17B2BA8854CC9CDCE4089"},"89f43cb3df807293de2772d5f01ac2fc1482b38ccc8fdaee859b80642b7a0487":{"appid":"pghocgajpebopihickglahgebcmkcekh","fp":""},"95FD9D48E4FC245A3F3A99A3A16ECD1355050BA3F4AFC555F19A97C7F9B49677":{"appid":"ohckeflnhegojcjlcpbfpciadgikcohk","fp":"1.95FD9D48E4FC245A3F3A99A3A16ECD1355050BA3F4AFC555F19A97C7F9B49677"},"A81D1959892AE4180554347DF1B97834ABBA2E1A5E6B9AEBA000ECEA26EABECC":{"appid":"fppmbhmldokgmleojlplaaodlkibgikh","fp":"1.A81D1959892AE4180554347DF1B97834ABBA2E1A5E6B9AEBA000ECEA26EABECC"},"A99D66CFCE8CA170740CE0403956F4DFAF4683829A89F4B7AD9C95303871E284":{"appid":"eeobbhfgfagbclfofmgbdfoicabjdbkn","fp":"1.A99D66CFCE8CA170740CE0403956F4DFAF4683829A89F4B7AD9C95303871E284"},"b987bdc4f2ad2a409b964921d4a5db1cdbe07f9c98f868293b4cc32acdc42cec":{"appid":"alpjnmnfbgfkmmpcfpejmmoebdndedno","fp":""},"bcb93cba8636743d1fbd32be3bd8ce8ff602323895bf4d136c26b9bc64b0a6a4":{"appid":"ndikpojcjlepofdkaaldkinkjbeeebkl","fp":""}}}
|
||||
{"hashes":{"00AF3F07B5ABB71F6D30337E1EEF62FA280F06EF19485C0CF6B72171F92CCC0A":{"appid":"kpfehajjjbbcifeehjgfgnabifknmdad","fp":"1.00AF3F07B5ABB71F6D30337E1EEF62FA280F06EF19485C0CF6B72171F92CCC0A"},"452064dcff76e03e0e81b4bb3c48ab1c432e040094f7546c7261a90d4a1c1bbf":{"appid":"fgbafbciocncjfbbonhocjaohoknlaco","fp":""},"4B81B4DF3AD971287E1AE02C449344FCFA5D20431DE17B2BA8854CC9CDCE4089":{"appid":"ahmaebgpfccdhgidjaidaoojjcijckba","fp":"1.4B81B4DF3AD971287E1AE02C449344FCFA5D20431DE17B2BA8854CC9CDCE4089"},"89f43cb3df807293de2772d5f01ac2fc1482b38ccc8fdaee859b80642b7a0487":{"appid":"pghocgajpebopihickglahgebcmkcekh","fp":""},"95FD9D48E4FC245A3F3A99A3A16ECD1355050BA3F4AFC555F19A97C7F9B49677":{"appid":"ohckeflnhegojcjlcpbfpciadgikcohk","fp":"1.95FD9D48E4FC245A3F3A99A3A16ECD1355050BA3F4AFC555F19A97C7F9B49677"},"A81D1959892AE4180554347DF1B97834ABBA2E1A5E6B9AEBA000ECEA26EABECC":{"appid":"fppmbhmldokgmleojlplaaodlkibgikh","fp":"1.A81D1959892AE4180554347DF1B97834ABBA2E1A5E6B9AEBA000ECEA26EABECC"},"A99D66CFCE8CA170740CE0403956F4DFAF4683829A89F4B7AD9C95303871E284":{"appid":"eeobbhfgfagbclfofmgbdfoicabjdbkn","fp":"1.A99D66CFCE8CA170740CE0403956F4DFAF4683829A89F4B7AD9C95303871E284"},"b987bdc4f2ad2a409b964921d4a5db1cdbe07f9c98f868293b4cc32acdc42cec":{"appid":"alpjnmnfbgfkmmpcfpejmmoebdndedno","fp":""},"bcb93cba8636743d1fbd32be3bd8ce8ff602323895bf4d136c26b9bc64b0a6a4":{"appid":"ndikpojcjlepofdkaaldkinkjbeeebkl","fp":""},"fa29a6d5775ff340900a65b39b02fc8b4b77d403c048d8debf22f2f5d09c61a0":{"appid":"oankkpibpaokgecfckkdkgaoafllipag","fp":""}}}
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -17,7 +17,7 @@
|
|||
<meta name="viewport" content="width=device-width,
|
||||
initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<style>
|
||||
#map_b4846582c871aaafb422e9fb94bff081 {
|
||||
#map_28e5199720417a91208a7dff1794e441 {
|
||||
position: relative;
|
||||
width: 100.0%;
|
||||
height: 100.0%;
|
||||
|
|
@ -54,14 +54,14 @@
|
|||
<body>
|
||||
|
||||
|
||||
<div class="folium-map" id="map_b4846582c871aaafb422e9fb94bff081" ></div>
|
||||
<div class="folium-map" id="map_28e5199720417a91208a7dff1794e441" ></div>
|
||||
|
||||
</body>
|
||||
<script>
|
||||
|
||||
|
||||
var map_b4846582c871aaafb422e9fb94bff081 = L.map(
|
||||
"map_b4846582c871aaafb422e9fb94bff081",
|
||||
var map_28e5199720417a91208a7dff1794e441 = L.map(
|
||||
"map_28e5199720417a91208a7dff1794e441",
|
||||
{
|
||||
center: [0.0, 0.0],
|
||||
crs: L.CRS.EPSG3857,
|
||||
|
|
@ -96,7 +96,7 @@
|
|||
}
|
||||
trajeto_json_add({"features": []});
|
||||
|
||||
trajeto_json.addTo(map_b4846582c871aaafb422e9fb94bff081);
|
||||
trajeto_json.addTo(map_28e5199720417a91208a7dff1794e441);
|
||||
|
||||
function adicionarGeometria(novaGeometria) {
|
||||
trajeto_json.addData(novaGeometria);
|
||||
|
|
@ -159,9 +159,9 @@
|
|||
|
||||
var marcadorEquipamento = L.marker([0, 0], {
|
||||
icon: customIcon
|
||||
}).addTo(map_b4846582c871aaafb422e9fb94bff081);
|
||||
}).addTo(map_28e5199720417a91208a7dff1794e441);
|
||||
|
||||
var marcadorBase = L.marker([0, 0], {}).addTo(map_b4846582c871aaafb422e9fb94bff081);
|
||||
var marcadorBase = L.marker([0, 0], {}).addTo(map_28e5199720417a91208a7dff1794e441);
|
||||
var icon = L.AwesomeMarkers.icon(
|
||||
{"extraClasses": "fa-rotate-0", "icon": "info-sign", "iconColor": "white", "markerColor": "red", "prefix": "glyphicon"}
|
||||
);
|
||||
|
|
@ -226,7 +226,7 @@
|
|||
}
|
||||
|
||||
if (foco) {
|
||||
map_b4846582c871aaafb422e9fb94bff081.setView(novaPosicao, map_b4846582c871aaafb422e9fb94bff081.getZoom());
|
||||
map_28e5199720417a91208a7dff1794e441.setView(novaPosicao, map_28e5199720417a91208a7dff1794e441.getZoom());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -248,7 +248,7 @@
|
|||
marcadorDinamico.setRotationAngle(angulo);
|
||||
|
||||
adicionarCoordenada("Tj", [novaLongitude, novaLatitude]);
|
||||
map_b4846582c871aaafb422e9fb94bff081.setView(novaPosicao, map_b4846582c871aaafb422e9fb94bff081.getZoom());*/
|
||||
map_28e5199720417a91208a7dff1794e441.setView(novaPosicao, map_28e5199720417a91208a7dff1794e441.getZoom());*/
|
||||
});
|
||||
|
||||
function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -258,9 +258,9 @@ def _comando_mapa_gps_mpc(contexto):
|
|||
_controle = ContextoGlobalRedis.get_controle()
|
||||
|
||||
comando_anterior = {
|
||||
"angulo": _controle.get("angulo_sp", 0.0),
|
||||
"tipo": _controle.get("tipo_movimento_direcional", TipoMovimentoDirecional.RodasDianteiras.value),
|
||||
"velocidade": _controle.get("velocidade_sp", 0.0)
|
||||
"angulo": _controle.get("angulo_sp_ant", 0.0),
|
||||
"tipo": _controle.get("tipo_movimento_direcional_ant", TipoMovimentoDirecional.RodasDianteiras.value),
|
||||
"velocidade": _controle.get("velocidade_sp_ant", 0.0)
|
||||
}
|
||||
|
||||
# 🔸 Requisição ao controlador MPC
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ def definir_comando(parada_necessaria: bool, erro: bool, filtro_vel: FiltroVeloc
|
|||
#percentual_ervas_no_radar = (_contexto.get("Gerais", {}).get("percentual_ervas_no_radar", 0)) * 100.0
|
||||
_dados_ww = ContextoGlobalRedis.get(CtxKey.DadosWeedWorker, {}).get("analise", {})
|
||||
ervas_no_radar = _dados_ww.get("ervas_no_radar", False)
|
||||
percentual_ervas_no_radar = _dados_ww.get("estatisticas", {}).get("frac_global", 0.0)
|
||||
percentual_ervas_no_radar = _dados_ww.get("estatisticas", {}).get("ema_global", 0.0)
|
||||
|
||||
vel_min = 15
|
||||
ervas_min_percenet = 0.5
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
from copy import deepcopy
|
||||
import heapq
|
||||
import math
|
||||
import time
|
||||
|
|
@ -254,7 +253,7 @@ class ControladorMPC:
|
|||
|
||||
def _corrigir_pontos_visitados(self, x, y, pontos_visitados: np.ndarray, idx_atual: int = -1,
|
||||
limite_max_avanco: float = 5.0, # em METROS
|
||||
limite_max_pontos: int = 10):
|
||||
limite_max_pontos: int = 10, velocidade: float = -1, dt: float = -1):
|
||||
try:
|
||||
p_xy, p_mg, p_s = self._p_xy, self._p_margem, self._p_s
|
||||
N = p_xy.shape[0]
|
||||
|
|
@ -263,7 +262,7 @@ class ControladorMPC:
|
|||
|
||||
# --- (1) Igual ao antigo: marcar EXCLUSIVO quando idx_atual vier do C# ---
|
||||
if idx_atual > -1:
|
||||
pontos_visitados[:idx_atual] = True # <<< EXCLUSIVO (antes era :idx_atual+1)
|
||||
pontos_visitados[:idx_atual+1] = True # <<< EXCLUSIVO (antes era :idx_atual+1)
|
||||
return idx_atual
|
||||
|
||||
if pontos_visitados.all():
|
||||
|
|
@ -286,12 +285,18 @@ class ControladorMPC:
|
|||
margem2 = p_mg[sl] * p_mg[sl]
|
||||
|
||||
# --- (2) Opcional para fidelidade ao antigo: usar '<' em vez de '<=' ---
|
||||
hits = dist2 < margem2 # era <=
|
||||
hits = dist2 <= margem2 # era <=
|
||||
|
||||
if np.any(hits):
|
||||
off = int(np.argmax(hits))
|
||||
idx = start_idx + off
|
||||
pontos_visitados[:idx+1] = True
|
||||
pontos_visitados[:idx] = True
|
||||
if velocidade > -1:
|
||||
s_hit = self._p_s[idx]
|
||||
s_goal = s_hit + self.d_look_ahead_m(velocidade, dt)
|
||||
idx_alvo = int(np.searchsorted(self._p_s, s_goal, side="left"))
|
||||
idx_alvo = min(idx_alvo, len(self._p_s)-1)
|
||||
return idx_alvo
|
||||
return idx
|
||||
|
||||
# --- (3) Fallback robusto para “próximo não visitado” ---
|
||||
|
|
@ -333,7 +338,7 @@ class ControladorMPC:
|
|||
try:
|
||||
peso_erro_pos = 1.2 # 0
|
||||
peso_erro_ori = 1.0 # 1
|
||||
peso_suavidade = 1.4 # 2
|
||||
peso_suavidade = 1.5 # 2
|
||||
peso_fator_re = 0.2 # 3
|
||||
peso_ideal = 0.4 # 4
|
||||
|
||||
|
|
@ -380,7 +385,7 @@ class ControladorMPC:
|
|||
Propaga (x,y,theta) por 'latency_s' usando 'nova_posicao_fn' que depende de self.dt.
|
||||
Retorna (x, y, theta) estimados no presente.
|
||||
"""
|
||||
visitados_copy = deepcopy(visitados)
|
||||
visitados_copy = visitados.copy()
|
||||
latency_s = max(0.0, float(latency_s))
|
||||
if latency_s == 0.0:
|
||||
return x, y, theta, visitados_copy
|
||||
|
|
@ -435,6 +440,63 @@ class ControladorMPC:
|
|||
# theta = (theta + np.pi) % (2*np.pi) - np.pi
|
||||
return x, y, theta, visitados_copy
|
||||
|
||||
def d_look_ahead_m(self, velocidade, dt: float = None):
|
||||
"""
|
||||
Retorna look-ahead em METROS.
|
||||
- velocidade: pode vir em m/s ou normalizada (0-1). Detecto automaticamente.
|
||||
- dt: passo real do MPC (s) para suavização adaptativa (opcional).
|
||||
"""
|
||||
|
||||
# --- 1) Normalização de velocidade ---------------------------------------
|
||||
# tente usar self.vel_max_m_s se já existir; senão, usa 6.8 km/h (~1.889 m/s)
|
||||
vel_max_ms = getattr(self, "vel_max_m_s", 6.8/3.6)
|
||||
v = float(velocidade)
|
||||
if v <= 1.05: # heurística: trata <=1.0 como v_norm
|
||||
v = max(0.0, min(1.0, v)) * vel_max_ms
|
||||
else:
|
||||
v = max(0.0, v) # já está em m/s
|
||||
|
||||
# --- 2) Base polinomial (suave e previsível) ------------------------------
|
||||
# L_base = L0 + a*v + b*v^2 (clamp em [Lmin, Lmax])
|
||||
Lmin, Lmax = 0.60, 2.80 # bom para teu range (1.3–6.8 km/h)
|
||||
L0, a, b = 0.60, 0.70, 0.20
|
||||
L = L0 + a*v + b*(v*v)
|
||||
if L < Lmin: L = Lmin
|
||||
if L > Lmax: L = Lmax
|
||||
|
||||
# --- 3) Redução por curvatura e erro de orientação ------------------------
|
||||
# Se você já calcula curvatura/erro, exponha em self; senão, assumo 0.
|
||||
kappa = abs(getattr(self, "curvatura_atual", 0.0)) # 1/m
|
||||
err_yaw = abs(getattr(self, "erro_angular_atual", 0.0)) # rad
|
||||
|
||||
# Fatores <=1.0: reduzem o L em curva forte e/ou erro de yaw grande.
|
||||
# Ajuste c_k, c_e conforme seu corredor (mais alto = reduz mais).
|
||||
c_k, c_e = 3.0, 1.2
|
||||
f_k = 1.0 / (1.0 + c_k * kappa)
|
||||
f_e = 1.0 / (1.0 + c_e * err_yaw)
|
||||
L *= min(f_k, f_e)
|
||||
|
||||
# --- 4) Compensação de latência de controle/planta ------------------------
|
||||
# Se você tem latência medida, exponha em self.tau_ctrl (s). Senão: ~0.15 s.
|
||||
tau = float(getattr(self, "tau_ctrl", 0.15))
|
||||
L += v * tau # “empurra” o alvo à frente para cobrir atraso
|
||||
|
||||
# Clamp final para garantir limites mesmo após fatores
|
||||
if L < Lmin: L = Lmin
|
||||
if L > Lmax: L = Lmax
|
||||
|
||||
# --- 5) Suavização temporal (anti-chatter) --------------------------------
|
||||
# EMA com constante de tempo ~0.4 s (ajuste T_ema). Usa dt se informado.
|
||||
T_ema = 0.40
|
||||
if dt is None:
|
||||
dt = float(getattr(self, "dt", 0.15)) # teu MPC já guarda dt
|
||||
alpha = max(0.0, min(1.0, 1.0 - pow(2.718281828, -dt / T_ema)))
|
||||
L_suave = getattr(self, "_L_ema", L)
|
||||
L_suave = (1.0 - alpha) * L_suave + alpha * L
|
||||
self._L_ema = L_suave
|
||||
|
||||
return L_suave
|
||||
|
||||
|
||||
def _wrap_pi(self, a):
|
||||
try:
|
||||
|
|
@ -649,7 +711,7 @@ class ControladorMPC:
|
|||
if exp_budget <= 0 or ms_left() <= 0:
|
||||
break
|
||||
x_atual, y_atual, theta_atual = candidato["x"], candidato["y"], candidato["theta"]
|
||||
visitados = deepcopy(candidato["visitados"])
|
||||
visitados = candidato["visitados"].copy()
|
||||
cmd_anterior = {
|
||||
"tipo": candidato["comandos"][-1][0],
|
||||
"angulo": candidato["comandos"][-1][1],
|
||||
|
|
@ -878,7 +940,7 @@ class ControladorMPC:
|
|||
)
|
||||
}
|
||||
cmd_seq = None
|
||||
x, y, theta, pts_visitados = self.corrigir_pose_por_latencia(
|
||||
x, y, theta, self.visitados_execucao = self.corrigir_pose_por_latencia(
|
||||
x, y, theta, self.visitados_execucao,
|
||||
latency_s=min(pos_latencia, LAT_MAX),
|
||||
dt=self.dt,
|
||||
|
|
@ -888,7 +950,7 @@ class ControladorMPC:
|
|||
time_left_ms=lambda: (deadline - now()) * 1000.0,
|
||||
calc_omega_fn=self.gps_handler.calcular_omega
|
||||
)
|
||||
idx_alvo_correcao = self._corrigir_pontos_visitados(x, y, pts_visitados, idx_proximo_ponto_real)
|
||||
idx_alvo_correcao = self._corrigir_pontos_visitados(x, y, self.visitados_execucao, idx_proximo_ponto_real)
|
||||
|
||||
# -------------------- Planejamento: horizonte ESPACIAL fixo --------------------
|
||||
S_ALVO = float(getattr(self, "horizonte", 2.5))
|
||||
|
|
@ -941,7 +1003,7 @@ class ControladorMPC:
|
|||
"custo": 0.0,
|
||||
"comandos": [(tipo_anterior, angulo_anterior)],
|
||||
"trajetoria": [],
|
||||
"visitados": pts_visitados,
|
||||
"visitados": self.visitados_execucao,
|
||||
"inicial": True
|
||||
}]
|
||||
|
||||
|
|
@ -957,14 +1019,14 @@ class ControladorMPC:
|
|||
break
|
||||
|
||||
x_atual, y_atual, theta_atual = candidato["x"], candidato["y"], candidato["theta"]
|
||||
visitados = deepcopy(candidato["visitados"])
|
||||
visitados = candidato["visitados"].copy()
|
||||
cmd_anterior_local = {
|
||||
"tipo": candidato["comandos"][-1][0],
|
||||
"angulo": candidato["comandos"][-1][1],
|
||||
}
|
||||
|
||||
idx_alvo = self._corrigir_pontos_visitados(x_atual, y_atual, visitados)
|
||||
if idx_alvo < len(self.pontos_info) - 1: idx_alvo += 1
|
||||
idx_alvo = self._corrigir_pontos_visitados(x_atual, y_atual, visitados, velocidade=v_sim, dt=dt_pred)
|
||||
#if idx_alvo < len(self.pontos_info) - 1: idx_alvo += 1
|
||||
ponto_alvo = self.pontos_info[idx_alvo]
|
||||
|
||||
tipos, angs, custos_candidatos = self._gerar_angulos_candidatos_receding(
|
||||
|
|
@ -1931,7 +1993,7 @@ class ControladorMPC:
|
|||
simulacoes = []
|
||||
prev_ang = float(comando_anterior.get("angulo", 0.0))
|
||||
prev_tipo = comando_anterior.get("tipo", TipoMovimentoDirecional.RodasDianteiras.value)
|
||||
pontos_visitados = deepcopy(visitados)
|
||||
pontos_visitados = visitados.copy()
|
||||
|
||||
# Contexto usado no custo
|
||||
angulo_caminho = np.radians(contexto.get("Carro", {}).get("AnguloCaminho", 0.0))
|
||||
|
|
@ -1945,7 +2007,7 @@ class ControladorMPC:
|
|||
passos_local = max(1, int(getattr(self, "passos_horizonte_local", 1)))
|
||||
dt_total = float(dt_pred) * passos_local
|
||||
|
||||
SUB_MAX = float(getattr(self, "_dt_sub_max", 0.08)) # ~80 ms por subpasso
|
||||
SUB_MAX = float(getattr(self, "_dt_sub_max", 0.15)) # ~80 ms por subpasso
|
||||
n_sub = max(1, int(math.ceil(dt_total / SUB_MAX)))
|
||||
sub_dt = dt_total / n_sub
|
||||
dist_sub = v_planejado * sub_dt # usado para custo por metro
|
||||
|
|
@ -1962,7 +2024,7 @@ class ControladorMPC:
|
|||
simulacoes.append((x_sim, y_sim, theta_sim))
|
||||
|
||||
# alvo mais próximo após avançar
|
||||
idx_alvo_sim = self._corrigir_pontos_visitados(x_sim, y_sim, pontos_visitados)
|
||||
idx_alvo_sim = self._corrigir_pontos_visitados(x_sim, y_sim, pontos_visitados, velocidade=v_planejado, dt=sub_dt)
|
||||
ponto_alvo_sim = self.pontos_info[idx_alvo_sim]["xy"]
|
||||
|
||||
# orientação do caminho + erro angular combinado
|
||||
|
|
|
|||
|
|
@ -104,15 +104,15 @@ class CostmapFuser:
|
|||
use_persistence=False,
|
||||
velocidade_mps=None, # m/s; se None, decisão não usa distância de frenagem
|
||||
a_max_freio=0.8, # m/s²
|
||||
margem_parada=0.25, # m
|
||||
margem_parada=0.5, # m
|
||||
N_on=2, # frames p/ entrar
|
||||
N_off=5, # frames p/ sair
|
||||
N_off=3, # frames p/ sair
|
||||
blackout_imediato=True,
|
||||
|
||||
det_score_f=None, # (H,W) 0..1
|
||||
det_label_id=None, # (H,W) int, -1 = none
|
||||
det_strength=None, # (H,W) 0..1 ~ conf*cov dominante
|
||||
thr_det_consider=0.25
|
||||
thr_det_consider=0.15
|
||||
):
|
||||
H, W = custo_f.shape
|
||||
c0, c1 = central_cols
|
||||
|
|
|
|||
|
|
@ -183,13 +183,16 @@ public:
|
|||
|
||||
// tenta enfileirar pro worker
|
||||
if (callbacksQ && xQueueSend(callbacksQ, &message, 0) != pdTRUE) {
|
||||
if (DebugMode) {
|
||||
PrintTela("Erro ao adicionar mensagem recebida na fila: " + String(rx_drops));
|
||||
}
|
||||
rx_drops++;
|
||||
|
||||
// (opcional) política "drop oldest": remove 1 e tenta de novo
|
||||
// twai_message_t dump;
|
||||
// if (xQueueReceive(callbacksQ, &dump, 0) == pdTRUE) {
|
||||
// xQueueSend(callbacksQ, &message, 0);
|
||||
// }
|
||||
twai_message_t dump;
|
||||
if (xQueueReceive(callbacksQ, &dump, 0) == pdTRUE) {
|
||||
xQueueSend(callbacksQ, &message, 0);
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(1)); // dá uma respirada
|
||||
}
|
||||
|
|
@ -212,8 +215,7 @@ public:
|
|||
if (xQueueReceive(callbacksQ, &msg, portMAX_DELAY) == pdTRUE) {
|
||||
if (_callback && msg.data_length_code > 0) {
|
||||
CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)msg.data[0];
|
||||
_callback(msg.data_length_code, msg.identifier, posicao,
|
||||
&msg.data[1], msg.data_length_code - 1);
|
||||
_callback(msg.data_length_code, msg.identifier, posicao, &msg.data[1], msg.data_length_code - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -540,7 +542,7 @@ private:
|
|||
uint32_t _baudRate = 250000;
|
||||
uint8_t _nodeId = 0;
|
||||
OnReceiveCallback _callback = nullptr;
|
||||
bool DebugMode = true;
|
||||
bool DebugMode = false;
|
||||
};
|
||||
|
||||
#endif // CANSERVICE_H
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public:
|
|||
// Inicializa GPIOs
|
||||
pinMode(_pinM0, OUTPUT);
|
||||
pinMode(_pinM1, OUTPUT);
|
||||
pinMode(_pinAUX, INPUT);
|
||||
pinMode(_pinAUX, INPUT_PULLUP);
|
||||
|
||||
_serialLoRa = &Serial2;
|
||||
if (Conectado) {
|
||||
|
|
@ -194,14 +194,32 @@ public:
|
|||
//EnviarDadosCAN(MontarMensagemCAN(CanMessagePosicaoDados::Status));
|
||||
if (Conectado) {
|
||||
if (requisitarParametrosLoRa()) {
|
||||
//EnviarDadosCAN(MontarMensagemCAN(CanMessagePosicaoDados::Dados1));
|
||||
// Log detalhado do que veio da EEPROM
|
||||
MostrarLog("EEPROM -> "
|
||||
"Addr=" + String(parametrosAtual.address, HEX) +
|
||||
" BaudAir=" + String(parametrosAtual.baudAndAirRate, HEX) +
|
||||
" PacketPower=" + String(parametrosAtual.packetSizeAndPower, HEX) +
|
||||
" Channel=" + String(parametrosAtual.channel, HEX) +
|
||||
" TranModeWor=" + String(parametrosAtual.tranModeAndWorCycle, HEX)
|
||||
);
|
||||
|
||||
MostrarLog("Desejado -> "
|
||||
"Addr=" + String(addr, HEX) +
|
||||
" BaudAir=" + String(baud, HEX) +
|
||||
" PacketPower=" + String(packet, HEX) +
|
||||
" Channel=" + String(channel, HEX) +
|
||||
" TranModeWor=" + String(worCycle, HEX)
|
||||
);
|
||||
|
||||
Configurado =
|
||||
(uint8_t)parametrosAtual.address == (uint8_t)addr &&
|
||||
(uint8_t)parametrosAtual.baudAndAirRate == (uint8_t)baud &&
|
||||
(uint8_t)parametrosAtual.packetSizeAndPower == (uint8_t)packet &&
|
||||
(uint8_t)parametrosAtual.channel == (uint8_t)channel &&
|
||||
(uint8_t)parametrosAtual.tranModeAndWorCycle == (uint8_t)worCycle;
|
||||
MostrarLog("Modulo ja configurado: " + String(Configurado));
|
||||
parametrosAtual.address == addr &&
|
||||
parametrosAtual.baudAndAirRate == baud &&
|
||||
parametrosAtual.packetSizeAndPower == packet &&
|
||||
parametrosAtual.channel == channel &&
|
||||
parametrosAtual.tranModeAndWorCycle== worCycle;
|
||||
|
||||
MostrarLog(String("Modulo ja configurado? ") + (Configurado ? "SIM" : "NAO"));
|
||||
|
||||
if (!Configurado) {
|
||||
Configurado = configurarModuloLoRa(addr, baud, packet, channel, worCycle);
|
||||
}
|
||||
|
|
@ -252,7 +270,7 @@ private:
|
|||
void LraTaskRx(void* pvParameters) {
|
||||
LoRaService* service = static_cast<LoRaService*>(pvParameters);
|
||||
while (true) {
|
||||
if (!Conectado || !Configurado) {
|
||||
if (!Conectado || !Configurado || PausarRX) {
|
||||
vTaskDelay(1000);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -343,7 +361,7 @@ private:
|
|||
LoRaService* service = static_cast<LoRaService*>(pvParameters);
|
||||
std::vector<uint8_t> msg;
|
||||
while (true) {
|
||||
if (!Conectado || !Configurado) {
|
||||
if (!Conectado || !Configurado || PausarTX) {
|
||||
vTaskDelay(1000);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -386,49 +404,98 @@ private:
|
|||
int _baudRate = 9600;
|
||||
LoRaMode currentMode = NORMAL;
|
||||
LoRaParametrosModel parametrosAtual;
|
||||
int commandTimeout = 200;
|
||||
int commandTimeout = 800;
|
||||
bool PausarTX = false;
|
||||
bool PausarRX = false;
|
||||
|
||||
// Métodos internos
|
||||
void pauseLoRaTasks() {
|
||||
// pare produtoras de TX e consumidoras de RX antes de mexer no modo
|
||||
PausarTX = true; // sua flag para impedir enqueue/envio
|
||||
PausarRX = true; // idem recepção
|
||||
vTaskDelay(5);
|
||||
}
|
||||
|
||||
void resumeLoRaTasks() {
|
||||
PausarTX = false;
|
||||
PausarRX = false;
|
||||
}
|
||||
|
||||
bool waitAUXHigh(unsigned long toMs = 2000) {
|
||||
unsigned long t0 = millis();
|
||||
while (millis() - t0 < toMs) {
|
||||
if (digitalRead(_pinAUX) == HIGH) return true;
|
||||
vTaskDelay(1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void drainUart() {
|
||||
// garante que nada esteja “pendurado” no buffer
|
||||
if (_serialLoRa) {
|
||||
_serialLoRa->flush(); // espera TX terminar
|
||||
while (_serialLoRa->available()) _serialLoRa->read(); // limpa RX
|
||||
}
|
||||
}
|
||||
|
||||
// Define o modo do LoRa
|
||||
bool setLoRaMode(LoRaMode mode) {
|
||||
if (mode == currentMode) return true;
|
||||
|
||||
// Ajusta os pinos M0 e M1 conforme o modo desejado
|
||||
switch (mode) {
|
||||
case NORMAL:
|
||||
digitalWrite(_pinM0, LOW);
|
||||
digitalWrite(_pinM1, LOW);
|
||||
break;
|
||||
case WAKE_UP:
|
||||
digitalWrite(_pinM0, HIGH);
|
||||
digitalWrite(_pinM1, LOW);
|
||||
break;
|
||||
case POWER_SAVING:
|
||||
digitalWrite(_pinM0, LOW);
|
||||
digitalWrite(_pinM1, HIGH);
|
||||
break;
|
||||
case CONFIG:
|
||||
digitalWrite(_pinM0, HIGH);
|
||||
digitalWrite(_pinM1, HIGH);
|
||||
break;
|
||||
}
|
||||
// 0) Garante direção dos pinos e pull-up no AUX
|
||||
pinMode(_pinM0, OUTPUT);
|
||||
pinMode(_pinM1, OUTPUT);
|
||||
pinMode(_pinAUX, INPUT_PULLUP); // evita flutuação
|
||||
|
||||
MostrarLog("Modo alterado de " + String(currentMode) + " para " + String(mode));
|
||||
// 1) Pausa tarefas que podem forçar TX/RX enquanto troca
|
||||
pauseLoRaTasks();
|
||||
|
||||
currentMode = mode;
|
||||
|
||||
vTaskDelay(100); // Aguarda sinalização inicial de troca
|
||||
|
||||
// ESPERA o AUX ir para HIGH, indicando que a troca completou
|
||||
unsigned long timeout = millis() + commandTimeout;
|
||||
while (digitalRead(_pinAUX) == LOW) {
|
||||
if (millis() > timeout) {
|
||||
MostrarLog("Erro: Timeout aguardando AUX após mudança de modo.");
|
||||
// 2) Aguarda o rádio estar ocioso antes de mexer em M0/M1
|
||||
if (!waitAUXHigh(2000)) {
|
||||
MostrarLog("Erro: AUX não ficou HIGH antes da troca de modo.");
|
||||
resumeLoRaTasks();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3) Para tráfego de UART e limpa buffers
|
||||
drainUart();
|
||||
|
||||
// 4) Comuta M0/M1
|
||||
switch (mode) {
|
||||
case NORMAL: digitalWrite(_pinM0, LOW); digitalWrite(_pinM1, LOW); break;
|
||||
case WAKE_UP: digitalWrite(_pinM0, HIGH); digitalWrite(_pinM1, LOW); break;
|
||||
case POWER_SAVING: digitalWrite(_pinM0, LOW); digitalWrite(_pinM1, HIGH); break;
|
||||
case CONFIG: digitalWrite(_pinM0, HIGH); digitalWrite(_pinM1, HIGH); break;
|
||||
}
|
||||
|
||||
vTaskDelay(100); // Manual pede 2ms após AUX ficar HIGH
|
||||
// 5) Esperas mínimas do datasheet
|
||||
vTaskDelay(5); // >2ms após M0/M1
|
||||
|
||||
// 6) Espera o módulo sinalizar pronto no novo modo
|
||||
if (!waitAUXHigh(2000)) {
|
||||
MostrarLog("Erro: Timeout aguardando AUX após mudança de modo.");
|
||||
resumeLoRaTasks();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 7) Ajustes específicos por modo
|
||||
if (mode == CONFIG) {
|
||||
// A UART do módulo em CONFIG é 9600 8N1 SEMPRE.
|
||||
if (_serialLoRa) _serialLoRa->begin(9600, SERIAL_8N1, _pinRXD, _pinTXD);
|
||||
drainUart();
|
||||
}
|
||||
|
||||
if (mode == NORMAL) {
|
||||
// voltar à baud configurada do módulo (ex.: 9600/19200/etc)
|
||||
if (_serialLoRa) _serialLoRa->begin(_baudRate, SERIAL_8N1, _pinRXD, _pinTXD);
|
||||
drainUart();
|
||||
}
|
||||
|
||||
currentMode = mode;
|
||||
MostrarLog("Modo alterado OK: " + String(mode));
|
||||
|
||||
// 8) Retoma tarefas só quando NORMAL (evita competição em CONFIG)
|
||||
if (mode == NORMAL) resumeLoRaTasks();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -547,66 +614,69 @@ private:
|
|||
return sucesso;
|
||||
}
|
||||
|
||||
bool receberParametrosModulo(uint8_t _startAddr, uint8_t _dataLen) {
|
||||
unsigned long startTime = millis();
|
||||
bool sucesso = false;
|
||||
bool readByteWithTimeout(uint8_t &out, unsigned long toMs = 500) {
|
||||
unsigned long t0 = millis();
|
||||
while ((millis() - t0) < toMs) {
|
||||
if (_serialLoRa && _serialLoRa->available()) {
|
||||
int r = _serialLoRa->read();
|
||||
if (r >= 0) {
|
||||
out = (uint8_t)r;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// no ESP32 tem FreeRTOS; se preferir, use vTaskDelay(1);
|
||||
vTaskDelay(1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!sucesso && millis() - startTime < commandTimeout) {
|
||||
if (_serialLoRa->available()) {
|
||||
uint8_t cabecalho = _serialLoRa->read();
|
||||
if (cabecalho == CodigosFuncoes::CfgRx) { // Cabeçalho de resposta correta
|
||||
MostrarLog("Cabecalho recebido corretamente.");
|
||||
uint8_t startAddr = _serialLoRa->read();
|
||||
uint8_t dataLen = _serialLoRa->read();
|
||||
bool receberParametrosModulo(uint8_t _startAddr, uint8_t _dataLen) {
|
||||
unsigned long t0 = millis();
|
||||
// janela total mais folgada p/ rádio
|
||||
while ((millis() - t0) < 1500UL) {
|
||||
uint8_t b = 0;
|
||||
|
||||
if (!readByteWithTimeout(b, 500)) {
|
||||
// não chegou nada ainda, segue tentando até estourar 1.5s
|
||||
continue;
|
||||
}
|
||||
|
||||
if (b == CodigosFuncoes::CfgRx) {
|
||||
uint8_t startAddr = 0, dataLen = 0;
|
||||
if (!readByteWithTimeout(startAddr) || !readByteWithTimeout(dataLen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (startAddr == _startAddr && dataLen == _dataLen) {
|
||||
MostrarLog("Parâmetros recebidos corretamente.");
|
||||
|
||||
// Agora ler os registros
|
||||
uint8_t addh = _serialLoRa->read(); // byte 0
|
||||
uint8_t addl = _serialLoRa->read(); // byte 1
|
||||
parametrosAtual.address = addl; // usa só o ADDL (0~255)
|
||||
parametrosAtual.baudAndAirRate = _serialLoRa->read(); // byte 2
|
||||
parametrosAtual.packetSizeAndPower = _serialLoRa->read(); // byte 3
|
||||
parametrosAtual.channel = _serialLoRa->read(); // byte 4
|
||||
parametrosAtual.tranModeAndWorCycle = _serialLoRa->read(); // byte 5
|
||||
|
||||
if (DebugMode) {
|
||||
String log =
|
||||
"Recebido Parametros do Modulo: (" + String(dataLen) + " bytes): " +
|
||||
"0x" + String(startAddr, HEX) + " " +
|
||||
"0x" + String(dataLen, HEX) + " " +
|
||||
"0x" + String(addh, HEX) + " " +
|
||||
"0x" + String(addl, HEX) + " " +
|
||||
"0x" + String(parametrosAtual.baudAndAirRate, HEX) + " " +
|
||||
"0x" + String(parametrosAtual.packetSizeAndPower, HEX) + " " +
|
||||
"0x" + String(parametrosAtual.channel, HEX) + " " +
|
||||
"0x" + String(parametrosAtual.tranModeAndWorCycle, HEX);
|
||||
MostrarLog(log);
|
||||
uint8_t addh=0, addl=0, bAir=0, pwr=0, ch=0, wor=0;
|
||||
if (!readByteWithTimeout(addh) || !readByteWithTimeout(addl) ||
|
||||
!readByteWithTimeout(bAir) || !readByteWithTimeout(pwr) ||
|
||||
!readByteWithTimeout(ch) || !readByteWithTimeout(wor)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sucesso = true;
|
||||
}
|
||||
else {
|
||||
if (DebugMode) {
|
||||
String log = "Dados Corrompidos: (" + String(dataLen) + " bytes): 0x" + String(startAddr, HEX) + " 0x" + String(dataLen, HEX) + " ";
|
||||
for (size_t i = 0; i < dataLen; i++) {
|
||||
uint8_t c = _serialLoRa->read();
|
||||
log += "0x" + String(c, HEX) + " ";
|
||||
}
|
||||
MostrarLog(log);
|
||||
parametrosAtual.address = addl; // assumindo ADDL como address
|
||||
parametrosAtual.baudAndAirRate = bAir;
|
||||
parametrosAtual.packetSizeAndPower = pwr;
|
||||
parametrosAtual.channel = ch;
|
||||
parametrosAtual.tranModeAndWorCycle = wor;
|
||||
return true;
|
||||
} else {
|
||||
// endereçamento diferente: drena os bytes anunciados pra limpar o stream
|
||||
for (int i = 0; i < dataLen; i++) {
|
||||
uint8_t dump;
|
||||
if (!readByteWithTimeout(dump)) break;
|
||||
}
|
||||
}
|
||||
} else if (cabecalho == CodigosFuncoes::WrongMode) {
|
||||
MostrarLog("Modo invalido!");
|
||||
} else if (b == CodigosFuncoes::WrongMode) {
|
||||
// opcional: logar que o módulo respondeu “modo errado”
|
||||
// e talvez sair para re-tentar setLoRaMode(CONFIG)
|
||||
}
|
||||
}
|
||||
vTaskDelay(10);
|
||||
// senão, segue laçando e coletando até bater timeout total
|
||||
}
|
||||
|
||||
limparBufferLoRa();
|
||||
|
||||
return sucesso;
|
||||
limparBufferLoRa(); // garantir que não fique lixo
|
||||
return false;
|
||||
}
|
||||
|
||||
void enviarDadosSerial(const uint8_t* dados, int tamanho, const String& descricao = "") {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ void inicializarDependenciasI2C() {
|
|||
}
|
||||
|
||||
void setup() {
|
||||
delay(5000);
|
||||
delay(2000);
|
||||
|
||||
inicializarDependenciasI2C();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue