ajuste na atuação do bico enquanto parado e antecipação da zona de atuação conforme velcodaide
This commit is contained in:
parent
bfed826136
commit
bb546da70f
|
|
@ -296,6 +296,8 @@ class WeedDetector:
|
|||
|
||||
cfg = self.config
|
||||
vel_mps = float(cfg.get("velocidade_robo", 0.0) or 0.0)
|
||||
# A geometria de atuação foi definida para o avanço. A ré não é
|
||||
# reinterpretada como um percurso espacial inverso dos bicos.
|
||||
if vel_mps < 0:
|
||||
vel_mps = 0.0
|
||||
|
||||
|
|
@ -463,9 +465,14 @@ class WeedDetector:
|
|||
self._frac_grid_last = frac_grid
|
||||
|
||||
# 3) Atualiza score espacial.
|
||||
# Em movimento, acumula evidência e desloca a esteira normalmente.
|
||||
# Parado, acompanha a evidência do frame atual por EMA: o mesmo ruído
|
||||
# não pode ser somado indefinidamente, mas uma erva persistente continua
|
||||
# podendo manter/ligar o bico.
|
||||
score_update_info = self._atualizar_score_memoria(
|
||||
frac_grid=frac_grid,
|
||||
cfg=cfg,
|
||||
em_movimento=bool(shift_info["em_movimento"]),
|
||||
)
|
||||
|
||||
# 4) Decide bicos pela zona física de atuação, com compensação de latência.
|
||||
|
|
@ -533,6 +540,7 @@ class WeedDetector:
|
|||
return {
|
||||
"dt_s": 0.0,
|
||||
"vel_mps": float(vel_mps),
|
||||
"em_movimento": False,
|
||||
"delta_frac": 0.0,
|
||||
"shift_cells": 0.0,
|
||||
"distancia_deslocada_total_cm": float(self._distancia_deslocada_total_cm),
|
||||
|
|
@ -545,10 +553,17 @@ class WeedDetector:
|
|||
if max_dt > 0:
|
||||
dt = min(dt, max_dt)
|
||||
|
||||
if dt <= 0 or vel_mps <= 0:
|
||||
vel_min = max(
|
||||
0.0,
|
||||
float(cfg.get("vel_min_movimento_memoria_mps", 0.03) or 0.03),
|
||||
)
|
||||
em_movimento = bool(abs(vel_mps) >= vel_min)
|
||||
|
||||
if dt <= 0 or not em_movimento:
|
||||
return {
|
||||
"dt_s": float(max(0.0, dt)),
|
||||
"vel_mps": float(vel_mps),
|
||||
"em_movimento": False,
|
||||
"delta_frac": 0.0,
|
||||
"shift_cells": 0.0,
|
||||
"distancia_deslocada_total_cm": float(self._distancia_deslocada_total_cm),
|
||||
|
|
@ -582,6 +597,7 @@ class WeedDetector:
|
|||
return {
|
||||
"dt_s": float(dt),
|
||||
"vel_mps": float(vel_mps),
|
||||
"em_movimento": True,
|
||||
"delta_frac": float(delta_frac),
|
||||
"shift_cells": float(shift_cells),
|
||||
"k_shift_frame_por_mps": float(k_shift),
|
||||
|
|
@ -723,6 +739,7 @@ class WeedDetector:
|
|||
self,
|
||||
frac_grid: np.ndarray,
|
||||
cfg: dict,
|
||||
em_movimento: bool = True,
|
||||
):
|
||||
min_frac_pred = float(
|
||||
cfg.get(
|
||||
|
|
@ -748,7 +765,9 @@ class WeedDetector:
|
|||
evidencia = np.clip(frac_grid / percent_ref, 0.0, 1.0).astype(np.float32)
|
||||
cond_pos = frac_grid >= min_frac_pred
|
||||
|
||||
# Decaimento geral, depois reforço positivo.
|
||||
if em_movimento:
|
||||
# Em movimento, cada frame traz evidência de uma nova faixa física
|
||||
# do terreno; mantém a estratégia acumulativa original.
|
||||
score = np.maximum(0.0, self._score_grid - down_decay)
|
||||
|
||||
score = np.where(
|
||||
|
|
@ -756,6 +775,25 @@ class WeedDetector:
|
|||
np.minimum(1.0, score + up_gain * evidencia),
|
||||
score,
|
||||
).astype(np.float32)
|
||||
modo_atualizacao = "acumulativo_movimento"
|
||||
else:
|
||||
# Parado, vários frames observam essencialmente o mesmo terreno.
|
||||
# Uma EMA faz o score convergir para a evidência atual, em vez de
|
||||
# transformar repetição temporal em confiança espacial infinita.
|
||||
alpha_parado = float(cfg.get("score_alpha_parado", 0.70) or 0.70)
|
||||
alpha_parado = float(np.clip(alpha_parado, 0.0, 0.99))
|
||||
|
||||
evidencia_atual = np.where(
|
||||
cond_pos,
|
||||
evidencia,
|
||||
0.0,
|
||||
).astype(np.float32)
|
||||
|
||||
score = (
|
||||
alpha_parado * self._score_grid
|
||||
+ (1.0 - alpha_parado) * evidencia_atual
|
||||
).astype(np.float32)
|
||||
modo_atualizacao = "ema_parado"
|
||||
|
||||
self._score_grid = score
|
||||
|
||||
|
|
@ -764,6 +802,11 @@ class WeedDetector:
|
|||
"percent_ref_evidencia": float(percent_ref),
|
||||
"score_up_gain": float(up_gain),
|
||||
"score_down_decay": float(down_decay),
|
||||
"em_movimento": bool(em_movimento),
|
||||
"modo_atualizacao": modo_atualizacao,
|
||||
"score_alpha_parado": float(
|
||||
cfg.get("score_alpha_parado", 0.70) or 0.70
|
||||
),
|
||||
"frac_grid_max": float(frac_grid.max()) if frac_grid.size else 0.0,
|
||||
"evidencia_max": float(evidencia.max()) if evidencia.size else 0.0,
|
||||
}
|
||||
|
|
@ -788,20 +831,32 @@ class WeedDetector:
|
|||
|
||||
k_shift = max(0.0, k_shift)
|
||||
|
||||
# Antecipação em fração da imagem:
|
||||
# Se demora para atuar, avalia células um pouco acima da zona real,
|
||||
# porque elas chegarão na zona quando o bico abrir de fato.
|
||||
antecipacao_frac = max(0.0, vel_mps * lat_s * k_shift)
|
||||
# A zona configurada representa a posição física fixa dos bicos.
|
||||
# Com faixa=0,85, área=0,10 e inversão vertical, 85%..95% da imagem
|
||||
# original vira 5%..15% na convenção interna. Essa zona NÃO muda de
|
||||
# parado até a velocidade de referência. Somente a parcela de
|
||||
# velocidade ACIMA da referência antecipa a avaliação para compensar
|
||||
# o tempo de resposta do sistema.
|
||||
vel_referencia = max(
|
||||
0.0,
|
||||
float(cfg.get("velocidade_referencia_atuacao_mps", 0.65) or 0.65),
|
||||
)
|
||||
velocidade_abs = abs(float(vel_mps))
|
||||
velocidade_excedente = max(0.0, velocidade_abs - vel_referencia)
|
||||
antecipacao_extra_frac = velocidade_excedente * lat_s * k_shift
|
||||
|
||||
if getattr(self, "inverter_sentido_vertical_bicos", False):
|
||||
# Se a erva vem do pé para o topo, antecipar significa olhar
|
||||
# um pouco abaixo da zona real, pois ela ainda vai subir até o bico.
|
||||
zona_eval_ini_frac = zona_ini_frac + antecipacao_frac
|
||||
zona_eval_fim_frac = zona_fim_frac + antecipacao_frac
|
||||
else:
|
||||
# Lógica atual: erva vem do topo para o pé.
|
||||
zona_eval_ini_frac = zona_ini_frac - antecipacao_frac
|
||||
zona_eval_fim_frac = zona_fim_frac - antecipacao_frac
|
||||
# A posição dos bicos é fixa. Não tentamos reinterpretar essa zona na
|
||||
# marcha a ré; a antecipação só indica uma região anterior no sentido
|
||||
# visual configurado para a operação normal de avanço.
|
||||
sentido_vertical = (
|
||||
1.0
|
||||
if getattr(self, "inverter_sentido_vertical_bicos", False)
|
||||
else -1.0
|
||||
)
|
||||
offset_assinado = antecipacao_extra_frac * sentido_vertical
|
||||
|
||||
zona_eval_ini_frac = zona_ini_frac + offset_assinado
|
||||
zona_eval_fim_frac = zona_fim_frac + offset_assinado
|
||||
|
||||
zona_eval_ini_frac = max(0.0, min(1.0, zona_eval_ini_frac))
|
||||
zona_eval_fim_frac = max(0.0, min(1.0, zona_eval_fim_frac))
|
||||
|
|
@ -872,7 +927,12 @@ class WeedDetector:
|
|||
|
||||
# Zona avaliada com compensação de latência.
|
||||
"latencia_total_atuacao_ms": float(lat_ms),
|
||||
"antecipacao_frac": float(antecipacao_frac),
|
||||
"antecipacao_frac": float(antecipacao_extra_frac),
|
||||
"velocidade_referencia_atuacao_mps": float(vel_referencia),
|
||||
"velocidade_excedente_atuacao_mps": float(velocidade_excedente),
|
||||
"offset_base_referencia_frac": 0.0,
|
||||
"antecipacao_extra_frac": float(antecipacao_extra_frac),
|
||||
"offset_assinado_frac": float(offset_assinado),
|
||||
"zona_eval_inicio_frac": float(zona_eval_ini_frac),
|
||||
"zona_eval_fim_frac": float(zona_eval_fim_frac),
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue