ajustado dados do sonar OAK

This commit is contained in:
Diego Freitas 2025-04-03 11:00:55 -03:00
parent e107e7a810
commit 8c87105398
42 changed files with 1208 additions and 578 deletions

Binary file not shown.

View File

@ -471,6 +471,7 @@
<Compile Include="Models\PerformanceModel.cs" />
<Compile Include="Models\PIDModel.cs" />
<Compile Include="Models\PZEMModel.cs" />
<Compile Include="Models\SonarCamModel.cs" />
<Compile Include="Models\SonarModel.cs" />
<Compile Include="Models\SyncDataModel.cs" />
<Compile Include="Models\TrajetoriaMapaOperacaoModel.cs" />
@ -511,6 +512,7 @@
<Compile Include="Services\PythonService.cs" />
<Compile Include="Services\PZEMService.cs" />
<Compile Include="Services\SerialService.cs" />
<Compile Include="Services\SonarService.cs" />
<Compile Include="Services\SyncDataService.cs" />
<Compile Include="Services\UltrasonicA05Service.cs" />
<Compile Include="Services\UsrDR302Service.cs" />

View File

@ -44,9 +44,9 @@
this.lblD_Dir_DT = new System.Windows.Forms.Label();
this.lblD_Dir_ET = new System.Windows.Forms.Label();
this.lblD_Mov_ET = new System.Windows.Forms.Label();
this.lblD_Cam_S0 = new System.Windows.Forms.Label();
this.lblD_Cam_S1 = new System.Windows.Forms.Label();
this.lblD_Knt = new System.Windows.Forms.Label();
this.lblD_Cam_0 = new System.Windows.Forms.Label();
this.lblD_Cam_1 = new System.Windows.Forms.Label();
this.lblD_Snr = new System.Windows.Forms.Label();
this.lblDiagnosticos = new System.Windows.Forms.Label();
this.lblOperacao = new System.Windows.Forms.Label();
this.lblAjustes = new System.Windows.Forms.Label();
@ -254,39 +254,39 @@
this.lblD_Mov_ET.Text = "MOV";
this.lblD_Mov_ET.Click += new System.EventHandler(this.lblModulo_Click);
//
// lblD_Cam_S0
// lblD_Cam_0
//
this.lblD_Cam_S0.AutoSize = true;
this.lblD_Cam_S0.BackColor = System.Drawing.Color.Lavender;
this.lblD_Cam_S0.Cursor = System.Windows.Forms.Cursors.Hand;
this.lblD_Cam_S0.Location = new System.Drawing.Point(85, 470);
this.lblD_Cam_S0.Name = "lblD_Cam_S0";
this.lblD_Cam_S0.Size = new System.Drawing.Size(52, 24);
this.lblD_Cam_S0.TabIndex = 29;
this.lblD_Cam_S0.Text = "CAM";
this.lblD_Cam_S0.Click += new System.EventHandler(this.lblModulo_Click);
this.lblD_Cam_0.AutoSize = true;
this.lblD_Cam_0.BackColor = System.Drawing.Color.Lavender;
this.lblD_Cam_0.Cursor = System.Windows.Forms.Cursors.Hand;
this.lblD_Cam_0.Location = new System.Drawing.Point(85, 470);
this.lblD_Cam_0.Name = "lblD_Cam_0";
this.lblD_Cam_0.Size = new System.Drawing.Size(52, 24);
this.lblD_Cam_0.TabIndex = 29;
this.lblD_Cam_0.Text = "CAM";
this.lblD_Cam_0.Click += new System.EventHandler(this.lblModulo_Click);
//
// lblD_Cam_S1
// lblD_Cam_1
//
this.lblD_Cam_S1.AutoSize = true;
this.lblD_Cam_S1.Cursor = System.Windows.Forms.Cursors.Hand;
this.lblD_Cam_S1.Location = new System.Drawing.Point(334, 470);
this.lblD_Cam_S1.Name = "lblD_Cam_S1";
this.lblD_Cam_S1.Size = new System.Drawing.Size(52, 24);
this.lblD_Cam_S1.TabIndex = 30;
this.lblD_Cam_S1.Text = "CAM";
this.lblD_Cam_S1.Click += new System.EventHandler(this.lblModulo_Click);
this.lblD_Cam_1.AutoSize = true;
this.lblD_Cam_1.Cursor = System.Windows.Forms.Cursors.Hand;
this.lblD_Cam_1.Location = new System.Drawing.Point(334, 470);
this.lblD_Cam_1.Name = "lblD_Cam_1";
this.lblD_Cam_1.Size = new System.Drawing.Size(52, 24);
this.lblD_Cam_1.TabIndex = 30;
this.lblD_Cam_1.Text = "CAM";
this.lblD_Cam_1.Click += new System.EventHandler(this.lblModulo_Click);
//
// lblD_Knt
// lblD_Snr
//
this.lblD_Knt.AutoSize = true;
this.lblD_Knt.Cursor = System.Windows.Forms.Cursors.Hand;
this.lblD_Knt.Location = new System.Drawing.Point(214, 125);
this.lblD_Knt.Name = "lblD_Knt";
this.lblD_Knt.Size = new System.Drawing.Size(48, 24);
this.lblD_Knt.TabIndex = 31;
this.lblD_Knt.Text = "KNT";
this.lblD_Knt.Click += new System.EventHandler(this.lblModulo_Click);
this.lblD_Snr.AutoSize = true;
this.lblD_Snr.Cursor = System.Windows.Forms.Cursors.Hand;
this.lblD_Snr.Location = new System.Drawing.Point(210, 125);
this.lblD_Snr.Name = "lblD_Snr";
this.lblD_Snr.Size = new System.Drawing.Size(49, 24);
this.lblD_Snr.TabIndex = 31;
this.lblD_Snr.Text = "SNR";
this.lblD_Snr.Click += new System.EventHandler(this.lblModulo_Click);
//
// lblDiagnosticos
//
@ -528,10 +528,10 @@
this.Controls.Add(this.lblDiagnosticos);
this.Controls.Add(this.picDiagnosticos);
this.Controls.Add(this.picOperacao);
this.Controls.Add(this.lblD_Knt);
this.Controls.Add(this.lblD_Snr);
this.Controls.Add(this.picAjustes);
this.Controls.Add(this.lblD_Cam_S1);
this.Controls.Add(this.lblD_Cam_S0);
this.Controls.Add(this.lblD_Cam_1);
this.Controls.Add(this.lblD_Cam_0);
this.Controls.Add(this.picDesligar);
this.Controls.Add(this.lblD_Dir_ET);
this.Controls.Add(this.lblD_Mov_ET);
@ -590,9 +590,9 @@
private System.Windows.Forms.PictureBox picDiagnosticos;
private System.Windows.Forms.PictureBox picOperacao;
private System.Windows.Forms.PictureBox picDesligar;
private System.Windows.Forms.Label lblD_Cam_S0;
private System.Windows.Forms.Label lblD_Cam_S1;
private System.Windows.Forms.Label lblD_Knt;
private System.Windows.Forms.Label lblD_Cam_0;
private System.Windows.Forms.Label lblD_Cam_1;
private System.Windows.Forms.Label lblD_Snr;
private System.Windows.Forms.PictureBox picAjustes;
private System.Windows.Forms.Label lblDiagnosticos;
private System.Windows.Forms.Label lblOperacao;

View File

@ -134,66 +134,6 @@ namespace AgroBase.Forms.IHM
lblCodigoFalha.Click += LblCodigoFalha_Click;
}
/*
private async Task tmrDispositivos_Tick()
{
CodFalha = Variaveis.OperacaoEmAndamento.RetornaCodigoFalha();
var Labels = this.Controls.OfType<Label>().Where(y => y.Name.Contains("lblD_")).ToList();
Labels.ForEach(lbl =>
{
T_Code Dispositivo = (T_Code)Enum.Parse(typeof(T_Code), lbl.Name.Split('_')[1]);
string Mod_ID = lbl.Name.Split('_').Length == 3 ? lbl.Name.Split('_')[2] : lbl.Name.Split('_')[1];
if (Dispositivo == T_Code.Cam)
{
var listaCameras = CameraService.AtualizaListaCameras();
var CameraCaminho = Variaveis.OperacaoEmAndamento.CameraCaminhoKinect;
if (CameraCaminho != null && Mod_ID == CameraCaminho.ID)
{
lbl.ForeColor = !listaCameras.Any(x => x.Value == CameraCaminho.CameraSelecionada) ? Color.DarkRed : CameraCaminho.camera.selectedCamera == 0 ? Color.Gold : Color.DarkGreen;
}
else
{
var CameraSolo = Variaveis.OperacaoEmAndamento.CamerasSolo.FirstOrDefault(x => x.ID == Mod_ID);
if (CameraSolo != null)
{
lbl.ForeColor = !listaCameras.Any(x => x.Value == CameraSolo.CameraSelecionada) ? Color.DarkRed : CameraSolo.camera.selectedCamera == 0 ? Color.Gold : Color.DarkGreen;
}
}
}
else
{
var Modulo = SerialService.DispositivosMapeados.FirstOrDefault(x => x.Dispositivo == Dispositivo && (x.Mod_ID == Mod_ID || x.Mod_ID == null));
if (Modulo != null)
{
lbl.ForeColor = Modulo.Erro ? Color.Gold : Modulo.Conectado ? Color.DarkGreen : Color.DarkRed;
}
else
{
lbl.ForeColor = Color.Black;
}
}
});
bool mqttConectado = Variaveis.MqttService.StatusConexao();
lblMqtt.Text = "MQTT: " + (mqttConectado ? "Conectado" : "Desconectado");
lblMqtt.ForeColor = mqttConectado ? Color.Green : Color.Red;
bool wifiConectado = WifiService.WifiConectado;
bool wifiDisponivel = WifiService.WifiDisponivel;
lblWifi.Text = "Wi-Fi: " + (wifiConectado ? "Conectado" : wifiDisponivel ? "Disponível" : "Desconectado");
lblWifi.ForeColor = wifiConectado ? Color.Green : wifiDisponivel ? Color.Yellow : Color.Red;
bool opLiberada = Variaveis.OperacaoEmAndamento.OperacaoLiberada;
lblOperacaoLiberada.Text = "Operação Liberada: " + (opLiberada ? "Sim" : "Não");
lblOperacaoLiberada.ForeColor = opLiberada ? Color.Green : Color.Red;
lblCodigoFalha.Text = $"Código de Falha: {CodFalha}";
picWifi.Image = APIService.HasInternet ? Resources.wifi_on : Resources.wifi_off;
}
*/
private async Task tmrDispositivos_Tick()
{
try
@ -220,12 +160,26 @@ namespace AgroBase.Forms.IHM
var Labels = this.Controls.OfType<Label>().Where(y => y.Name.Contains("lblD_")).ToList();
var listaCameras = OAKCameraService.GetListaCameras();
listaCameras.RemoveAt(0);
Labels.ForEach(lbl =>
{
T_Code Dispositivo = (T_Code)Enum.Parse(typeof(T_Code), lbl.Name.Split('_')[1]);
string Mod_ID = lbl.Name.Split('_').Length == 3 ? lbl.Name.Split('_')[2] : lbl.Name.Split('_')[1];
if (Dispositivo == T_Code.Cam)
{
Mod_ID = T_Code.Cam.ToString() + "_" + Mod_ID;
var CameraSolo = Variaveis.OperacaoEmAndamento.CamerasSolo.FirstOrDefault(x => x.ID == Mod_ID);
if (CameraSolo != null)
{
lbl.ForeColor = !listaCameras.Any(x => x.Id == CameraSolo.DeviceID) ?
Color.DarkRed :
CameraSolo.camera.cameraIndex == 0 ?
Color.Gold :
Color.DarkGreen;
}
}
else if (Dispositivo == T_Code.Snr)
{
var CameraCaminho = Variaveis.OperacaoEmAndamento.CameraCaminho;
if (CameraCaminho != null && Mod_ID == CameraCaminho.ID)
@ -236,18 +190,6 @@ namespace AgroBase.Forms.IHM
? Color.Gold
: Color.DarkGreen;
}
else
{
var CameraSolo = Variaveis.OperacaoEmAndamento.CamerasSolo.FirstOrDefault(x => x.ID == Mod_ID);
if (CameraSolo != null)
{
lbl.ForeColor = !listaCameras.Any(x => x.Id == CameraSolo.DeviceID) ?
Color.DarkRed :
CameraSolo.camera.cameraIndex == 0 ?
Color.Gold :
Color.DarkGreen;
}
}
}
else
{

View File

@ -175,8 +175,8 @@ namespace AgroBase.Forms.Operacoes
lblRPM.Text = _Sensoriamento.Movimentacao.RPMMedio.ToString("0") + " rpm";
lblVelocidade.Text = _Sensoriamento.Movimentacao.VelocidadeMedia.ToString("0.00");
var Sonar = _Sensoriamento.SonarFrontal_Kinect;
bool sonarAtivado = (Sonar?.Iniciado ?? false) && Variaveis.OperacaoEmAndamento.Controle.SonarAtivado;
var Sonar = _Sensoriamento.Sonar;
bool sonarAtivado = Sonar.Iniciado && Variaveis.OperacaoEmAndamento.Controle.SonarAtivado;
chbSonarDesvioAutomatico.Enabled = sonarAtivado;
chbMostrarGrade.Enabled = sonarAtivado;
if (!sonarAtivado)

View File

@ -277,7 +277,7 @@ namespace AgroBase.Forms.Operacoes
try
{
//DesenharInclinacao((Panel)sender, e, (float)cameraCaminho.Angulo);
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)(Variaveis.OperacaoEmAndamento.Sensoriamento.AnguloRuaCamera), 90);
FuncoesGlobais.DesenharInclinacao((Panel)sender, e, (float)(Variaveis.OperacaoEmAndamento.Sensoriamento.Sonar.AnguloRuaCamera), 90);
}
catch { }
}

View File

@ -26,13 +26,12 @@ namespace AgroBase.Forms.Operacoes
List<PzmSensoriamentoLogModel> LogsPzem = new List<PzmSensoriamentoLogModel>();
List<WitSensoriamentoLogModel> LogsWt901C = new List<WitSensoriamentoLogModel>();
List<UltrasonicA05Model> LogsA05 = new List<UltrasonicA05Model>();
//List<KinectModel> LogsKinect = new List<KinectModel>();
List<SonarCamModel> LogsSonar = new List<SonarCamModel>();
List<List<CamSoloSensoriamentoLogModel>> LogsCam_Solo = new List<List<CamSoloSensoriamentoLogModel>>();
List<string> pathImagensSolo = new List<string>();
List<PictureBox> picsCamSolo = new List<PictureBox>();
List<CamCaminhoSensoriamentoLogModel> LogsCam_Caminho = new List<CamCaminhoSensoriamentoLogModel>();
string pathImagensCaminho = "";
string pathImagensSonarRGB = "";
string pathImagensMapaCalor = "";
DateTime MomentoAtual = DateTime.Now;
@ -136,9 +135,8 @@ namespace AgroBase.Forms.Operacoes
LogsPzem = JsonConvert.DeserializeObject<PzmSensoriamentoLogModel[]>(OperacaoModel.DeserializarDadosOperacao(ofd.FileName, data.pzm ?? Enums.T_Code.Pzm.ToString())).ToList();
LogsWt901C = JsonConvert.DeserializeObject<WitSensoriamentoLogModel[]>(OperacaoModel.DeserializarDadosOperacao(ofd.FileName, data.wit ?? Enums.T_Code.Wit.ToString())).ToList();
LogsA05 = JsonConvert.DeserializeObject<UltrasonicA05Model[]>(OperacaoModel.DeserializarDadosOperacao(ofd.FileName, data.a05 ?? Enums.T_Code.A05.ToString())).ToList();
//LogsKinect = JsonConvert.DeserializeObject<KinectModel[]>(DeserializarDadosOperacao(ofd.FileName, data.knt ?? Enums.T_Code.Knt.ToString())).ToList();
LogsSonar = JsonConvert.DeserializeObject<SonarCamModel[]>(OperacaoModel.DeserializarDadosOperacao(ofd.FileName, data.snr ?? Enums.T_Code.Snr.ToString())).ToList();
LogsCam_Caminho = JsonConvert.DeserializeObject<CamCaminhoSensoriamentoLogModel[]>(OperacaoModel.DeserializarDadosOperacao(ofd.FileName, data.cam_caminho)).ToList();
pathImagensSonarRGB = ofd.FileName.Replace("data.lgop", data.knt + "/rgb_");
pathImagensMapaCalor = ofd.FileName.Replace("data.lgop", data.cam_caminho + "/");
pathImagensCaminho = ofd.FileName.Replace("data.lgop", data.cam_caminho + "/");
@ -1060,7 +1058,7 @@ namespace AgroBase.Forms.Operacoes
AtualizarInformacoesSensoriamento();
//AtualizarInformacoesKinect();
AtualizarInformacoesSonar();
AtualizarInformacoesCPU();
}
@ -1136,7 +1134,6 @@ namespace AgroBase.Forms.Operacoes
private void AtualizarInformacoesCameras()
{
picCameraCaminho.Image = CarregarImagemCamera(pathImagensCaminho);
picMapaCalor.Image = CarregarImagemCamera(pathImagensMapaCalor, "_heat");
AtualizarInformacoesCameraCaminho();
for (int i = 0; i < LogsCam_Solo.Count(); i++)
@ -1198,11 +1195,11 @@ namespace AgroBase.Forms.Operacoes
.ToList();
//var LogKnt = LogsKinect.FirstOrDefault(x => x.Momento == MomentoAtual);
var LogSnr = LogsSonar.FirstOrDefault(x => x.Momento == MomentoAtual);
var LogOpe = LogsOperacao.FirstOrDefault(x => x.Momento == MomentoAtual);
MapaDinamico.AtualizarDados(
null, //LogKnt.Iniciado && LogKnt.StatusDetecao ? LogKnt.ObstaculoCritico : null,
LogSnr.Iniciado && LogSnr.DirecaoDesvio != Enums.Direcao.Frente ? LogSnr.ObstaculoCritico : null,
(float)LogOpe.Trajetoria.AnguloCaminho,
(float)LogOpe.Gps.AnguloCarroDefinido,
Log,
@ -1445,9 +1442,9 @@ namespace AgroBase.Forms.Operacoes
}
/*private void AtualizarInformacoesKinect()
private void AtualizarInformacoesSonar()
{
var Log = LogsKinect.FirstOrDefault(x => x.Momento == MomentoAtual);
var Log = LogsSonar.FirstOrDefault(x => x.Momento == MomentoAtual);
txtEspacoLivreEsquerda.Text = Log.EspacoLivreEsquerda.ToString("0.00");
txtEspacoLivreDireita.Text = Log.EspacoLivreDireita.ToString("0.00");
txtDesvioNecessario.Text = Log.DesvioNecessario ? "Sim" : "Não";
@ -1482,17 +1479,17 @@ namespace AgroBase.Forms.Operacoes
);
}
picMapaCalor.Image = CarregarImagemCamera(pathImagensMapaCalor);
picMapaCalor.Image = CarregarImagemCamera(pathImagensMapaCalor, "_heat");
picSonarRGB.Image = CarregarImagemCamera(pathImagensSonarRGB);
picSonarRGB.Image = CarregarImagemCamera(pathImagensCaminho);
if (chbGrade.Checked)
{
Bitmap bitmap = (Bitmap)picSonarRGB.Image.Clone();
bitmap = (Bitmap)KinectService.ExibirObstaculos(bitmap, Log.Subdivisoes, Log.Obstaculos).Clone();
bitmap = (Bitmap)SonarService.ExibirObstaculos(bitmap, Log).Clone();
picSonarRGB.Image = (Bitmap)bitmap.Clone();
}
}*/
}
private void AtualizarInformacoesCameraCaminho()
{

View File

@ -47,6 +47,11 @@ namespace AgroBase.Models
public double AnguloDireito { get; set; }
public DateTime UltimaMensagemRecebida { get; set; } = DateTime.MinValue;
public DateTime UltimaMensagemProcessada { get; set; } = DateTime.MinValue;
public SonarCamModel Sonar { get; set; } = new SonarCamModel();

View File

@ -61,6 +61,9 @@ namespace AgroBase.Models
public int ErvasNoRadar { get; set; }
public DateTime UltimaMensagemRecebida { get; set; } = DateTime.MinValue;
public DateTime UltimaMensagemProcessada { get; set; } = DateTime.MinValue;
}

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AgroBase.Models
namespace AgroBase.Models
{
public class Enums
{
@ -66,6 +60,7 @@ namespace AgroBase.Models
A05 = 114,
Mod = 115,
Oid = 116,
Snr = 117,
}
public enum F_Code
@ -173,10 +168,11 @@ namespace AgroBase.Models
public enum ParametrosOperacao
{
CameraSolo,
Kinect,
Mapa,
Joystick
CameraSolo = 0,
Kinect = 1,
Mapa = 2,
Joystick = 3,
Sonar = 4
}
public enum StatusLED

View File

@ -749,8 +749,8 @@ namespace AgroBase
{
List<Keys> ComandosImpedidos = new List<Keys>();
var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.SonarFrontal_Kinect;
if ((Sonar?.Iniciado ?? false) && Variaveis.OperacaoEmAndamento.Controle.SonarAtivado && (Sonar?.DesvioNecessario ?? false))
var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.Sonar;
if (Sonar.Iniciado && Variaveis.OperacaoEmAndamento.Controle.SonarAtivado && Sonar.DesvioNecessario)
{
switch (Sonar.DirecaoDesvio)
{

View File

@ -463,287 +463,7 @@ namespace AgroBase.Models
}
}
public class Obstaculo
{
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public float DistanciaMedia_mm { get; set; }
public float Largura_mm { get; set; }
public float Altura_mm { get; set; }
public bool ObstaculoTrajetoria { get; set; }
public bool ObstaculoSuperior { get; set; }
public TipoObstaculo Tipo { get; set; }
public bool DesvioNecessario
{
get
{
int toleranciaObstaculo = ObstaculoSuperior ? KinectService.Parametros.toleranciaDeteccaoSuperior : ObstaculoTrajetoria ? KinectService.Parametros.toleranciaDeteccaoTrajetoria : 100;
bool larguraMinima = Largura_mm >= toleranciaObstaculo;
bool alutraMinima = Altura_mm >= toleranciaObstaculo; // (VariaveisEquipamento.DiametroRoda * 1000 / 2); // No minimo precisa ser mais alto que a metade da roda
bool desvioNecessario = larguraMinima && alutraMinima;
return desvioNecessario;
}
}
public float PercentualEsquerda { get; private set; }
public float PercentualDireita { get; private set; }
public Direcao DirecaoDesvio
{
get
{
Direcao direcaoDesvio = Direcao.Frente;
if (DesvioNecessario)
{
// Calcular as posições extremas do obstáculo
float posicaoInicioX = X;
float posicaoFimX = X + Width;
float centro = KinectService.Parametros.depthFrameWidth / 2;
// Calcular quanto do obstáculo está à esquerda e à direita do centro
float percentualEsquerda = 0;
float percentualDireita = 0;
if (posicaoFimX <= centro)
{
// Obstáculo todo à esquerda
percentualEsquerda = 1;
}
else if (posicaoInicioX >= centro)
{
// Obstáculo todo à direita
percentualDireita = 1;
}
else
{
// Parte do obstáculo está à esquerda e parte à direita
float larguraEsquerda = centro - posicaoInicioX;
float larguraDireita = posicaoFimX - centro;
percentualEsquerda = (larguraEsquerda / Width);
percentualDireita = (larguraDireita / Width);
}
// Definir a direção do desvio com base nos percentuais
if (DistanciaMedia_mm < (KinectService.Parametros.minDepth * 1.1) && (DistanciaDaLateralDireita < VariaveisEquipamento.LarguraDireita || DistanciaLivreEsquerda < VariaveisEquipamento.LarguraEsquerda))
{
direcaoDesvio = Direcao.Parado;
}
else if (percentualDireita > percentualEsquerda)
{
direcaoDesvio = Direcao.Esquerda; // Desviar para a esquerda
}
else
{
direcaoDesvio = Direcao.Direita; // Desviar para a direita
}
// Armazenar os percentuais como novas variáveis
this.PercentualEsquerda = percentualEsquerda;
this.PercentualDireita = percentualDireita;
}
return direcaoDesvio;
}
}
public float DistanciaLivreEsquerda
{
get
{
float ratio = KinectService.CalculatePixelToMMRatio(DistanciaMedia_mm);
float espacoLivre = (float)(X * ratio);
return espacoLivre;
}
}
public float DistanciaLivreDireita
{
get
{
float ratio = KinectService.CalculatePixelToMMRatio(DistanciaMedia_mm);
int tamanho = KinectService.Parametros.depthFrameWidth - (X + Width);
float espacoLivre = (float)((tamanho) * ratio);
return espacoLivre;
}
}
public double DistanciaDaLateralDireita
{
get
{
// Coordenadas do ponto central do robô (origem)
int centroX = KinectService.Parametros.depthFrameWidth / 2;
double profundidadeZ = DistanciaMedia_mm;
float ratio = KinectService.CalculatePixelToMMRatio((float)profundidadeZ);
var distancia = (((X + Width) - centroX) * ratio) / 10;
return distancia;
}
}
public double DistanciaDaLateralEsquerda
{
get
{
// Coordenadas do ponto central do robô (origem)
int centroX = KinectService.Parametros.depthFrameWidth / 2;
double profundidadeZ = DistanciaMedia_mm;
float ratio = KinectService.CalculatePixelToMMRatio((float)profundidadeZ);
var distancia = ((centroX - X) * ratio) / 10;
return distancia;
}
}
public bool Adireita
{
get
{
int origemX = KinectService.Parametros.depthFrameWidth / 2;
return X + Width > origemX;
}
}
public bool Aesquerda
{
get
{
int origemX = KinectService.Parametros.depthFrameWidth / 2;
return X < origemX;
}
}
public double DeslocamentoNecessarioDesvio
{
get
{
if (DirecaoDesvio == Direcao.Direita)
{
return DeslocamentoNecessarioDireita;
}
else if (DirecaoDesvio == Direcao.Esquerda)
{
return DeslocamentoNecessarioEsquerda;
}
else
{
return 0;
}
}
}
public double DeslocamentoNecessarioEsquerda
{
get
{
if (PercentualDireita > 0 || PercentualEsquerda > 0)
{
double deslocamento = ((((VariaveisEquipamento.LarguraEsquerda + VariaveisEquipamento.LarguraDireita) / 2.0) + DistanciaDaLateralEsquerda) * (1 + PercentualEsquerda)) + SonarModel.MargemSegurancaDesvio;
if (deslocamento < 0)
{
deslocamento = 0;
}
return deslocamento;
}
else
{
return 0;
}
}
}
public double DeslocamentoNecessarioDireita
{
get
{
if (PercentualDireita > 0 || PercentualEsquerda > 0)
{
double deslocamento = ((((VariaveisEquipamento.LarguraEsquerda + VariaveisEquipamento.LarguraDireita) / 2.0) + DistanciaDaLateralDireita) * (1 + PercentualDireita)) + SonarModel.MargemSegurancaDesvio;
if (deslocamento < 0)
{
deslocamento = 0;
}
return deslocamento;
}
else
{
return 0;
}
}
}
public double AnguloParaDesvio
{
get
{
double anguloDesvio = 0;
Direcao direcaoDesvio = DirecaoDesvio;
if (direcaoDesvio == Direcao.Esquerda)
{
anguloDesvio = AnguloParaDesvioEsquerda;
}
else if (direcaoDesvio == Direcao.Direita)
{
anguloDesvio = AnguloParaDesvioDireita;
}
return anguloDesvio;
}
}
public double AnguloParaDesvioEsquerda
{
get
{
// Usando trigonometria para calcular o ângulo necessário
// Nota: Assegure-se de converter o resultado de arco seno para graus, se necessário
double anguloRad = Math.Atan((DistanciaMedia_mm / 10) / DeslocamentoNecessarioEsquerda);
double anguloDesvio = (anguloRad * (180 / Math.PI)); // Convertendo radianos para graus
anguloDesvio = anguloDesvio - 90;
// Atribuição do ângulo calculado ao ângulo de desvio, com verificação de limites
return Math.Min(anguloDesvio, SonarModel.AnguloDesvioMaximo);
}
}
public double AnguloParaDesvioDireita
{
get
{
// Usando trigonometria para calcular o ângulo necessário
// Nota: Assegure-se de converter o resultado de arco seno para graus, se necessário
double anguloRad = Math.Atan((DistanciaMedia_mm / 10) / DeslocamentoNecessarioDireita);
double anguloDesvio = (anguloRad * (180 / Math.PI)); // Convertendo radianos para graus
anguloDesvio = 90 - anguloDesvio;
// Atribuição do ângulo calculado ao ângulo de desvio, com verificação de limites
return Math.Min(anguloDesvio, SonarModel.AnguloDesvioMaximo);
}
}
public Obstaculo Clone()
{
return new Obstaculo()
{
Altura_mm = this.Altura_mm,
DistanciaMedia_mm = this.DistanciaMedia_mm,
Height = this.Height,
Largura_mm = this.Largura_mm,
ObstaculoSuperior = this.ObstaculoSuperior,
ObstaculoTrajetoria = this.ObstaculoTrajetoria,
PercentualDireita = this.PercentualDireita,
PercentualEsquerda = this.PercentualEsquerda,
Tipo = this.Tipo,
Width = this.Width,
X = this.X,
Y = this.Y,
};
}
}
public class KinectParametrosModel
{
public int Angulo { get; set; }
@ -776,55 +496,7 @@ namespace AgroBase.Models
}
// Classe para armazenar informações sobre cada subdivisão
public class Subdivisao
{
public int idxX { get; set; }
public int idxY { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int Largura { get; set; }
public int Altura { get; set; }
public int ProfundidadeMedia { get; set; }
public int ProfundidadeEsperada { get; set; }
public int Tolerancia { get; set; }
public bool IsZonaSuperior { get; set; }
public int DiferencaProfundidade
{
get
{
return ProfundidadeMedia - ProfundidadeEsperada;
}
}
public bool ObstaculoDetectado
{
get
{
if (IsZonaSuperior)
{
return ProfundidadeMedia > 0 && (ProfundidadeMedia + Tolerancia) < ProfundidadeEsperada;
}
else
{
return Math.Abs(DiferencaProfundidade) > Tolerancia;
}
}
}
public TipoObstaculo Tipo
{
get
{
if (IsZonaSuperior)
{
return ObstaculoDetectado ? TipoObstaculo.Ressalto : TipoObstaculo.Rebaixo;
}
else
{
return ObstaculoDetectado && DiferencaProfundidade > 0 ? TipoObstaculo.Rebaixo : TipoObstaculo.Ressalto;
}
}
}
}
public class SimulacaoDesvio
{

View File

@ -156,8 +156,9 @@ namespace AgroBase.Models.Operacoes
}
case StatusCarroMapa.Direcionando:
{
var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.Sonar;
bool Manobrando = Variaveis.OperacaoEmAndamento.Trajetoria.ManobrandoEntreRuas;
bool DesvioSonar = (KinectService.Iniciado && Variaveis.OperacaoEmAndamento.Sensoriamento.SonarFrontal_Kinect.DesvioNecessario);
bool DesvioSonar = Sonar.Iniciado && Sonar.DesvioNecessario;
if (Manobrando || DesvioSonar)
{
Controle.PercentualVelocidadeSP = Controle.PercentualVelocidadeMin;

View File

@ -228,7 +228,8 @@ namespace AgroBase.Models
{
var parametrosMandatorios = Variaveis.OperacaoEmAndamento.ParametrosMandatorios;
if (parametrosMandatorios.Any(x => x.Mandatorio && x.Parametro == ParametrosOperacao.CameraSolo) && Variaveis.OperacaoEmAndamento.CamerasSolo.Count() < Variaveis.OperacaoEmAndamento.QuantidadeCamerasSolo) _operacaoLiberada = false;
if (parametrosMandatorios.Any(x => x.Mandatorio && x.Parametro == ParametrosOperacao.Kinect) && (!KinectService.Iniciado || KinectService.Leitura == null)) _operacaoLiberada = false;
if (parametrosMandatorios.Any(x => x.Mandatorio && x.Parametro == ParametrosOperacao.Sonar) && (Variaveis.OperacaoEmAndamento.CameraCaminho?.camera?.cameraIndex ?? -1) == -1) _operacaoLiberada = false;
//if (parametrosMandatorios.Any(x => x.Mandatorio && x.Parametro == ParametrosOperacao.Kinect) && (!KinectService.Iniciado || KinectService.Leitura == null)) _operacaoLiberada = false;
if (parametrosMandatorios.Any(x => x.Mandatorio && x.Parametro == ParametrosOperacao.Mapa) && !Variaveis.OperacaoEmAndamento.Mapa.mapaService.Carregado) _operacaoLiberada = false;
if (parametrosMandatorios.Any(x => x.Mandatorio && x.Parametro == ParametrosOperacao.Joystick) && GeneralJoystick.JoystickConectado == null) _operacaoLiberada = false;
if (!Variaveis.OperacaoEmAndamento.DispositivosIndividuaisConectados) _operacaoLiberada = false;
@ -617,7 +618,7 @@ namespace AgroBase.Models
},
new OperacaoParametrosMandatoriosModel()
{
Parametro = ParametrosOperacao.Kinect,
Parametro = ParametrosOperacao.Sonar,
Mandatorio = false,
},
new OperacaoParametrosMandatoriosModel()
@ -720,7 +721,7 @@ namespace AgroBase.Models
},
new OperacaoParametrosMandatoriosModel()
{
Parametro = ParametrosOperacao.Kinect,
Parametro = ParametrosOperacao.Sonar,
Mandatorio = true,
},
new OperacaoParametrosMandatoriosModel()
@ -890,10 +891,10 @@ namespace AgroBase.Models
}
}
if (KinectService.Iniciado)
/*if (KinectService.Iniciado)
{
KinectService.RecalibrarSubdivisoes();
}
}*/
}
@ -1042,7 +1043,7 @@ namespace AgroBase.Models
CameraSoloModel CameraSolo = new CameraSoloModel()
{
ID = "S" + i.ToString(),
ID = T_Code.Cam.ToString() + "_" + i.ToString(),
Nome = CamNome,
DeviceID = deviceId,
Posicao = CamerasSolo.Count(),
@ -1074,7 +1075,7 @@ namespace AgroBase.Models
var cameraCaminho = new CameraCaminhoModel()
{
ID = "C",
ID = T_Code.Snr.ToString(),
Nome = "Cam_Caminho",
DeviceID = deviceIdCaminho,
ArquivoLeitura = "leitura_ruas.json",
@ -1135,6 +1136,8 @@ namespace AgroBase.Models
CameraSolo.MqttTopico,
async (Mensagem) =>
{
CameraSolo.UltimaMensagemRecebida = Mensagem.Momento;
if (Mensagem.Momento > CameraSolo.camera.IniciadoEm && Mensagem.Mensagem == "OK")
{
CameraSolo.camera.ProntoEm = Mensagem.Momento;
@ -1189,7 +1192,7 @@ namespace AgroBase.Models
cameraCaminho.MqttTopico,
async (Mensagem) =>
{
cameraCaminho.UltimaMensagemRecebida = DateTime.Now;
cameraCaminho.UltimaMensagemRecebida = Mensagem.Momento;
if (Mensagem.Momento > cameraCaminho.camera.IniciadoEm && Mensagem.Mensagem == "OK_1")
{
cameraCaminho.camera.ProntoEm = Mensagem.Momento;
@ -1404,8 +1407,9 @@ namespace AgroBase.Models
{
if (Variaveis.OperacaoEmAndamento.Controle.SonarAtivado)
{
var Sonar = Variaveis.OperacaoEmAndamento.Sensoriamento.SonarFrontal_Kinect;
if ((Sonar?.Iniciado ?? false) && (Sonar?.DesvioNecessario ?? false))
var Camera = Variaveis.OperacaoEmAndamento.CameraCaminho;
var Sonar = CameraCaminho?.Sonar;
if ((Camera?.Iniciada ?? false) && (Sonar?.DesvioNecessario ?? false))
{
Keys TeclaComando =
Sonar.DirecaoDesvio == Direcao.Esquerda ? Keys.Left :
@ -1500,6 +1504,10 @@ namespace AgroBase.Models
private void AtualizaLeituraCameraSolo(CameraSoloModel CameraSolo)
{
if (CameraSolo.UltimaMensagemRecebida == CameraSolo.UltimaMensagemProcessada)
{
return;
}
if (CameraSolo.camera._mqttTopico?.Mensagens?.Any(x => x.Momento > CameraSolo.camera.IniciadoEm && x.Mensagem != "OK") ?? false)
{
@ -1509,6 +1517,7 @@ namespace AgroBase.Models
if (Mensagem != null)
{
CameraSolo.Leitura = JsonConvert.DeserializeObject<CameraCoordenadasFrameModel>(Mensagem.Mensagem);
CameraSolo.UltimaMensagemProcessada = CameraSolo.UltimaMensagemRecebida;
}
}
catch (Exception ex)
@ -1598,6 +1607,11 @@ namespace AgroBase.Models
return;
}
if (cameraCaminho.UltimaMensagemRecebida == cameraCaminho.UltimaMensagemProcessada)
{
return;
}
var MqttTopico = cameraCaminho.camera._mqttTopico;
if (MqttTopico != null && MqttTopico.Mensagens.Any(x => x.Momento > cameraCaminho.camera.IniciadoEm && !x.Mensagem.StartsWith("OK")))
{
@ -1606,13 +1620,14 @@ namespace AgroBase.Models
var Mensagem = MqttTopico.Mensagens.LastOrDefault(x => x.Momento > cameraCaminho.camera.IniciadoEm);
if (Mensagem != null)
{
Console.WriteLine(Mensagem.Mensagem);
cameraCaminho.Leitura = JsonConvert.DeserializeObject<CameraDeepLabV3PlusModel>(Mensagem.Mensagem);
cameraCaminho.Sonar.DetectarObstaculos(cameraCaminho.Leitura.subdivisoes);
cameraCaminho.UltimaMensagemProcessada = cameraCaminho.UltimaMensagemRecebida;
}
}
catch
catch (Exception ex)
{
Console.WriteLine("Erro ao processar leitura da camera caminho: " + ex.Message);
}
}
// Atualizar representação gráfica do resultado da leitura do caminho
@ -2008,6 +2023,10 @@ namespace AgroBase.Models
};
SalvarLog(T_Code.A05.ToString(), logA05, Fim);
SonarCamModel logSnr = Variaveis.OperacaoEmAndamento.Sensoriamento.Sonar?.Clone();
logSnr.Momento = Agora;
SalvarLog(T_Code.Snr.ToString(), logSnr, Fim);
//SalvarLogKinect(Agora);
Task.Run(async () => await SalvarLogCameras(Agora));
@ -2027,7 +2046,7 @@ namespace AgroBase.Models
pzm = T_Code.Pzm.ToString(),
wit = T_Code.Wit.ToString(),
a05 = T_Code.A05.ToString(),
knt = T_Code.Knt.ToString(),
snr = T_Code.Snr.ToString(),
cam_caminho = Variaveis.OperacaoEmAndamento.CameraCaminho.Nome,
cam_solo = Variaveis.OperacaoEmAndamento.CamerasSolo.Select( x=> x.Nome).ToList(),
};
@ -2270,11 +2289,11 @@ namespace AgroBase.Models
(_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.CameraSolo && x.Mandatorio) &&
Variaveis.OperacaoEmAndamento.CamerasSolo.Count(y => y.Iniciada) == Variaveis.OperacaoEmAndamento.QuantidadeCamerasSolo);
bool _kinectConectado =
!_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Kinect) ||
_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Kinect && !x.Mandatorio) ||
(_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Kinect && x.Mandatorio) &&
(_sensoriamento.SonarFrontal_Kinect != null && _sensoriamento.SonarFrontal_Kinect.Iniciado));
bool _sonarConectado =
!_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Sonar) ||
_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Sonar && !x.Mandatorio) ||
(_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Sonar && x.Mandatorio) &&
(_sensoriamento?.Sonar != null && _sensoriamento.Sonar.Iniciado));
bool _mapaIniciado =
!_parametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Mapa) ||
@ -2334,8 +2353,8 @@ namespace AgroBase.Models
Cod |= 0x08; // Bit 3: Módulos desconectados
if (!_camerasSoloConectadas)
Cod |= 0x10; // Bit 4: Câmeras de solo não conectadas
if (!_kinectConectado)
Cod |= 0x20; // Bit 5: Kinect não conectado
if (!_sonarConectado)
Cod |= 0x20; // Bit 5: Sonar não conectado
if (!_mapaIniciado)
Cod |= 0x40; // Bit 6: Mapa não iniciado
if (!_joystickConectado)
@ -2397,8 +2416,8 @@ namespace AgroBase.Models
case T_Code.Cam:
Cod |= 0x2000000; // Bit 25: Falha no Módulo de Câmera
break;
case T_Code.Knt:
Cod |= 0x4000000; // Bit 26: Falha no Módulo Kinect
case T_Code.Snr:
Cod |= 0x4000000; // Bit 26: Falha no Módulo Sonar
break;
case T_Code.A05:
Cod |= 0x8000000; // Bit 27: Falha no Módulo A05
@ -2941,7 +2960,7 @@ namespace AgroBase.Models
public string sen { get; set; }
public string pzm { get; set; }
public string wit { get; set; }
public string knt { get; set; }
public string snr { get; set; }
public string a05 { get; set; }
public string cam_caminho { get; set; }
public List<string> cam_solo { get; set; }
@ -2963,18 +2982,15 @@ namespace AgroBase.Models
return new DateTime().AddSeconds(TempoDecorridoSeg);
}
}
public double AnguloRuaCamera { get; set; } = 0;
public OperacaoSensoriamentoLogAtuModel Atuador { get; set; }
public OperacaoSensoriamentoLogMvdModel Movimentacao { get; set; }
public OperacaoSensoriamentoLogBateriaModel Bateria { get; set; }
public OperacaoSensoriamentoLogTrajetoriaModel Trajetoria { get; set; }
public GPSModel Gps { get; set; }
public WT901CModel WitMotion { get; set; }
public KinectModel SonarFrontal_Kinect { get; set; } = null;
public PerformanceModel DadosPerformance { get; set; } = new PerformanceModel();
public OperacaoControleModel Controle { get; set; }
public SonarCamModel Sonar { get; set; }
public void AtualizarDados()
{
@ -3066,7 +3082,12 @@ namespace AgroBase.Models
var dadosWitMotion = WT901CService.DadosLeitura.Clone();
var dadosKinect = KinectService.Leitura.Clone();
var dadosSonar = Variaveis.OperacaoEmAndamento.CameraCaminho?.Sonar?.Clone();
if (dadosSonar == null)
{
dadosSonar = new SonarCamModel();
dadosSonar.DetectarObstaculos(null);
}
var dadosControle = _Controle.Clone();
@ -3081,16 +3102,13 @@ namespace AgroBase.Models
DataInicio = Variaveis.OperacaoEmAndamento.DataInicio,
DataFim = Variaveis.OperacaoEmAndamento.DataFim,
TempoDecorridoSeg = Variaveis.OperacaoEmAndamento.TempoDecorridoSegs,
AnguloRuaCamera = Variaveis.OperacaoEmAndamento.CameraCaminho?.Angulo ?? 0,
Atuador = dadosAtuador,
Movimentacao = dadosMovimentacao,
Bateria = dadosBateria,
Trajetoria = dadosTrajetoria,
Gps = dadosGps,
WitMotion = dadosWitMotion,
SonarFrontal_Kinect = dadosKinect,
Sonar = dadosSonar,
Controle = dadosControle,
DadosPerformance = dadosPerformance
};
@ -3098,7 +3116,7 @@ namespace AgroBase.Models
Variaveis.OperacaoEmAndamento.Sensoriamento = dadosAtualizados;
}
public OperacaoSensoriamentoLogModel Clone()
public OperacaoSensoriamentoLogModel Clone(bool comSonar = false)
{
return new OperacaoSensoriamentoLogModel()
{
@ -3109,14 +3127,13 @@ namespace AgroBase.Models
DataInicio = DataInicio,
DataFim = DataFim,
TempoDecorridoSeg = TempoDecorridoSeg,
AnguloRuaCamera = AnguloRuaCamera,
Atuador = Atuador.Clone(),
Movimentacao = Movimentacao.Clone(),
Bateria = Bateria.Clone(),
Trajetoria = Trajetoria.Clone(),
Gps = Gps.Clone(),
WitMotion = WitMotion.Clone(),
SonarFrontal_Kinect = SonarFrontal_Kinect.Clone(),
Sonar = comSonar ? Sonar.Clone() : null,
Controle = Controle.Clone(),
DadosPerformance = DadosPerformance.Clone(),
};

View File

@ -0,0 +1,511 @@
using AgroBase.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using static AgroBase.Models.Enums;
namespace AgroBase.Models
{
public class SonarCamModel
{
public double minDepth = 25;
private double maxDepth = 10000;
private float focalLength = 440.0f;
private float sensorWidthMM = 5.76f;
public int depthFrameWidth = 640;
private static int toleranciaDeteccaoSuperior = 200;
private static int toleranciaDeteccaoTrajetoria = 100;
private float distProjetarTrajetoriaMm = 2000f;
public static double MargemSegurancaDesvio = 5;
public static int AnguloDesvioMaximo = 60;
public SonarService service;
public SonarCamModel()
{
service = new SonarService(minDepth, focalLength, sensorWidthMM, depthFrameWidth, toleranciaDeteccaoSuperior, toleranciaDeteccaoTrajetoria);
}
public DateTime Momento { get; set; }
public bool Iniciado { get; set; }
private void AtualizarIniciado()
{
Iniciado = Variaveis.OperacaoEmAndamento.CameraCaminho?.Iniciada ?? false;
}
public int X_Max { get; set; }
public int Y_Max { get; set; }
private void AtualizarLarguraAltura(int x_max, int y_max)
{
X_Max = x_max;
Y_Max = y_max;
}
public List<Subdivisao> Subdivisoes { get; set; } = new List<Subdivisao>();
public List<Obstaculo> Obstaculos { get; set; } = new List<Obstaculo>();
public Obstaculo ObstaculoCritico { get; set; }
private void AtualizarObstaculoCritico()
{
// Ordenar os obstáculos por criticidade
var obstaculoCritico = Obstaculos
.OrderByDescending(o => o.DesvioNecessario) // Primeiro, priorizar os que precisam de desvio
.ThenBy(o => o.DistanciaMedia_mm) // Priorizar os mais próximos
.ThenByDescending(o => o.Largura_mm) // Depois, os mais largos
.ThenByDescending(o => o.Altura_mm) // Em seguida, os mais altos
.ThenByDescending(o => Math.Abs(o.AnguloParaDesvio)) // Finalmente, os que requerem maior ângulo de desvio
.FirstOrDefault();
ObstaculoCritico = obstaculoCritico;
}
public bool DesvioNecessario { get; set; }
private void AtualizarDesvioNecessario()
{
DesvioNecessario = Obstaculos.Any(x => x.DesvioNecessario);
}
public double AnguloDesvio { get; set; }
public Direcao DirecaoDesvio { get; set; }
private void AtualizarAnguloDirecaoDesvio()
{
var ObstaculosDetectados = Obstaculos.Where(x => x.DesvioNecessario).ToList();
if (!ObstaculosDetectados.Any())
{
AnguloDesvio = 0;
DirecaoDesvio = Direcao.Frente;
}
if (ObstaculosDetectados.Any(x => x.DirecaoDesvio == Direcao.Parado))
{
AnguloDesvio = 0;
DirecaoDesvio = Direcao.Parado;
}
if (ObstaculosDetectados.Count() == 1)
{
AnguloDesvio = ObstaculoCritico.AnguloParaDesvio;
DirecaoDesvio = ObstaculoCritico.DirecaoDesvio;
}
var obstaculosLista = ObstaculosDetectados.Select(o => o.Clone()).ToList();
float LimiteRiscoAceitavel = 0.1f;
//var Simulacoes = RealizarSimulacao(obstaculosLista, LimiteRiscoAceitavel);
var Simulacoes = service.RealizarSimulacaoGranular(obstaculosLista, 10, LimiteRiscoAceitavel);
if (Simulacoes.Any(x => x.DirecaoDesvio == Direcao.Parado || x.RiscoTotal > LimiteRiscoAceitavel))
{
AnguloDesvio = 0;
DirecaoDesvio = Direcao.Parado;
}
// Se a primeira simulação for segura
var SimulacaoSegura = Simulacoes.First();
AnguloDesvio = SimulacaoSegura.AnguloDesvio;
DirecaoDesvio = SimulacaoSegura.DirecaoDesvio;
}
public float EspacoLivreEsquerda { get; set; }
private void AtualizarEspacoLivreEsquerda()
{
float dE = (depthFrameWidth / 2.0f);
float rE = SonarService.CalculatePixelToMMRatio(distProjetarTrajetoriaMm);
float espacoLivreE = dE * rE;
var obstaculosE = Obstaculos.Where(o => o.DirecaoDesvio == Direcao.Direita).ToList();
EspacoLivreEsquerda = obstaculosE.Any() ? obstaculosE.Min(x => x.DistanciaLivreEsquerda) : espacoLivreE;
}
public float EspacoLivreDireita { get; set; }
private void AtualizarEspacoLivreDireita()
{
float dD = (depthFrameWidth / 2.0f);
float rD = SonarService.CalculatePixelToMMRatio(distProjetarTrajetoriaMm);
float espacoLivreD = dD * rD;
var obstaculosD = Obstaculos.Where(o => o.DirecaoDesvio == Direcao.Esquerda).ToList();
EspacoLivreDireita = obstaculosD.Any() ? obstaculosD.Min(x => x.DistanciaLivreDireita) : espacoLivreD;
}
public double AnguloRuaCamera { get; set; } = 0;
private void AtualizarDadosObstaculos(int x_max, int y_max)
{
AtualizarIniciado();
AtualizarLarguraAltura(x_max, y_max);
if (Obstaculos == null || !Obstaculos.Any())
{
ObstaculoCritico = null;
DesvioNecessario = false;
DirecaoDesvio = Direcao.Frente;
AnguloDesvio = 0;
EspacoLivreDireita = 0;
EspacoLivreEsquerda = 0;
return;
}
AtualizarObstaculoCritico();
AtualizarDesvioNecessario();
AtualizarAnguloDirecaoDesvio();
AtualizarEspacoLivreEsquerda();
AtualizarEspacoLivreDireita();
}
public SonarCamModel Clone()
{
return new SonarCamModel()
{
Momento = Momento,
Iniciado = Iniciado,
X_Max = X_Max,
Y_Max = Y_Max,
AnguloDesvio = AnguloDesvio,
depthFrameWidth = depthFrameWidth,
distProjetarTrajetoriaMm = distProjetarTrajetoriaMm,
focalLength = focalLength,
maxDepth = maxDepth,
minDepth = minDepth,
Obstaculos = new List<Obstaculo>(Obstaculos),
sensorWidthMM = sensorWidthMM,
Subdivisoes = new List<Subdivisao>(Subdivisoes),
DesvioNecessario = DesvioNecessario,
DirecaoDesvio = DirecaoDesvio,
ObstaculoCritico = ObstaculoCritico?.Clone(),
EspacoLivreDireita = EspacoLivreDireita,
EspacoLivreEsquerda = EspacoLivreEsquerda,
AnguloRuaCamera = AnguloRuaCamera,
};
}
public void DetectarObstaculos(OAKDLiteSubdivisoesModel modelo)
{
Subdivisoes = service.ConverterSubdivisoes(modelo);
Obstaculos = service.IdentificarObstaculos(Subdivisoes, Variaveis.OperacaoEmAndamento.Controle.SonarAtivado);
AtualizarDadosObstaculos(modelo?.x_max ?? 640, modelo?.y_max ?? 480);
}
}
public class Obstaculo
{
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public float DistanciaMedia_mm { get; set; }
public float Largura_mm { get; set; }
public float Altura_mm { get; set; }
public bool ObstaculoTrajetoria { get; set; }
public bool ObstaculoSuperior { get; set; }
public int Tolerancia { get; set; }
public TipoObstaculo Tipo { get; set; }
public bool DesvioNecessario { get; set; }
private void AtualizarDesvioNecessario()
{
bool larguraMinima = Largura_mm >= Tolerancia;
bool alutraMinima = Altura_mm >= Tolerancia; // (VariaveisEquipamento.DiametroRoda * 1000 / 2); // No minimo precisa ser mais alto que a metade da roda
DesvioNecessario = larguraMinima && alutraMinima;
}
public float PercentualEsquerda { get; set; }
public float PercentualDireita { get; set; }
public Direcao DirecaoDesvio { get; set; }
private void AtualizarDirecaoDesvio(int depthFrameWidth, double minDepth)
{
Direcao direcaoDesvio = Direcao.Frente;
if (DesvioNecessario)
{
// Calcular as posições extremas do obstáculo
float posicaoInicioX = X;
float posicaoFimX = X + Width;
float centro = depthFrameWidth / 2;
// Calcular quanto do obstáculo está à esquerda e à direita do centro
float percentualEsquerda = 0;
float percentualDireita = 0;
if (posicaoFimX <= centro)
{
// Obstáculo todo à esquerda
percentualEsquerda = 1;
}
else if (posicaoInicioX >= centro)
{
// Obstáculo todo à direita
percentualDireita = 1;
}
else
{
// Parte do obstáculo está à esquerda e parte à direita
float larguraEsquerda = centro - posicaoInicioX;
float larguraDireita = posicaoFimX - centro;
percentualEsquerda = (larguraEsquerda / Width);
percentualDireita = (larguraDireita / Width);
}
// Definir a direção do desvio com base nos percentuais
if (DistanciaMedia_mm < (minDepth * 1.1) && (DistanciaDaLateralDireita < VariaveisEquipamento.LarguraDireita || DistanciaLivreEsquerda < VariaveisEquipamento.LarguraEsquerda))
{
direcaoDesvio = Direcao.Parado;
}
else if (percentualDireita > percentualEsquerda)
{
direcaoDesvio = Direcao.Esquerda; // Desviar para a esquerda
}
else
{
direcaoDesvio = Direcao.Direita; // Desviar para a direita
}
// Armazenar os percentuais como novas variáveis
PercentualEsquerda = percentualEsquerda;
PercentualDireita = percentualDireita;
}
DirecaoDesvio = direcaoDesvio;
}
public float DistanciaLivreEsquerda { get; set; }
private void AtualizarDistanciaLivreEsquerda()
{
float ratio = SonarService.CalculatePixelToMMRatio(DistanciaMedia_mm);
DistanciaLivreEsquerda = (float)(X * ratio);
}
public float DistanciaLivreDireita { get; set; }
private void AtualizarDistanciaLivreDireita(int depthFrameWidth)
{
float ratio = SonarService.CalculatePixelToMMRatio(DistanciaMedia_mm);
int tamanho = depthFrameWidth - (X + Width);
DistanciaLivreDireita = (float)((tamanho) * ratio);
}
public double DistanciaDaLateralDireita { get; set; }
private void AtualizarDistanciaLateralDireita(int depthFrameWidth)
{
// Coordenadas do ponto central do robô (origem)
int centroX = depthFrameWidth / 2;
double profundidadeZ = DistanciaMedia_mm;
float ratio = SonarService.CalculatePixelToMMRatio((float)profundidadeZ);
DistanciaDaLateralDireita = (((X + Width) - centroX) * ratio) / 10;
}
public double DistanciaDaLateralEsquerda { get; set; }
private void AtualizarDistanciaLateralEsquerda(int depthFrameWidth)
{
// Coordenadas do ponto central do robô (origem)
int centroX = depthFrameWidth / 2;
double profundidadeZ = DistanciaMedia_mm;
float ratio = SonarService.CalculatePixelToMMRatio((float)profundidadeZ);
DistanciaDaLateralEsquerda = ((centroX - X) * ratio) / 10;
}
public bool Adireita { get; set; }
private void AtualizarADireita(int depthFrameWidth)
{
int origemX = depthFrameWidth / 2;
Adireita = X + Width > origemX;
}
public bool Aesquerda { get; set; }
private void AtualizarAEsquerda(int depthFrameWidth)
{
int origemX = depthFrameWidth / 2;
Aesquerda = X < origemX;
}
public double DeslocamentoNecessarioDesvio { get; set; }
private void AtualizarDeslocamentoNecessarioDesvio()
{
if (DirecaoDesvio == Direcao.Direita)
{
DeslocamentoNecessarioDesvio = DeslocamentoNecessarioDireita;
}
else if (DirecaoDesvio == Direcao.Esquerda)
{
DeslocamentoNecessarioDesvio = DeslocamentoNecessarioEsquerda;
}
else
{
DeslocamentoNecessarioDesvio = 0;
}
}
public double DeslocamentoNecessarioEsquerda { get; set; }
private void AtualizarDeslocamentoNecessarioEsquerda()
{
if (PercentualDireita > 0 || PercentualEsquerda > 0)
{
double deslocamento = ((((VariaveisEquipamento.LarguraEsquerda + VariaveisEquipamento.LarguraDireita) / 2.0) + DistanciaDaLateralEsquerda) * (1 + PercentualEsquerda)) + SonarCamModel.MargemSegurancaDesvio;
if (deslocamento < 0)
{
deslocamento = 0;
}
DeslocamentoNecessarioEsquerda = deslocamento;
}
else
{
DeslocamentoNecessarioEsquerda = 0;
}
}
public double DeslocamentoNecessarioDireita { get; set; }
private void AtualizarDeslocamentoNecessarioDireita()
{
if (PercentualDireita > 0 || PercentualEsquerda > 0)
{
double deslocamento = ((((VariaveisEquipamento.LarguraEsquerda + VariaveisEquipamento.LarguraDireita) / 2.0) + DistanciaDaLateralDireita) * (1 + PercentualDireita)) + SonarCamModel.MargemSegurancaDesvio;
if (deslocamento < 0)
{
deslocamento = 0;
}
DeslocamentoNecessarioDireita = deslocamento;
}
else
{
DeslocamentoNecessarioDireita = 0;
}
}
public double AnguloParaDesvio { get; set; }
private void AtualizarAnguloParaDesvio()
{
double anguloDesvio = 0;
Direcao direcaoDesvio = DirecaoDesvio;
if (direcaoDesvio == Direcao.Esquerda)
{
anguloDesvio = AnguloParaDesvioEsquerda;
}
else if (direcaoDesvio == Direcao.Direita)
{
anguloDesvio = AnguloParaDesvioDireita;
}
AnguloParaDesvio = anguloDesvio;
}
public double AnguloParaDesvioEsquerda { get; set; }
private void AtualizarAnguloParaDesvioEsquerda()
{
// Usando trigonometria para calcular o ângulo necessário
// Nota: Assegure-se de converter o resultado de arco seno para graus, se necessário
double anguloRad = Math.Atan((DistanciaMedia_mm / 10) / DeslocamentoNecessarioEsquerda);
double anguloDesvio = (anguloRad * (180 / Math.PI)); // Convertendo radianos para graus
anguloDesvio = anguloDesvio - 90;
// Atribuição do ângulo calculado ao ângulo de desvio, com verificação de limites
AnguloParaDesvioEsquerda = Math.Min(anguloDesvio, SonarCamModel.AnguloDesvioMaximo);
}
public double AnguloParaDesvioDireita { get; set; }
private void AtualizarAnguloParaDesvioDireita()
{
// Usando trigonometria para calcular o ângulo necessário
// Nota: Assegure-se de converter o resultado de arco seno para graus, se necessário
double anguloRad = Math.Atan((DistanciaMedia_mm / 10) / DeslocamentoNecessarioDireita);
double anguloDesvio = (anguloRad * (180 / Math.PI)); // Convertendo radianos para graus
anguloDesvio = 90 - anguloDesvio;
// Atribuição do ângulo calculado ao ângulo de desvio, com verificação de limites
AnguloParaDesvioDireita = Math.Min(anguloDesvio, SonarCamModel.AnguloDesvioMaximo);
}
public void AtualizarDados(int depthFrameWidth, double minDepth)
{
AtualizarDesvioNecessario();
AtualizarDirecaoDesvio(depthFrameWidth, minDepth);
AtualizarDistanciaLivreEsquerda();
AtualizarDistanciaLivreDireita(depthFrameWidth);
AtualizarDistanciaLateralDireita(depthFrameWidth);
AtualizarDistanciaLateralEsquerda(depthFrameWidth);
AtualizarADireita(depthFrameWidth);
AtualizarAEsquerda(depthFrameWidth);
AtualizarDeslocamentoNecessarioEsquerda();
AtualizarDeslocamentoNecessarioDireita();
AtualizarDeslocamentoNecessarioDesvio();
AtualizarAnguloParaDesvioEsquerda();
AtualizarAnguloParaDesvioDireita();
AtualizarAnguloParaDesvio();
}
public Obstaculo Clone()
{
return new Obstaculo()
{
Tolerancia = Tolerancia,
Altura_mm = Altura_mm,
DistanciaMedia_mm = DistanciaMedia_mm,
Height = Height,
Largura_mm = Largura_mm,
ObstaculoSuperior = ObstaculoSuperior,
ObstaculoTrajetoria = ObstaculoTrajetoria,
PercentualDireita = PercentualDireita,
PercentualEsquerda = PercentualEsquerda,
Tipo = Tipo,
Width = Width,
X = X,
Y = Y,
AnguloParaDesvioDireita = AnguloParaDesvioDireita,
AnguloParaDesvioEsquerda = AnguloParaDesvioEsquerda,
AnguloParaDesvio = AnguloParaDesvio,
DeslocamentoNecessarioEsquerda = DeslocamentoNecessarioEsquerda,
DeslocamentoNecessarioDesvio = DeslocamentoNecessarioDesvio,
Aesquerda = Aesquerda,
Adireita = Adireita,
DeslocamentoNecessarioDireita = DeslocamentoNecessarioDireita,
DesvioNecessario = DesvioNecessario,
DirecaoDesvio = DirecaoDesvio,
DistanciaDaLateralDireita = DistanciaDaLateralDireita,
DistanciaDaLateralEsquerda = DistanciaDaLateralEsquerda,
DistanciaLivreDireita = DistanciaLivreDireita,
DistanciaLivreEsquerda = DistanciaLivreEsquerda
};
}
}
public class Subdivisao
{
public int idxX { get; set; }
public int idxY { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int Largura { get; set; }
public int Altura { get; set; }
public int ProfundidadeMedia { get; set; }
public int ProfundidadeEsperada { get; set; }
public int Tolerancia { get; set; }
public bool IsZonaSuperior { get; set; }
public int DiferencaProfundidade
{
get
{
return ProfundidadeMedia - ProfundidadeEsperada;
}
}
public bool ObstaculoDetectado
{
get
{
if (IsZonaSuperior)
{
return ProfundidadeMedia > 0 && (ProfundidadeMedia + Tolerancia) < ProfundidadeEsperada;
}
else
{
return Math.Abs(DiferencaProfundidade) > Tolerancia;
}
}
}
public TipoObstaculo Tipo
{
get
{
if (IsZonaSuperior)
{
return ObstaculoDetectado ? TipoObstaculo.Ressalto : TipoObstaculo.Rebaixo;
}
else
{
return ObstaculoDetectado && DiferencaProfundidade > 0 ? TipoObstaculo.Rebaixo : TipoObstaculo.Ressalto;
}
}
}
}
}

View File

@ -522,7 +522,7 @@ namespace AgroBase.Models
{
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
double anguloCamera = _Sensoriamento.AnguloRuaCamera;
double anguloCamera = _Sensoriamento.Sonar.AnguloRuaCamera;
double anguloCorredor = AnguloMedioCorredor;
double anguloProximoPonto = AnguloCaminho;
double anguloCarro = _Sensoriamento.Gps.AnguloCarroDefinido;

View File

@ -256,7 +256,7 @@ namespace AgroBase.Services
Leitura.VelZ = velocidade[2];
}
Variaveis.OperacaoEmAndamento.Sensoriamento.SonarFrontal_Kinect = Leitura;
//Variaveis.OperacaoEmAndamento.Sensoriamento.SonarFrontal_Kinect = Leitura;
}
private static KinectParametrosModel CarregarParametros()

View File

@ -0,0 +1,477 @@
using AgroBase.Models;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using static AgroBase.Models.Enums;
namespace AgroBase.Services
{
public class SonarService
{
private double minDepth;
private int toleranciaDeteccaoSuperior;
private int toleranciaDeteccaoTrajetoria;
private static float sfocalLength;
private static float sensorWidthMM;
private static int depthFrameWidth;
public SonarService(double _minDepth, float _focalLeght, float _sensorWidthMM, int _depthFrameWidth, int _toleranciaCima, int _toleranciaBaixo)
{
minDepth = _minDepth;
toleranciaDeteccaoSuperior = _toleranciaCima;
toleranciaDeteccaoTrajetoria = _toleranciaBaixo;
sfocalLength = _focalLeght;
sensorWidthMM = _sensorWidthMM;
depthFrameWidth = _depthFrameWidth;
}
public List<SimulacaoDesvio> RealizarSimulacaoGranular(List<Obstaculo> obstaculosSimulados, float passoSimulacaoCm, float LimiteRiscoAceitavel)
{
List<SimulacaoDesvio> simulacoes = new List<SimulacaoDesvio>();
var obstaculosClone = obstaculosSimulados.Select(o => o.Clone()).ToList();
float distanciaPercorrida = 0;
int passo = 0;
while (obstaculosClone.Any())
{
var obstaculoCritico = obstaculosClone.OrderBy(o => o.DistanciaMedia_mm).First();
// Simular um passo
SimulacaoDesvio simulacaoAtual = SimularPasso(obstaculoCritico.DirecaoDesvio, obstaculoCritico.AnguloParaDesvio, obstaculosClone, passoSimulacaoCm, ref passo);
simulacoes.Add(simulacaoAtual);
distanciaPercorrida += passoSimulacaoCm * 10; // Convertendo de cm para mm
// Verificar se o robô ultrapassou o obstáculo crítico
if (distanciaPercorrida >= (obstaculoCritico.DistanciaMedia_mm - minDepth))
{
// Novo obstáculo crítico, ajustar o ângulo de desvio
obstaculosClone = simulacaoAtual.Obstaculos.Where(o => o.DistanciaMedia_mm > distanciaPercorrida).ToList();
if (obstaculosClone.Any())
{
obstaculoCritico = obstaculosClone.OrderBy(o => o.DistanciaMedia_mm).First();
simulacaoAtual = SimularPasso(obstaculoCritico.DirecaoDesvio, obstaculoCritico.AnguloParaDesvio, obstaculosClone, passoSimulacaoCm, ref passo);
simulacoes.Add(simulacaoAtual);
}
else
{
break; // Não há mais obstáculos a considerar
}
}
if (simulacaoAtual.RiscoTotal >= LimiteRiscoAceitavel || !obstaculosClone.Any())
{
break;
}
obstaculosClone = simulacaoAtual.Obstaculos.ToList();
}
return simulacoes;
}
private SimulacaoDesvio SimularPasso(Direcao direcaoDesvio, double anguloDesvio, List<Obstaculo> obstaculosSimulados, float passoSimulacaoCm, ref int passo)
{
passo++;
var obstaculosClone = obstaculosSimulados.Select(o => o.Clone()).ToList();
double novoAnguloDesvio = double.IsNaN(anguloDesvio) ? 0 : anguloDesvio;
// Conversão de ângulo para radianos para cálculos trigonométricos
double anguloEmRadianos = novoAnguloDesvio * (Math.PI / 180.0);
foreach (var obstaculo in obstaculosClone)
{
// Calcular o deslocamento em Y (distância até o robô) considerando o passo da simulação
float deslocamentoYmm = (passoSimulacaoCm * 10); // Convertendo de cm para mm
obstaculo.DistanciaMedia_mm -= deslocamentoYmm;
// Calcular o deslocamento em X (lateral) com base no ângulo de desvio
float deslocamentoXmm = Convert.ToInt32(deslocamentoYmm * Math.Tan(anguloEmRadianos));
// Atualizar as novas dimensões do obstáculo com base na nova distância
float ratioAtual = CalculatePixelToMMRatio(obstaculo.DistanciaMedia_mm);
float fatorCrescimento = CalculatePixelToMMRatio(obstaculo.DistanciaMedia_mm + deslocamentoYmm) / ratioAtual;
var b = ((obstaculo.Largura_mm * fatorCrescimento) - obstaculo.Largura_mm) / 2;
int deslocamentoXpx = (int)(deslocamentoXmm / ratioAtual);
var d = fatorCrescimento * obstaculo.Width;
var e = (int)((d - obstaculo.Width));
var c = ((obstaculo.Altura_mm * fatorCrescimento) - obstaculo.Altura_mm) / 2;
var f = fatorCrescimento * obstaculo.Height;
var g = (int)((f - obstaculo.Height) / 2);
int deslocamentoYpx = (int)(deslocamentoYmm / ratioAtual);
obstaculo.Y += (int)g;
if (direcaoDesvio == Direcao.Esquerda)
{
obstaculo.X += (int)(e / 2);
}
else if (direcaoDesvio == Direcao.Direita)
{
obstaculo.X -= (int)(e * 2);
}
obstaculo.Width = Convert.ToInt32(obstaculo.Width * fatorCrescimento);
obstaculo.Height = Convert.ToInt32(obstaculo.Height * fatorCrescimento);
}
double riscoTotal = CalcularRiscoTotal(obstaculosClone);
return new SimulacaoDesvio
{
DirecaoDesvio = direcaoDesvio,
AnguloDesvio = novoAnguloDesvio, // Mantém o ângulo original até a ultrapassagem do obstáculo crítico
RiscoTotal = riscoTotal,
Obstaculos = obstaculosClone
};
}
private double CalcularRiscoTotal(List<Obstaculo> obstaculos)
{
double riscoTotal = 0;
foreach (var obstaculo in obstaculos)
{
if (obstaculo.DirecaoDesvio != Direcao.Parado)
{
riscoTotal += (1 / obstaculo.DistanciaMedia_mm) * 1; // obstaculo.PercentualCobertura;
}
else
{
riscoTotal += 1;
}
}
return riscoTotal;
}
public static float CalculatePixelToMMRatio(float distance)
{
// Exemplo de cálculo simplificado da relação pixels para milímetros
// A relação exata pode variar e pode precisar de ajustes
// Aqui assumimos uma relação linear simplificada
float pixelToMM = (distance / sfocalLength) * (sensorWidthMM / depthFrameWidth) * 10;
return pixelToMM;
}
public static Bitmap ExibirObstaculos(Bitmap bitmap, SonarCamModel leitura, bool ExibirTexto = false)
{
if (bitmap == null || (!Variaveis.OperacaoEmAndamento.Controle.SonarAtivado && Variaveis.OperacaoEmAndamento.Iniciado))
{
return bitmap;
}
try
{
var _bitmapMap = (Bitmap)bitmap.Clone();
using (Graphics g = Graphics.FromImage(_bitmapMap))
{
// Calcular fatores de escala
double fatorX = (double)_bitmapMap.Width / leitura.X_Max;
double fatorY = (double)_bitmapMap.Height / leitura.Y_Max;
// Desenhar a trajetória do robô com os fatores aplicados
DesenharTrajetoriaRobo(g, leitura.Subdivisoes, fatorX, fatorY);
foreach (var obstaculo in leitura.Obstaculos)
{
Pen Cor = (obstaculo.Tipo == TipoObstaculo.Ressalto ? Pens.Red : obstaculo.Tipo == TipoObstaculo.Rebaixo ? Pens.Blue : Pens.Black);
Rectangle rect = new Rectangle(obstaculo.X, obstaculo.Y, obstaculo.Width, obstaculo.Height);
g.DrawRectangle(Cor, rect);
if (ExibirTexto)
{
string distanceText = $"D: {obstaculo.DistanciaMedia_mm:F1} mm, L: {obstaculo.Largura_mm:F1} mm, A: {obstaculo.Altura_mm:F1} mm";
Font font = new Font("Arial", 12);
SizeF textSize = g.MeasureString(distanceText, font);
PointF textLocation = new PointF(obstaculo.X + (obstaculo.Width - textSize.Width) / 2, obstaculo.Y + (obstaculo.Height - textSize.Height) / 2);
g.DrawString(distanceText, font, Brushes.Red, textLocation);
}
}
if (leitura.DesvioNecessario && leitura.DirecaoDesvio != Direcao.Parado)
{
// Desenhar a seta
DesenharSeta(g, _bitmapMap.Width, _bitmapMap.Height, 90 - (float)leitura.AnguloDesvio);
}
}
return _bitmapMap;
}
catch (Exception ex)
{
}
return bitmap;
}
private static void DesenharSeta(Graphics g, int largura, int altura, float angulo)
{
// Ponto de início (base da seta)
PointF pontoInicio = new PointF(largura / 2, altura);
// Comprimento da seta (2/3 da altura da tela)
float comprimentoSeta = altura * 1 / 3;
// Cálculo do ponto final da seta com base no ângulo
float anguloRad = (float)(Math.PI * angulo / 180.0);
PointF pontoFinal = new PointF(
pontoInicio.X + comprimentoSeta * (float)Math.Cos(anguloRad),
pontoInicio.Y - comprimentoSeta * (float)Math.Sin(anguloRad)
);
// Desenhar a linha da seta
Pen penSeta = new Pen(Color.Orange, 4);
g.DrawLine(penSeta, pontoInicio, pontoFinal);
// Desenhar as pontas da seta
float tamanhoPonta = 20;
PointF ponta1 = new PointF(
pontoFinal.X + tamanhoPonta * (float)Math.Cos(anguloRad + Math.PI * 3 / 4),
pontoFinal.Y - tamanhoPonta * (float)Math.Sin(anguloRad + Math.PI * 3 / 4)
);
PointF ponta2 = new PointF(
pontoFinal.X + tamanhoPonta * (float)Math.Cos(anguloRad - Math.PI * 3 / 4),
pontoFinal.Y - tamanhoPonta * (float)Math.Sin(anguloRad - Math.PI * 3 / 4)
);
g.DrawLine(penSeta, pontoFinal, ponta1);
g.DrawLine(penSeta, pontoFinal, ponta2);
}
public static void DesenharTrajetoriaRobo(Graphics g, List<Subdivisao> subdivisoes, double fatorX, double fatorY)
{
var subdivisoesTrajetoria = subdivisoes.Where(x => !x.IsZonaSuperior).ToList();
DesenharSubdivisoes(g, subdivisoesTrajetoria, subdivisoesTrajetoria.FirstOrDefault()?.Tolerancia ?? 100, Color.Green, Color.Green, fatorX, fatorY);
var subdivisoesSuperior = subdivisoes.Where(x => x.IsZonaSuperior).ToList();
DesenharSubdivisoes(g, subdivisoesSuperior, subdivisoesSuperior.FirstOrDefault()?.Tolerancia ?? 100, Color.Red, Color.Red, fatorX, fatorY);
}
// Atualizado para aplicar fatorX e fatorY nas posições e tamanhos
private static void DesenharSubdivisoes(Graphics g, List<Subdivisao> subdivisoes, int tolerancia, Color corContorno, Color corPreenchimento, double fatorX, double fatorY)
{
foreach (var subdivisao in subdivisoes)
{
Color cor = subdivisao.ObstaculoDetectado ? Color.FromArgb(128, corPreenchimento) : Color.Transparent;
Brush brush = new SolidBrush(cor);
Pen pen = new Pen(corContorno);
// Aplicando os fatores de escala
int x = (int)(subdivisao.X * fatorX);
int y = (int)(subdivisao.Y * fatorY);
int largura = (int)(subdivisao.Largura * fatorX);
int altura = (int)(subdivisao.Altura * fatorY);
Rectangle rect = new Rectangle(x, y, largura, altura);
g.FillRectangle(brush, rect);
g.DrawRectangle(pen, rect);
}
}
public List<Obstaculo> IdentificarObstaculos(List<Subdivisao> subdivisoes, bool sonarAtivado)
{
if (!sonarAtivado || subdivisoes == null)
{
return new List<Obstaculo>();
}
double tolerancia = 100.0;
List<List<Subdivisao>> AgrupamentoPorProfundidade = new List<List<Subdivisao>>();
foreach (var sub in subdivisoes.Where(x => x.ObstaculoDetectado))
{
bool add = false;
foreach (var grupo in AgrupamentoPorProfundidade)
{
if (grupo.Any(x => Math.Abs(x.ProfundidadeMedia - sub.ProfundidadeMedia) <= tolerancia))
{
grupo.Add(sub);
add = true;
continue;
}
}
if (!add)
{
AgrupamentoPorProfundidade.Add(new List<Subdivisao>() { sub });
}
}
List<List<Subdivisao>> AgrupamentoPorAdjacencia = new List<List<Subdivisao>>();
foreach (var grupo in AgrupamentoPorProfundidade)
{
while (grupo.Any())
{
var subgrupo = new List<Subdivisao> { grupo[0] };
grupo.RemoveAt(0);
bool adicionou = true;
while (adicionou)
{
adicionou = false;
var adjacentes = grupo.Where(s =>
subgrupo.Any(x =>
Math.Abs(x.X - s.X) <= Math.Max(x.Largura, s.Largura) &&
(x.IsZonaSuperior != s.IsZonaSuperior ?
VerificarContinuidade(x, s) :
Math.Abs(x.Y - s.Y) <= (Math.Max(x.Altura, s.Altura) + 1)))).ToList();
if (adjacentes.Any())
{
subgrupo.AddRange(adjacentes);
foreach (var adj in adjacentes)
{
grupo.Remove(adj);
}
adicionou = true;
}
}
AgrupamentoPorAdjacencia.Add(subgrupo);
}
}
List<Obstaculo> obstaculos = new List<Obstaculo>();
foreach (var grupoSubdivisoes in AgrupamentoPorAdjacencia)
{
var obstaculo = CriarObstaculo(grupoSubdivisoes);
if (obstaculo.DistanciaMedia_mm > 0 && obstaculo.DesvioNecessario)
{
obstaculo.AtualizarDados(depthFrameWidth, minDepth);
obstaculos.Add(obstaculo);
}
}
return obstaculos;
}
// Método auxiliar para verificar continuidade entre zonas superior e inferior
private bool VerificarContinuidade(Subdivisao sub1, Subdivisao sub2)
{
// Se as subdivisões estão na mesma zona, são adjacentes se tocarem fisicamente
if (sub1.IsZonaSuperior == sub2.IsZonaSuperior)
{
return true;
}
// Se uma subdivisão está na zona superior e a outra na inferior, verifique se estão alinhadas verticalmente
// Isso considera a adjacência na transição entre as zonas
if (sub1.IsZonaSuperior && !sub2.IsZonaSuperior)
{
return sub1.idxY == sub2.idxY - 1;
}
if (!sub1.IsZonaSuperior && sub2.IsZonaSuperior)
{
return sub1.idxY - 1 == sub2.idxY;
}
return false;
}
private Obstaculo CriarObstaculo(List<Subdivisao> grupoObstaculo)
{
int minX = grupoObstaculo.Min(s => s.X);
int minY = grupoObstaculo.Min(s => s.Y);
int maxX = grupoObstaculo.Max(s => s.X + s.Largura);
int maxY = grupoObstaculo.Max(s => s.Y + s.Altura);
int larguraPixels = maxX - minX;
int alturaPixels = maxY - minY;
// Calcular a distância média do obstáculo
float distanciaMedia = (float)grupoObstaculo.Average(s => s.ProfundidadeMedia);
// Calcular a relação pixels para milímetros
float pixelToMM = CalculatePixelToMMRatio(distanciaMedia);
// Converter dimensões de pixels para milímetros
float larguraMM = larguraPixels * pixelToMM;
float alturaMM = alturaPixels * pixelToMM;
Obstaculo obstaculo = new Obstaculo
{
X = minX,
Y = minY,
Width = larguraPixels,
Height = alturaPixels,
DistanciaMedia_mm = distanciaMedia,
Largura_mm = larguraMM,
Altura_mm = alturaMM,
ObstaculoSuperior = grupoObstaculo.Any(x => x.IsZonaSuperior),
Tolerancia = grupoObstaculo.Any(x => x.IsZonaSuperior) ? toleranciaDeteccaoSuperior : toleranciaDeteccaoTrajetoria,
ObstaculoTrajetoria = grupoObstaculo.Any(x => !x.IsZonaSuperior),
Tipo = grupoObstaculo.Count(x => x.Tipo == TipoObstaculo.Ressalto) > grupoObstaculo.Count(x => x.Tipo == TipoObstaculo.Rebaixo) ? TipoObstaculo.Ressalto : TipoObstaculo.Rebaixo,
};
return obstaculo;
}
public List<Subdivisao> ConverterSubdivisoes(OAKDLiteSubdivisoesModel modelo)
{
var lista = new List<Subdivisao>();
if (modelo == null)
{
return lista;
}
if (modelo?.subdivisoes_cima?.celulas != null)
{
foreach (var celula in modelo.subdivisoes_cima.celulas)
{
lista.Add(new Subdivisao
{
idxX = celula.coluna,
idxY = celula.linha,
X = celula.x,
Y = celula.y,
Largura = celula.largura,
Altura = celula.altura,
ProfundidadeMedia = (int)Math.Round(celula.profundidade_media),
ProfundidadeEsperada = (int)Math.Round(celula.profundidade_calibragem),
Tolerancia = toleranciaDeteccaoSuperior,
IsZonaSuperior = true
});
}
}
if (modelo?.subdivisoes_chao?.celulas != null)
{
foreach (var celula in modelo.subdivisoes_chao.celulas)
{
lista.Add(new Subdivisao
{
idxX = celula.coluna,
idxY = celula.linha,
X = celula.x,
Y = celula.y,
Largura = celula.largura,
Altura = celula.altura,
ProfundidadeMedia = (int)Math.Round(celula.profundidade_media),
ProfundidadeEsperada = (int)Math.Round(celula.profundidade_calibragem),
Tolerancia = toleranciaDeteccaoTrajetoria,
IsZonaSuperior = false
});
}
}
return lista;
}
}
}

View File

@ -1 +1 @@
{"tmrRegistrador":{"_uiControl":null,"State":2,"IsRunning":false,"IsStopped":true,"IsCreated":false,"Interval":500,"StackTrace":"AtuadorModel.IniciarRegistrador","Id":"tmrRegistrador_Atu","TimeTick":"00:00:00"},"Modulo_ID":"Atu","IP":"192.168.100.13","RequisitarDados":true,"Conectado":false,"QuantidadeBicos":4,"DensidadeHerbicida":1.05,"BicosPulverizadores":[{"ID":"B01","Posicao":1,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B02","Posicao":2,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B03","Posicao":3,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B04","Posicao":4,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.02674584437758935,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0}],"BombasPressurizadoras":[{"ID":"BOMBA","ComandoAtuar":false,"Componente":325,"LeituraEstado":false,"Comandar":true,"Testando":false,"Funcoes":[14,35,36,37,5],"LeituraPotencia":0.0,"LeituraPressaoSP":0.0,"LeituraPressao":0.0,"Leitura":null,"Inicializado":false}],"Sensores":[{"LogGrafico":[],"ID":"FLXLN","Prioridade":23,"Descricao":"Fluxo na linha principal","Componente":198,"Aferir":true,"DelayAmostragem":300,"Leitura":null,"Inicializado":false,"Testando":false,"Funcoes":[25],"Parametros":[],"UnidadeMedida":"mL/s","LimiteMaximo":0.0,"LimiteMinimo":0.0},{"LogGrafico":[],"ID":"MASRS","Prioridade":3,"Descricao":"Massa do reservatório de herbicida","Componente":532,"Aferir":true,"DelayAmostragem":1000,"Leitura":null,"Inicializado":false,"Testando":false,"Funcoes":[22,23],"Parametros":[],"UnidadeMedida":"Kg","LimiteMaximo":50.0,"LimiteMinimo":5.0},{"LogGrafico":[],"ID":"PRSLN","Prioridade":3,"Descricao":"Pressão na linha principal","Componente":333,"Aferir":true,"DelayAmostragem":1000,"Leitura":null,"Inicializado":false,"Testando":false,"Funcoes":[24],"Parametros":[["Vmin","000.00"],["Vmax","004.50"],["Pmax","174.04"]],"UnidadeMedida":"psi","LimiteMaximo":120.0,"LimiteMinimo":60.0}],"BombaPressurizadora":{"ID":"BOMBA","ComandoAtuar":false,"Componente":325,"LeituraEstado":false,"Comandar":true,"Testando":false,"Funcoes":[14,35,36,37,5],"LeituraPotencia":0.0,"LeituraPressaoSP":0.0,"LeituraPressao":0.0,"Leitura":null,"Inicializado":false},"ScriptDeteccaoErvas":"weed_detector_oak-1_0.py","DadosLeitura":{"Momento":"0001-01-01T00:00:00","Conectado":false,"Mod_ID":null,"QualidadeWifi":0,"LatenciaLoop":0,"BicosPulverizadores":[],"BombasPressurizadoras":[],"SensoresFluxo":[],"SensoresMassa":[],"SensoresPressao":[]},"_MassaRef":0.8,"_MassaLeituraRef":40876.37,"_MassaLeituraExtra":1895800.0,"MassaReservatorio":0.0,"VolumeReservatorio":0.0,"PercentualReservatorio":0.0,"VolumeVazaoAferido":0.0,"_FluxoMlRef":102.0,"_FluxoPulsoRef":80.0,"VazaoFluxoMLpSInstantanea":0.0,"VazaoFluxoMLpSMedia":0.0,"VolumeVazaoML":0.0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0,"_PressaoVmin":0.0,"_PressaoVmax":4.5,"_PressaoMax":174.045,"PressaoLinha":0.0,"PressaoLinhaCalc":0.0,"PercentualErvasTerreno":0.0}
{"tmrRegistrador":{"_uiControl":null,"State":2,"IsRunning":false,"IsStopped":true,"IsCreated":false,"Interval":500,"StackTrace":"AtuadorModel.IniciarRegistrador","Id":"tmrRegistrador_Atu","TimeTick":"00:00:00.0003149"},"Modulo_ID":"Atu","IP":"192.168.100.13","RequisitarDados":true,"Conectado":false,"QuantidadeBicos":4,"DensidadeHerbicida":1.05,"BicosPulverizadores":[{"ID":"B01","Posicao":1,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B02","Posicao":2,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B03","Posicao":3,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.0,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0},{"ID":"B04","Posicao":4,"Componente":422,"AtuacaoNivelAlto":true,"ComandoAtuar":false,"Comandar":true,"Testando":false,"Funcoes":[21],"LeituraStatusBico":false,"MediaNivelFluxo":0.02674584437758935,"Leitura":null,"Inicializado":false,"Atuacoes":0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0}],"BombasPressurizadoras":[{"ID":"BOMBA","ComandoAtuar":false,"Componente":325,"LeituraEstado":false,"Comandar":true,"Testando":false,"Funcoes":[14,35,36,37,5],"LeituraPotencia":0.0,"LeituraPressaoSP":0.0,"LeituraPressao":0.0,"Leitura":null,"Inicializado":false}],"Sensores":[{"LogGrafico":[],"ID":"FLXLN","Prioridade":23,"Descricao":"Fluxo na linha principal","Componente":198,"Aferir":true,"DelayAmostragem":300,"Leitura":null,"Inicializado":false,"Testando":false,"Funcoes":[25],"Parametros":[],"UnidadeMedida":"mL/s","LimiteMaximo":0.0,"LimiteMinimo":0.0},{"LogGrafico":[],"ID":"MASRS","Prioridade":3,"Descricao":"Massa do reservatório de herbicida","Componente":532,"Aferir":true,"DelayAmostragem":1000,"Leitura":null,"Inicializado":false,"Testando":false,"Funcoes":[22,23],"Parametros":[],"UnidadeMedida":"Kg","LimiteMaximo":50.0,"LimiteMinimo":5.0},{"LogGrafico":[],"ID":"PRSLN","Prioridade":3,"Descricao":"Pressão na linha principal","Componente":333,"Aferir":true,"DelayAmostragem":1000,"Leitura":null,"Inicializado":false,"Testando":false,"Funcoes":[24],"Parametros":[["Vmin","000.00"],["Vmax","004.50"],["Pmax","174.04"]],"UnidadeMedida":"psi","LimiteMaximo":120.0,"LimiteMinimo":60.0}],"BombaPressurizadora":{"ID":"BOMBA","ComandoAtuar":false,"Componente":325,"LeituraEstado":false,"Comandar":true,"Testando":false,"Funcoes":[14,35,36,37,5],"LeituraPotencia":0.0,"LeituraPressaoSP":0.0,"LeituraPressao":0.0,"Leitura":null,"Inicializado":false},"ScriptDeteccaoErvas":"weed_detector_oak-1_0.py","DadosLeitura":{"Momento":"0001-01-01T00:00:00","Conectado":false,"Mod_ID":null,"QualidadeWifi":0,"LatenciaLoop":0,"BicosPulverizadores":[],"BombasPressurizadoras":[],"SensoresFluxo":[],"SensoresMassa":[],"SensoresPressao":[]},"_MassaRef":0.8,"_MassaLeituraRef":40876.37,"_MassaLeituraExtra":1895800.0,"MassaReservatorio":0.0,"VolumeReservatorio":0.0,"PercentualReservatorio":0.0,"VolumeVazaoAferido":0.0,"_FluxoMlRef":102.0,"_FluxoPulsoRef":80.0,"VazaoFluxoMLpSInstantanea":0.0,"VazaoFluxoMLpSMedia":0.0,"VolumeVazaoML":0.0,"InicioAtuacao":"0001-01-01T00:00:00","TempoAtuado":0.0,"_PressaoVmin":0.0,"_PressaoVmax":4.5,"_PressaoMax":174.045,"PressaoLinha":0.0,"PressaoLinhaCalc":0.0,"PercentualErvasTerreno":0.0}

View File

@ -1 +1 @@
{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"Id":"1","Name":"02_04_2025_17_20_50","Length":0.0,"Dist1":0.0,"Dist2":0.0},"geometry":{"id":null,"type":"LineString","coordinates":[[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0]]}}]}
{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"Id":"1","Name":"03_04_2025_10_58_00","Length":0.0,"Dist1":0.0,"Dist2":0.0},"geometry":{"id":null,"type":"LineString","coordinates":[[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0],[0.0,0.0]]}}]}

View File

@ -25,7 +25,7 @@
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<style>
#map_084fd12da6e91f44659dd95dda10e013 {
#map_67cd6a07e1e73bd8b24c674130299a2e {
position: relative;
width: 100.0%;
height: 100.0%;
@ -39,14 +39,14 @@
<body>
<div class="folium-map" id="map_084fd12da6e91f44659dd95dda10e013" ></div>
<div class="folium-map" id="map_67cd6a07e1e73bd8b24c674130299a2e" ></div>
</body>
<script>
var map_084fd12da6e91f44659dd95dda10e013 = L.map(
"map_084fd12da6e91f44659dd95dda10e013",
var map_67cd6a07e1e73bd8b24c674130299a2e = L.map(
"map_67cd6a07e1e73bd8b24c674130299a2e",
{
center: [0.0, 0.0],
crs: L.CRS.EPSG3857,
@ -60,13 +60,13 @@
var tile_layer_67f4a27d47a2b4494d6ed3f07cc58c1c = L.tileLayer(
var tile_layer_ce904b97c8dd293fcdeb3021c651794e = L.tileLayer(
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{"attribution": "\u0026copy; \u003ca href=\"https://www.openstreetmap.org/copyright\"\u003eOpenStreetMap\u003c/a\u003e contributors", "detectRetina": false, "maxNativeZoom": 19, "maxZoom": 19, "minZoom": 0, "noWrap": false, "opacity": 1, "subdomains": "abc", "tms": false}
);
tile_layer_67f4a27d47a2b4494d6ed3f07cc58c1c.addTo(map_084fd12da6e91f44659dd95dda10e013);
tile_layer_ce904b97c8dd293fcdeb3021c651794e.addTo(map_67cd6a07e1e73bd8b24c674130299a2e);
</script>
@ -87,7 +87,7 @@
}
trajeto_json_add({"features": []});
trajeto_json.addTo(map_084fd12da6e91f44659dd95dda10e013);
trajeto_json.addTo(map_67cd6a07e1e73bd8b24c674130299a2e);
function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria);
@ -145,7 +145,7 @@
var marcadorDinamico = L.marker([0, 0], {
icon: customIcon
}).addTo(map_084fd12da6e91f44659dd95dda10e013);
}).addTo(map_67cd6a07e1e73bd8b24c674130299a2e);
// Conectar ao broker MQTT
const client = mqtt.connect('ws://localhost:9001'); // Use wss para conexão segura
@ -183,7 +183,7 @@
marcadorDinamico.setRotationAngle(angulo);
adicionarCoordenada("Tj", [novaLongitude, novaLatitude]);
map_084fd12da6e91f44659dd95dda10e013.setView(novaPosicao, map_084fd12da6e91f44659dd95dda10e013.getZoom());
map_67cd6a07e1e73bd8b24c674130299a2e.setView(novaPosicao, map_67cd6a07e1e73bd8b24c674130299a2e.getZoom());
});
function calcularOrientacao(P1latitude, P1longitude, P2latitude, P2longitude) {

View File

@ -25,7 +25,7 @@
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<style>
#map_6db772d0d8d14e2d02efe2b399e87581 {
#map_895975571795f58cc80aa1bfdf54e824 {
position: relative;
width: 100.0%;
height: 100.0%;
@ -39,14 +39,14 @@
<body>
<div class="folium-map" id="map_6db772d0d8d14e2d02efe2b399e87581" ></div>
<div class="folium-map" id="map_895975571795f58cc80aa1bfdf54e824" ></div>
</body>
<script>
var map_6db772d0d8d14e2d02efe2b399e87581 = L.map(
"map_6db772d0d8d14e2d02efe2b399e87581",
var map_895975571795f58cc80aa1bfdf54e824 = L.map(
"map_895975571795f58cc80aa1bfdf54e824",
{
center: [0.0, 0.0],
crs: L.CRS.EPSG3857,
@ -60,13 +60,13 @@
var tile_layer_53d89bd6580a52ed08e8b535dbe73fc5 = L.tileLayer(
var tile_layer_01645eade339bfe02b20ad4fd3bc3378 = L.tileLayer(
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
{"attribution": "\u0026copy; \u003ca href=\"https://www.openstreetmap.org/copyright\"\u003eOpenStreetMap\u003c/a\u003e contributors", "detectRetina": false, "maxNativeZoom": 19, "maxZoom": 19, "minZoom": 0, "noWrap": false, "opacity": 1, "subdomains": "abc", "tms": false}
);
tile_layer_53d89bd6580a52ed08e8b535dbe73fc5.addTo(map_6db772d0d8d14e2d02efe2b399e87581);
tile_layer_01645eade339bfe02b20ad4fd3bc3378.addTo(map_895975571795f58cc80aa1bfdf54e824);
@ -82,7 +82,7 @@
}*/
});
}
function geo_json_3dd7e60984a746b98c90d1ccb69ef337_onEachFeature(feature, layer) {
function geo_json_f0f226a0199059fea21b2eb31e350844_onEachFeature(feature, layer) {
layer.on({
click: function(e) {
@ -118,20 +118,20 @@
}*/
});
};
var geo_json_3dd7e60984a746b98c90d1ccb69ef337 = L.geoJson(null, {
onEachFeature: geo_json_3dd7e60984a746b98c90d1ccb69ef337_onEachFeature,
var geo_json_f0f226a0199059fea21b2eb31e350844 = L.geoJson(null, {
onEachFeature: geo_json_f0f226a0199059fea21b2eb31e350844_onEachFeature,
});
function geo_json_3dd7e60984a746b98c90d1ccb69ef337_add (data) {
geo_json_3dd7e60984a746b98c90d1ccb69ef337
function geo_json_f0f226a0199059fea21b2eb31e350844_add (data) {
geo_json_f0f226a0199059fea21b2eb31e350844
.addData(data);
}
geo_json_3dd7e60984a746b98c90d1ccb69ef337_add({"features": [{"geometry": {"coordinates": [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]], "id": null, "type": "LineString"}, "id": 0, "properties": {"Dist1": 0.0, "Dist2": 0.0, "Id": "1", "Length": 0.0, "Name": "02_04_2025_17_20_50"}, "type": "Feature"}], "type": "FeatureCollection"});
geo_json_f0f226a0199059fea21b2eb31e350844_add({"features": [{"geometry": {"coordinates": [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]], "id": null, "type": "LineString"}, "id": 0, "properties": {"Dist1": 0.0, "Dist2": 0.0, "Id": "1", "Length": 0.0, "Name": "03_04_2025_10_58_00"}, "type": "Feature"}], "type": "FeatureCollection"});
geo_json_3dd7e60984a746b98c90d1ccb69ef337.addTo(map_6db772d0d8d14e2d02efe2b399e87581);
geo_json_f0f226a0199059fea21b2eb31e350844.addTo(map_895975571795f58cc80aa1bfdf54e824);
</script>
@ -152,7 +152,7 @@
}
trajeto_json_add({"features": []});
trajeto_json.addTo(map_6db772d0d8d14e2d02efe2b399e87581);
trajeto_json.addTo(map_895975571795f58cc80aa1bfdf54e824);
function adicionarGeometria(novaGeometria) {
trajeto_json.addData(novaGeometria);
@ -210,7 +210,7 @@
}
trajeto_dinamico_json_add({"features": []});
trajeto_dinamico_json.addTo(map_6db772d0d8d14e2d02efe2b399e87581);
trajeto_dinamico_json.addTo(map_895975571795f58cc80aa1bfdf54e824);
function adicionarGeometriaDinamica(novaGeometria) {
trajeto_dinamico_json.addData(novaGeometria);
@ -263,9 +263,9 @@
var marcadorEquipamento = L.marker([0, 0], {
icon: customIcon
}).addTo(map_6db772d0d8d14e2d02efe2b399e87581);
}).addTo(map_895975571795f58cc80aa1bfdf54e824);
var marcadorBase = L.marker([0, 0], {}).addTo(map_6db772d0d8d14e2d02efe2b399e87581);
var marcadorBase = L.marker([0, 0], {}).addTo(map_895975571795f58cc80aa1bfdf54e824);
var icon = L.AwesomeMarkers.icon(
{"extraClasses": "fa-rotate-0", "icon": "info-sign", "iconColor": "white", "markerColor": "red", "prefix": "glyphicon"}
);
@ -347,7 +347,7 @@
}
if (foco) {
map_6db772d0d8d14e2d02efe2b399e87581.setView(novaPosicao, map_6db772d0d8d14e2d02efe2b399e87581.getZoom());
map_895975571795f58cc80aa1bfdf54e824.setView(novaPosicao, map_895975571795f58cc80aa1bfdf54e824.getZoom());
}
}
@ -364,7 +364,7 @@
function atualizarSelecaoRuas(selecionadas) {
selecionadas = JSON.parse(selecionadas);
RuasSelecionadas = Array.isArray(selecionadas) ? [...selecionadas] : [];
geo_json_3dd7e60984a746b98c90d1ccb69ef337.eachLayer(function (layer) {
geo_json_f0f226a0199059fea21b2eb31e350844.eachLayer(function (layer) {
if (RuasSelecionadas.includes(parseInt(layer.feature.id))) {
layer.setStyle({ color: 'blue' });
} else {

View File

@ -1 +1 @@
1ccd04225d048dc265da75465ce916117f9ec7d8ad86c56b4979cd52d202386b
72612633a638e852d1ad773fe9be7468ab3bb5f45f191001dba7ac9c77d8755b

View File

@ -33,7 +33,7 @@
this.rtbA05 = new System.Windows.Forms.RichTextBox();
this.chbA05 = new System.Windows.Forms.CheckBox();
this.rtbKnt = new System.Windows.Forms.RichTextBox();
this.chbKnt = new System.Windows.Forms.CheckBox();
this.chbSnr = new System.Windows.Forms.CheckBox();
this.rtbLRA = new System.Windows.Forms.RichTextBox();
this.chbLra = new System.Windows.Forms.CheckBox();
this.rtbATU = new System.Windows.Forms.RichTextBox();
@ -95,18 +95,18 @@
this.lblVelocidadeDirecional = new System.Windows.Forms.Label();
this.lblAnguloMaximo = new System.Windows.Forms.Label();
this.tabMapa = new System.Windows.Forms.TabPage();
this.chbMapaDinamico = new System.Windows.Forms.CheckBox();
this.lblTempoEstimado = new System.Windows.Forms.Label();
this.lblDistanciaOperacao = new System.Windows.Forms.Label();
this.lblDistanciaTotal = new System.Windows.Forms.Label();
this.btnCarregarMapa = new System.Windows.Forms.Button();
this.lblMapaCarregado = new System.Windows.Forms.Label();
this.pnlMapa = new System.Windows.Forms.Panel();
this.pnlZoomMapa = new System.Windows.Forms.Panel();
this.btnSalvar = new System.Windows.Forms.Button();
this.btnCarregar = new System.Windows.Forms.Button();
this.txtDescricao = new System.Windows.Forms.TextBox();
this.lblDescricao = new System.Windows.Forms.Label();
this.pnlZoomMapa = new System.Windows.Forms.Panel();
this.chbMapaDinamico = new System.Windows.Forms.CheckBox();
this.gpbModulos.SuspendLayout();
this.pnlModulos.SuspendLayout();
this.tabControl1.SuspendLayout();
@ -143,7 +143,7 @@
this.pnlModulos.Controls.Add(this.rtbA05);
this.pnlModulos.Controls.Add(this.chbA05);
this.pnlModulos.Controls.Add(this.rtbKnt);
this.pnlModulos.Controls.Add(this.chbKnt);
this.pnlModulos.Controls.Add(this.chbSnr);
this.pnlModulos.Controls.Add(this.rtbLRA);
this.pnlModulos.Controls.Add(this.chbLra);
this.pnlModulos.Controls.Add(this.rtbATU);
@ -200,17 +200,17 @@
this.rtbKnt.TabIndex = 16;
this.rtbKnt.Text = "Responsável pelo monitoramento e detecção de obstáculos à frente do equipamento";
//
// chbKnt
// chbSnr
//
this.chbKnt.AutoSize = true;
this.chbKnt.BackColor = System.Drawing.SystemColors.Control;
this.chbKnt.Location = new System.Drawing.Point(3, 572);
this.chbKnt.Name = "chbKnt";
this.chbKnt.Size = new System.Drawing.Size(48, 17);
this.chbKnt.TabIndex = 17;
this.chbKnt.Text = "KNT";
this.chbKnt.UseVisualStyleBackColor = false;
this.chbKnt.CheckedChanged += new System.EventHandler(this.chbModulo_CheckedChanged);
this.chbSnr.AutoSize = true;
this.chbSnr.BackColor = System.Drawing.SystemColors.Control;
this.chbSnr.Location = new System.Drawing.Point(3, 572);
this.chbSnr.Name = "chbSnr";
this.chbSnr.Size = new System.Drawing.Size(49, 17);
this.chbSnr.TabIndex = 17;
this.chbSnr.Text = "SNR";
this.chbSnr.UseVisualStyleBackColor = false;
this.chbSnr.CheckedChanged += new System.EventHandler(this.chbModulo_CheckedChanged);
//
// rtbLRA
//
@ -864,6 +864,19 @@
this.tabMapa.Text = "Mapa";
this.tabMapa.UseVisualStyleBackColor = true;
//
// chbMapaDinamico
//
this.chbMapaDinamico.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.chbMapaDinamico.AutoSize = true;
this.chbMapaDinamico.Location = new System.Drawing.Point(425, 34);
this.chbMapaDinamico.Name = "chbMapaDinamico";
this.chbMapaDinamico.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
this.chbMapaDinamico.Size = new System.Drawing.Size(128, 17);
this.chbMapaDinamico.TabIndex = 6;
this.chbMapaDinamico.Text = "Exibir Mapa Dinamico";
this.chbMapaDinamico.UseVisualStyleBackColor = true;
this.chbMapaDinamico.CheckedChanged += new System.EventHandler(this.chbMapaDinamico_CheckedChanged);
//
// lblTempoEstimado
//
this.lblTempoEstimado.AutoSize = true;
@ -922,6 +935,16 @@
this.pnlMapa.Size = new System.Drawing.Size(550, 359);
this.pnlMapa.TabIndex = 0;
//
// pnlZoomMapa
//
this.pnlZoomMapa.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.pnlZoomMapa.BackColor = System.Drawing.Color.White;
this.pnlZoomMapa.Location = new System.Drawing.Point(159, 43);
this.pnlZoomMapa.Name = "pnlZoomMapa";
this.pnlZoomMapa.Size = new System.Drawing.Size(388, 313);
this.pnlZoomMapa.TabIndex = 16;
this.pnlZoomMapa.Visible = false;
//
// btnSalvar
//
this.btnSalvar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
@ -960,29 +983,6 @@
this.lblDescricao.TabIndex = 7;
this.lblDescricao.Text = "Descrição";
//
// pnlZoomMapa
//
this.pnlZoomMapa.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.pnlZoomMapa.BackColor = System.Drawing.Color.White;
this.pnlZoomMapa.Location = new System.Drawing.Point(159, 43);
this.pnlZoomMapa.Name = "pnlZoomMapa";
this.pnlZoomMapa.Size = new System.Drawing.Size(388, 313);
this.pnlZoomMapa.TabIndex = 16;
this.pnlZoomMapa.Visible = false;
//
// chbMapaDinamico
//
this.chbMapaDinamico.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.chbMapaDinamico.AutoSize = true;
this.chbMapaDinamico.Location = new System.Drawing.Point(425, 34);
this.chbMapaDinamico.Name = "chbMapaDinamico";
this.chbMapaDinamico.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
this.chbMapaDinamico.Size = new System.Drawing.Size(128, 17);
this.chbMapaDinamico.TabIndex = 6;
this.chbMapaDinamico.Text = "Exibir Mapa Dinamico";
this.chbMapaDinamico.UseVisualStyleBackColor = true;
this.chbMapaDinamico.CheckedChanged += new System.EventHandler(this.chbMapaDinamico_CheckedChanged);
//
// frmAjustesOperacao
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -1092,7 +1092,7 @@
private System.Windows.Forms.RichTextBox rtbA05;
private System.Windows.Forms.CheckBox chbA05;
private System.Windows.Forms.RichTextBox rtbKnt;
private System.Windows.Forms.CheckBox chbKnt;
private System.Windows.Forms.CheckBox chbSnr;
private System.Windows.Forms.Panel pnlParametros;
private System.Windows.Forms.GroupBox gpbSensoriamento;
private System.Windows.Forms.Label lblConfigUltrassom;

View File

@ -243,9 +243,16 @@ namespace AgroMonitor.Forms
});
}
if (Dispositivo == T_Code.A05 || Dispositivo == T_Code.Knt)
List<T_Code> dispositivosSensoriamento = new List<T_Code>() { T_Code.Snr, T_Code.A05 };
if (dispositivosSensoriamento.Contains(Dispositivo))
{
gpbSensoriamento.Enabled = chb.Checked;
bool sensoriamentoAtivado = false;
foreach (var disp in dispositivosSensoriamento)
{
sensoriamentoAtivado |= (FuncoesGlobais.FindControlRecursive<CheckBox>(pnlModulos, "chb" + disp.ToString())).Checked;
}
gpbSensoriamento.Enabled = sensoriamentoAtivado;
}
}