ajustado dados do sonar OAK
This commit is contained in:
parent
e107e7a810
commit
8c87105398
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.
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 { }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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}
|
||||
|
|
@ -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]]}}]}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
1ccd04225d048dc265da75465ce916117f9ec7d8ad86c56b4979cd52d202386b
|
||||
72612633a638e852d1ad773fe9be7468ab3bb5f45f191001dba7ac9c77d8755b
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue