Робот Unity WheelCollider неправильно поворачивает и борется с уклонамиC#

Место общения программистов C#
Ответить
Anonymous
 Робот Unity WheelCollider неправильно поворачивает и борется с уклонами

Сообщение Anonymous »

Я работаю над проектом Unity, в котором автомобиль-робот должен автономно перемещаться по трассе с помощью датчиков. Модель автомобиля и окружающая среда фиксированы; единственный скрипт, который я изменяю, — это RobotController.cs, который управляет движением и рулевым управлением.
Робот:
  • Использует WheelColliders для движения и рулевого управления
  • Использует датчики Raycast (спереди, слева, справа) для обнаружения приближения
  • Использует Датчик EulerAngles для ориентации
  • Правильно движется вперед и передает ожидаемый крутящий момент двигателя
  • Колеса визуально вращаются и управляются правильно
Однако у меня есть две основные проблемы:
1. Машина поворачивает неправильно
Хотя:
  • Код: Выделить всё

    steerAngle
    применяется к коллайдерам передних колес.
  • Крутящий момент двигателя подается правильно.
  • Значения датчиков действительны и обновляются правильно.
…автомобиль либо:
  • едет в основном прямо и игнорирует повороты, либо
  • очень слабо поворачивает и съезжает с трассы на поворотах
2. Автомобиль плохо ведет себя на склонах
После улучшения поворотов автомобиль должен также:
  • Надежно ездить в гору и на спуске
  • Соответствующим образом регулировать мощность на уклонах
  • Сохранять устойчивость и сцепление с дорогой на наклонных поверхностях
На данный момент на склонах может:
  • терять скорость на подъеме
  • слишком агрессивно ускоряться на спуске
  • дрифтовать или не выдерживать намеченную траекторию
дополнительный контекст
  • логика рулевого управления и двигателя выполняется в методе FixUpdate()
  • рукоятка передних колес рулевое управление; задние колеса обеспечивают движение
  • Решения по рулевому управлению принимаются на основе расстояний raycast
  • Я не могу изменить модель транспортного средства, физические материалы или настройки Unity — только скрипт контроллера
Код
Ниже приведен фрагмент кода текущий RobotController.cs, над которым я работаю, где требуется управление рулевым управлением и управление наклоном улучшение.
Я также предоставил изображение макета дорожки для контекста.

Код: Выделить всё

// RobotController.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading.Tasks;

public class RobotController : MonoBehaviour
{
// wheel colliders
[SerializeField] private WheelCollider WheelColliderFrontLeft;
[SerializeField] private WheelCollider WheelColliderFrontRight;
[SerializeField] private WheelCollider WheelColliderBackLeft;
[SerializeField] private WheelCollider WheelColliderBackRight;
// transforms for the wheels
[SerializeField] private Transform TransformWheelFrontLeft;
[SerializeField] private Transform TransformWheelFrontRight;
[SerializeField] private Transform TransformWheelBackLeft;
[SerializeField] private Transform TransformWheelBackRight;

// transforms for the sensors
[SerializeField] private Transform RaycastSensorFront;
[SerializeField] private Transform RaycastSensorLeft;
[SerializeField] private Transform RaycastSensorRight;
[SerializeField] private Transform EulerAnglesSensor;

private Rigidbody rb;
[SerializeField] private float angle_x;
[SerializeField] private float angle_z;
[SerializeField] private float velocity;

private float steerAngle;
private float maxSteeringAngle;
private float motorForce =150f;
private float s1dist = 5;
private float s3dist = 4;

private void Start()
{
rb = GetComponent();
float s1x =0; float s1y=10;  float s1z =0;

AdjustSensors(RaycastSensorFront, 20,0,0);
AdjustSensors(RaycastSensorLeft, s1x,-s1y,s1z);
AdjustSensors(RaycastSensorRight, s1x,s1y,s1z);
AdjustSensors(EulerAnglesSensor, 50,180,0);
}

private void FixedUpdate()
{
StayOnRoad();
AvoidObstacles();
AdjustSpeed();
HandleMotor();
UpdateWheels();
angle_x = EulerAnglesSensor.eulerAngles.x;
angle_z = EulerAnglesSensor.eulerAngles.z;

velocity = rb.linearVelocity.magnitude;
}

private void AdjustSensors(Transform sensor, float x_angle, float y_angle, float z_angle)
{
sensor.transform.Rotate(x_angle, y_angle, z_angle);
}

private void HandleMotor()
{
WheelColliderFrontLeft.motorTorque = motorForce;
WheelColliderFrontRight.motorTorque = motorForce;
WheelColliderBackLeft.motorTorque = motorForce;
WheelColliderBackRight.motorTorque = motorForce;
}

private void UpdateWheels()
{
UpdateWheelPos(WheelColliderFrontLeft, TransformWheelFrontLeft);
UpdateWheelPos(WheelColliderFrontRight, TransformWheelFrontRight);
UpdateWheelPos(WheelColliderBackLeft, TransformWheelBackLeft);
UpdateWheelPos(WheelColliderBackRight, TransformWheelBackRight);
}

private void UpdateWheelPos(WheelCollider wheelCollider, Transform trans)
{
Vector3 pos;
Quaternion rot;
wheelCollider.GetWorldPose(out pos, out rot);
trans.rotation = rot;
trans.position = pos;
}

private void HandleSteering(float direction)
{
steerAngle = maxSteeringAngle * direction;
WheelColliderFrontLeft.steerAngle = steerAngle;
WheelColliderFrontRight.steerAngle = steerAngle;
}

private bool sense (Transform sensor, float dist)
{
if(Physics.Raycast(sensor.position, sensor.TransformDirection(Vector3.forward), dist))
{
Debug.DrawRay(sensor.position, sensor.TransformDirection(Vector3.forward) * dist, Color.yellow);
return true;
}
else
{
Debug.DrawRay(sensor.position, sensor.TransformDirection(Vector3.forward) * dist, Color.white);
return false;
}
}

private void StayOnRoad()
{
if(!sense(RaycastSensorLeft, s3dist) || !sense(RaycastSensorRight, s3dist))
{
if(!sense(RaycastSensorLeft, s3dist))
{
HandleSteering(1);
}
if(!sense(RaycastSensorRight, s3dist))
{
HandleSteering(-1);
}
}
else
{
HandleSteering(0);
}
}

private void AdjustSpeed()
{
if(velocity < 2 & motorForce < 50)
{
motorForce = motorForce + 0.5f;
}
if(velocity > 4 & motorForce > 0)
{
motorForce = motorForce - 0.5f;
}
}

private void AvoidObstacles()
{
if(sense(RaycastSensorLeft, s1dist))
{
HandleSteering(1);
}
if(sense(RaycastSensorRight, s1dist))
{
HandleSteering(-1);
}
}
}

В чем мне нужна помощь:
  • Распространенные ошибки при использовании WheelCollider рулевого управления
  • Как правильно сбалансировать крутящий момент двигателя, угол поворота и торможение
  • Необходимо ли по-другому сглаживать или зажимать рулевое управление
  • Лучшие практики для автономных систем на основе raycast рулевое управление
  • Методы управления движением в гору/спуска с помощью WheelColliders
  • Любая логика контроллера, которая может помешать правильному повороту или компенсации наклона
Любые советы, примеры или объяснения будут очень полезны.
Спасибо!
Изображение


Подробнее здесь: https://stackoverflow.com/questions/798 ... -on-slopes
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»