Unity平台模拟自动驾驶汽车

日期: 2023-09-15 15:03:39|浏览: 221|编号: 54242
联系人:中国品瑞奢侈品修复护理 电话:13115811533 微信:772392775

Unity平台模拟自动驾驶汽车

自动车功能分析:

(1)制动值用0-255的连续量表示。 持续量根据按下键盘按钮的时间长度而增加,并在1秒后达到峰值。 无论车辆处于前进档还是倒档,制动后车辆逐渐减速至0。

(2)汽车分为四个档位,停车档P、倒档R、空档N、前进档D。

(3)汽车启动后,松开制动,车辆进入怠速模式,速度从0逐渐增加至12KM/H

(4)制动值用0-255的连续值表示。 车速对应1档0-10、2档11-20、3档21-40、4档41-60、5档61-80、6档81-最大,对应最高车速150KM/H。

(5)握住P档并拉起手刹将车辆停止。

(6)挂R档时,车辆可以倒车。

(7)可通过键盘A、D控制车辆左右转向

运行结果图:

启动车辆,拉起手刹,挂入前进档,进入怠速模式,缓慢加速。

车速增至12km/h后,匀速行驶。 要继续加速,您需要踩油门。

踩下油门后,车辆快速加速并自行换档:

向前行驶时,刹车后汽车逐渐减速至0:

切换至倒档,踩油门,车辆向后行驶,踩刹车,车辆逐渐减速至0:

前进时左右转:

倒档时从左向右换档:

源代码:

方法的使用,采用的是单例模式。

该类负责管理车辆的物理模拟。 该类负责接受用户的键盘输入信息。 该类负责更新UI界面的显示。

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using UnityEngine;
public class Car_Mng : MonoBehaviour
{    
    static public Car_Mng Instance;
    public SpeedGear speedGear;
    public float maxMotorTorque;  //最大的前进力矩
    public float maxSpeed;        //车辆最大前进速度
    public float maxReversMotorTorque;  //最大的倒车力矩
    public float maxBrakeToeque;   //最大的刹车阻力
    public float maxSteeringAngle;  //主动轮最大的旋转角度
    public Rigidbody car;   //车辆的刚体
    public WheelCollider[] coliders;   //车轮碰撞器
    public GameObject[] wheelMesh;     //车轮模型
    public  CarState carState=CarState.Off;   //车辆启动状态
    public  GearState gearState = GearState.ParkingGear;   //车辆的挡位
    public bool isHandBrakeON;     //是否拉起手刹的标志位
    public float currentSpeed=0;   //计算当前车辆的速度
    private bool currentHandBrakeState=true;
    private void Awake()
    {
        Instance = this;
    }
    void Start()
    {
       /* coliders[0].steerAngle = 30;
        coliders[1].steerAngle = 30;
        for (int i = 0; i < 4; i++)
        {
            Quaternion quat;
            Vector3 position;
            coliders[i].GetWorldPose(out position, out quat);
            Debug.Log(position);
            Debug.Log(quat.eulerAngles);
            wheelMesh[i].transform.position = position;
            wheelMesh[i].transform.rotation = 
                coliders[i].transform.rotation * Quaternion.Euler(0, coliders[i].steerAngle, 0); 
           
        }*/
    }
    private void Update()
    {
        UpdateHandBrokeState();  //更新手刹状态
    }
    private void FixedUpdate()
    {
        if (gearState == GearState.ForwardGear || gearState == GearState.ReversGear)
        {
            BrakeCalculate();  //刹车计算   阻力   
            AccCalculate();     //油门计算   动力
        }
        SteerCalculate();
        UpdateCarSpeed();  //更新车子的速度
        AutoChangeGear();   //自动换挡   自动挡的车子
        SynchronousWheelMesh();  //将车轮的状态同步给车的模型
       
       
    }
    void SynchronousWheelMesh()
    {
        for (int i = 0; i < 6; i++)
        {
            Quaternion quat;
            Vector3 position;
            coliders[i].GetWorldPose(out position, out quat);
            wheelMesh[i].transform.position = position;
            wheelMesh[i].transform.rotation = quat;
        }
    }
    void UpdateHandBrokeState()
    {
        if (currentHandBrakeState != isHandBrakeON)
        {
            currentHandBrakeState = isHandBrakeON;
            if (currentHandBrakeState)
            {
                PullupHandbrake();
            }
            else
            {
                PullDownHandbrake();
            }
        }
    }   //更新手刹状态
    public void StartCar() //启动车辆
    {
        carState = CarState.On;
    }
    public void StopCar() //停车
    {
        carState = CarState.Off;  //停止接收油门、方向盘、刹车信号
        gearState = GearState.ParkingGear;     //挂上停车挡
        PullupHandbrake();  //拉起手刹
    }
    void PullupHandbrake() //拉起手刹,相当于阻力矩最大,直接Freeze车辆刚体的运动
    {
        isHandBrakeON = true; //设置标志位
        //仅保留y轴向的运动
        car.constraints = RigidbodyConstraints.FreezeRotation 
            | RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezePositionZ;
    }
    void PullDownHandbrake() //放下手刹,解锁运动
    {
        isHandBrakeON = false;
        //解锁所有运动
        car.constraints = RigidbodyConstraints.None;
    }
  
    void BrakeCalculate()  //计算刹车的阻力
    {
        
        var value = Input_Mng.Instance.GetBrakeValue();  //读取刹车阻力
        var brakeToequePerWheel = maxBrakeToeque / 2 * value / 255;  //计算一个车轮的阻力
        coliders[0].motorTorque = 0;
        coliders[1].motorTorque = 0;
        for (int i = 0; i < 6; i++)
        {
            coliders[i].brakeTorque = brakeToequePerWheel;
        }
       
        // Debug.Log("刹车阻力:"+ brakeToequePerWheel);
    }
    void AccCalculate()    //油门动力计算
    {        
        if (gearState == GearState.ForwardGear)  //前进
        {           
            var value = Input_Mng.Instance.GetAcceleratorValue();
            if (value != 0) //加速行驶
            {
                
                if(MeterPerSeconds2KmPerHour(currentSpeed) <= 150)
                {
                    var accToequePerWheel = maxMotorTorque  * value / 255;  //计算一个车轮的动力
                    coliders[0].motorTorque = accToequePerWheel;
                    coliders[1].motorTorque = accToequePerWheel;
                }
                else  //不能超过速度上限
                {
                    coliders[0].motorTorque = 0;
                    coliders[1].motorTorque = 0;
                }
            }
            else //怠速驾驶
            {
                if (MeterPerSeconds2KmPerHour(currentSpeed) < 12)
                {
                    coliders[0].motorTorque = 100;
                    coliders[1].motorTorque = 100;
                }
                else
                {
                    Debug.Log("无动力");
                    for (int i = 0; i < 6; i++)
                    {
                        coliders[i].motorTorque = 0;
                    }
                }
                
            }
            
        }
        else   //倒车
        {            
            var value = Input_Mng.Instance.GetAcceleratorValue();
            var accToequePerWheel = maxReversMotorTorque / 2 * value / 255;  //计算一个车轮的动力
            coliders[0].motorTorque = -accToequePerWheel;
            coliders[1].motorTorque = -accToequePerWheel;
        }
            
    }
    void SteerCalculate() //计算转向
    {
        var value= Input_Mng.Instance.GetSteerValue();
        var steerAngle = (value - 128) / 128 * maxSteeringAngle; //计算旋转角度
        coliders[0].steerAngle = steerAngle;
        coliders[1].steerAngle = steerAngle;
    }
    void AutoChangeGear() //自动挡,前进时根据车辆的速度自动切换挡位
    {
        if (gearState == GearState.ForwardGear)
        {
            var speed = MeterPerSeconds2KmPerHour(currentSpeed);
            if (speed <= 10 && speed > 0)
            {
                speedGear = SpeedGear.Speed01;
            }
            if (speed <= 20 && speed > 10)
            {
                speedGear = SpeedGear.Speed02;
            }
            if (speed <= 40 && speed > 20)
            {
                speedGear = SpeedGear.Speed03;
            }
            if (speed <= 60 && speed > 40)
            {
                speedGear = SpeedGear.Speed04;
            }
            if (speed <= 80 && speed > 60)
            {
                speedGear = SpeedGear.Speed05;
            }
            if (speed <= 155 && speed > 80)
            {
                speedGear = SpeedGear.Speed06;
            }
        }
        else
        {
            speedGear = SpeedGear.none;
        }
        
    }
    void UpdateCarSpeed()
    {
        currentSpeed = car.velocity.magnitude;
    }
    static public float MeterPerSeconds2KmPerHour(float speed) //切换单位 m/s换算成 km/h
    {
        return speed*3.6f;
    }
    static float KmPerHour2MeterPerSeconds(float speed) //切换单位  km/h换算成m/s
    {
        return speed/3.6f;
    }
}
public enum CarState
{
    Off = 0,   //关机状态
    On = 1,     //运行状态
}
public enum GearState
{
    ParkingGear = 1,      //停车挡
    ReversGear = 2,       //倒挡
    NeutralGear = 3,       //空挡
    ForwardGear = 4,         //前进挡
}
public enum SpeedGear
{
    none,
    Speed01,
    Speed02,
    Speed03,
    Speed04,
    Speed05,
    Speed06
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Input_Mng : MonoBehaviour
{
    static public Input_Mng Instance;   //单例模式
    private KeyCode braKeyCode=KeyCode.M;     //刹车对应的键盘按键
    public float brakeValue = 0;   //刹车值
    public bool isBra = false;
    private KeyCode accKeyCode=KeyCode.W;   //油门对应的键盘按键
    public float acceleratorValue = 0;   //油门值
    public bool isAcc = false;
    private KeyCode leftSteerKeyCode = KeyCode.A;
    private KeyCode rightSteerKeyCode = KeyCode.D;
    public float steerValue = 128;
    private KeyCode parkingKeyCode = KeyCode.Alpha1;  //停车对应的按键
    private KeyCode reversKeyCode = KeyCode.Alpha2;   //倒车对应的按键
    private KeyCode neutralKeyCode = KeyCode.Alpha3;  //空挡对应的按键
    private KeyCode forwardKeyCode = KeyCode.Alpha4;  //前进挡对应的按键
    private KeyCode handBrakeKeyCode = KeyCode.H;  //手刹对应的按键
    public float GetBrakeValue()  //获取刹车值
    {
        return brakeValue;
    }
    public float GetAcceleratorValue()  //获取油门值
    {
        return acceleratorValue;
    }
    public float GetSteerValue()
    {
        return steerValue;
    }  //获取转弯值
    private void Awake()
    {
        Instance = this;
    }
    private void Update()
    {
        if (Car_Mng.Instance.carState == CarState.On)   //当车辆启动后,检测油门刹车和挡位变换
        {
            
            UpdateGeerState();
           
        }
        UpdateSteerValue();
        UpdateHandBrakeState();
        UpdateAcceleratorValue(accKeyCode);
        UpdateBrakeValue(braKeyCode);
    }
    void UpdateHandBrakeState()
    {
        if (Input.GetKeyDown(handBrakeKeyCode))
        {
            if (Car_Mng.Instance.isHandBrakeON)
            {
                Car_Mng.Instance.isHandBrakeON = false;
            }
            else
            {
                Car_Mng.Instance.isHandBrakeON = true;
            }
        }
    }
    void UpdateAcceleratorValue(KeyCode AccCode)
    {
        if (Input.GetKey(AccCode))
        {
            acceleratorValue += 255 * Time.deltaTime;
            acceleratorValue = Mathf.Clamp(acceleratorValue, 0, 255);
            isAcc = true;
        }
        else
        {
            acceleratorValue = 0;
            isAcc = false;
        }
    }   //更新油门状态
    void UpdateBrakeValue(KeyCode BraCode)     //更新刹车状态
    {
        if (Input.GetKey(BraCode))
        {
            brakeValue += 255 * Time.deltaTime;
            brakeValue = Mathf.Clamp(brakeValue, 0, 255);
            isBra = true;
        }
        else
        {
            brakeValue = 0;
            isBra = false;
        }
    }
   void UpdateSteerValue()   //更新方向盘状态
   {
        if (Input.GetKey(leftSteerKeyCode))
        {
            steerValue -= 255 * Time.deltaTime;     //0.5秒左侧打死
            steerValue = Mathf.Clamp(steerValue, 0, 255);
        }else if(Input.GetKey(rightSteerKeyCode))
        {
            steerValue += 255 * Time.deltaTime;     //0.5秒右侧打死
            steerValue = Mathf.Clamp(steerValue, 0, 255);
        }
        else
        {
            steerValue = 128;
        }
    }
    void UpdateGeerState()   //更新挡位状态
    {
        if (Input.GetKeyDown(parkingKeyCode))  //设置为停车档
        {
            Car_Mng.Instance.gearState = GearState.ParkingGear;
        }
        if (Input.GetKeyDown(reversKeyCode))  //倒车档
        {
            Car_Mng.Instance.gearState = GearState.ReversGear;
        }
        if (Input.GetKeyDown(neutralKeyCode))  //空挡
        {
            Car_Mng.Instance.gearState = GearState.NeutralGear;
        }
        if (Input.GetKeyDown(forwardKeyCode)) //前进挡
        {
            Car_Mng.Instance.gearState = GearState.ForwardGear;
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using UnityEngine;
using UnityEngine.UI;
public class UI_Mng : MonoBehaviour
{
    static public UI_Mng Instance;
    public Image ParkingBg;    //停车档
    public Image ForwardBg;    //前进挡
    public Image NeutralBg;    //空挡
    public Image ReversBg;     //倒车档
    public Image HandBrakeBg;  //手刹
    public Text speedText;   //速度显示
    public Text speedGearText;  //挡位显示
    public Image SwitchBg;  //开关背景
    public Text Switchtext;   //开关显示文字
    public Image AccBg;  //油门
    public Image BraBg;   //刹车
    private GearState currentGearState;
    private bool currentBrakeState;
    private void Awake()
    {
        Instance = this;
    }
    private void Update()
    {
        UpdateGearUI();
        UpdateHandBrakeUI();
        UpdateAccBra();
        UpdateSpeed();
    }
    void UpdateSpeed()
            

提醒:请联系我时一定说明是从同城奢侈品信息网上看到的!