Initial commit from MyParking project
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using CommonUsage.Mathematics;
|
||||
using FundamentalLib;
|
||||
|
||||
namespace CommonUsage.Chassis
|
||||
{
|
||||
public class SingleSteerChassis : AbstractChassis
|
||||
{
|
||||
public void SetSteerWheel(SteerWheel wheel)
|
||||
{
|
||||
_steerWheel = wheel;
|
||||
}
|
||||
|
||||
public SteerWheel GetSteerWheel()
|
||||
{
|
||||
return _steerWheel;
|
||||
}
|
||||
|
||||
public override void Visualize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override CarSpeed GetCarSpeed(bool isActual = false)
|
||||
{
|
||||
if (!isActual)
|
||||
{
|
||||
var sendAngle = _steerWheel.GetSendAngle();
|
||||
var sendAngleRad = _steerWheel.GetSendAngle() / 180f * Math.PI;
|
||||
// VSteer* Cos = v;
|
||||
var vsteer = _sendSpeed / ((Math.Cos(Math.Abs(sendAngleRad)) + 0.000001));
|
||||
var vsteerY = vsteer * Math.Sin(sendAngleRad);
|
||||
// Console.WriteLine($"{vsteer} {vsteerY} {sendAngleRad} {_sendSpeed}");
|
||||
return new CarSpeed()
|
||||
{
|
||||
Vx = (float)(_sendSpeed * Math.Cos(Math.Abs(sendAngle) / 180f * Math.PI)),
|
||||
Vy = 0,
|
||||
Vw = (float)(_sendSpeed * Math.Sin(Math.Abs(sendAngle) / 180f * Math.PI) /
|
||||
Math.Abs(_steerWheel.Position.X / 1000f) / Math.PI * 180f)
|
||||
//阿克曼
|
||||
// Vx = (float)(_sendSpeed),
|
||||
// Vy = 0,
|
||||
// Vw = (float)(vsteerY / Math.Abs(_steerWheel.Position.X / 1000f) / Math.PI * 180f)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return new CarSpeed()
|
||||
{
|
||||
Vx = (float)(_steerWheel.ReadSpeed() *
|
||||
Math.Cos(Math.Abs(_steerWheel.ReadAngle()) / 180f * Math.PI)),
|
||||
Vy = 0,
|
||||
Vw = (float)(_steerWheel.ReadSpeed() *
|
||||
Math.Sin(Math.Abs(_steerWheel.ReadAngle()) / 180f * Math.PI) /
|
||||
Math.Abs(_steerWheel.Position.X / 1000f) / Math.PI * 180f)
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
GeometricControlPoints = new List<GeometricControlPoint>()
|
||||
{
|
||||
new (_steerWheel.Position),
|
||||
new (Vector2.Zero)
|
||||
};
|
||||
Valid = true;
|
||||
}
|
||||
|
||||
public override void AfterDirectionChanged()
|
||||
{
|
||||
if (Math.Abs(CommonMath.ThDiff(0, _originBiasTh)) > 90)
|
||||
{
|
||||
GeometricControlPoints = new List<GeometricControlPoint>()
|
||||
{
|
||||
new (-_steerWheel.Position),
|
||||
};
|
||||
_direction = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
GeometricControlPoints = new List<GeometricControlPoint>()
|
||||
{
|
||||
new (_steerWheel.Position),
|
||||
};
|
||||
_direction = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public override void PredefinedDriveStop()
|
||||
{
|
||||
if (!Valid) return;
|
||||
_sendSpeed = 0;
|
||||
_steerWheel.WriteSpeed(_sendSpeed);
|
||||
GoingActive = false;
|
||||
RotatingActive = false;
|
||||
}
|
||||
|
||||
protected override void DefineGeometricWheelComputation(float speed)
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
if (!GoingActive)
|
||||
{
|
||||
LastMoveTime = now;
|
||||
GoingWheelAligned = false;
|
||||
}
|
||||
|
||||
SendSteerMotion(speed * _direction, GeometricControlPoints[0].Theta, now - LastMoveTime);
|
||||
|
||||
GoingActive = true;
|
||||
RotatingActive = false;
|
||||
}
|
||||
|
||||
public override bool ComputeRotateWheels(float rotSpeed)
|
||||
{
|
||||
if (!RotatingActive)
|
||||
{
|
||||
LastMoveTime = DateTime.Now;
|
||||
GoingWheelAligned = false;
|
||||
}
|
||||
|
||||
SendSteerMotion(rotSpeed, 90);
|
||||
|
||||
GoingActive = false;
|
||||
RotatingActive = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SendSteerMotion(float speed, float theta, TimeSpan? deltaTime = null)
|
||||
{
|
||||
_steerWheel.WriteAngle(theta);
|
||||
|
||||
if (!GoingWheelAligned && Math.Abs(CommonMath.ThDiff(_steerWheel.ReadAngle(), theta)) < 1)
|
||||
GoingWheelAligned = true;
|
||||
if (!GoingWheelAligned) speed = 0;
|
||||
|
||||
var turnThresholdSpeed = CalculateTurningSpeedDecayFac(Math.Abs(theta)) * MaxSpeed;
|
||||
AccumulateSpeed(Math.Min(turnThresholdSpeed, Math.Abs(speed)) * Math.Sign(speed), deltaTime);
|
||||
|
||||
LastMoveTime = DateTime.Now;
|
||||
}
|
||||
|
||||
public override float CalculateTurningSpeedDecayFac(float turn)
|
||||
{
|
||||
return 1 - Math.Min(turn, MaxTurnThreshold) / MaxTurnThreshold * MinTurnSpeedFac;
|
||||
}
|
||||
|
||||
private void AccumulateSpeed(float v, TimeSpan? deltaTime = null)
|
||||
{
|
||||
// _targetSpeed = v;
|
||||
var speedSign = Math.Sign(v - _sendSpeed);
|
||||
var acc = Math.Abs(v) > Math.Abs(_sendSpeed) ? AccPerSecond : DeAccPerSecond;
|
||||
_sendSpeed += speedSign * Math.Min(Math.Abs(v - _sendSpeed),
|
||||
acc * (float)(deltaTime ?? DateTime.Now - LastMoveTime).TotalSeconds);
|
||||
_steerWheel.WriteSpeed(_sendSpeed);
|
||||
|
||||
if (Debug)
|
||||
Console.WriteLine($"SingleSteer, target:{v:0.00},send:{_sendSpeed:0.0}");
|
||||
}
|
||||
|
||||
private SteerWheel _steerWheel;
|
||||
private float _sendSpeed;
|
||||
private int _direction = 1; // 1 forward, -1 backward
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user