/// <summary> /// 检测转向灯 /// </summary> protected override void LeftIndicatorCheck(IndicatorCheckState checkState) { //角度设置0时,不进行角度达到检测转向灯 if (checkState == IndicatorCheckState.MidCheckAngle && Settings.TurnLeftAngle < 0.5) { return; } if (indicatorChecked) { return; } if (checkState == IndicatorCheckState.MidCheckAngle) { //设置了变道角度后 if (CurrentAngle.IsValidAngle() && StartAngle.IsValidAngle() && !GeoHelper.IsBetweenDiffAngle(CurrentAngle, StartAngle, Settings.TurnLeftAngle)) { if (Settings.TurnLeftEndFlag) { stopDelayDistance = CurrentDistance; } CheckLeft(); } } else if (checkState == IndicatorCheckState.StopCheck) { CheckLeft(); } }
/// <summary> /// 检测转向灯 /// </summary> protected override void LeftIndicatorCheck(IndicatorCheckState checkState) { //角度设置0时,不进行角度达到检测转向灯 if (checkState == IndicatorCheckState.MidCheckAngle && Settings.TurnRightAngle < 0.5) { return; } if (indicatorChecked) { return; } if (checkState == IndicatorCheckState.MidCheckAngle) { //设置了变道角度后 if (CarSignalSet.Current.BearingAngle.IsValidAngle() && StartAngle.IsValidAngle() && !GeoHelper.IsBetweenDiffAngle(CarSignalSet.Current.BearingAngle, StartAngle, Settings.TurnRightAngle)) { CheckRight(); } } else if (checkState == IndicatorCheckState.StopCheck) { CheckRight(); } }
public override void WriteGroupCodes() { WriteGroupCodeValue(10, X0.ToString().Trim()); WriteGroupCodeValue(20, Y0.ToString().Trim()); WriteGroupCodeValue(30, Z0.ToString().Trim()); WriteGroupCodeValue(40, Radius.ToString().Trim()); WriteGroupCodeValue(50, StartAngle.ToString().Trim()); WriteGroupCodeValue(51, EndAngle.ToString().Trim()); }
private void Update(EvaluationContext context) { var closeCircle = CloseCircle.GetValue(context); var circleOffset = closeCircle ? 1 : 0; var corners = Count.GetValue(context).Clamp(1, 10000); var pointCount = corners + circleOffset; var listCount = corners + 2 * circleOffset; // Separator if (_pointList.NumElements != listCount) { //_points = new T3.Core.DataTypes.Point[count]; _pointList.SetLength(listCount); } var axis = Axis.GetValue(context); var center = Center.GetValue(context); var offset = Offset.GetValue(context); var radius = Radius.GetValue(context); var radiusOffset = RadiusOffset.GetValue(context); var thickness = W.GetValue(context); var thicknessOffset = WOffset.GetValue(context); var angelInRads = StartAngle.GetValue(context) * MathUtils.ToRad + (float)Math.PI / 2; var deltaAngle = -Cycles.GetValue(context) * MathUtils.Pi2 / (pointCount - circleOffset); for (var index = 0; index < pointCount; index++) { var f = corners == 1 ? 1 : (float)index / pointCount; var length = MathUtils.Lerp(radius, radius + radiusOffset, f); var v = Vector3.UnitX * length; var rot = Quaternion.CreateFromAxisAngle(axis, angelInRads); var vInAxis = Vector3.Transform(v, rot) + Vector3.Lerp(center, center + offset, f); var p = new Point { Position = vInAxis, W = MathUtils.Lerp(thickness, thickness + thicknessOffset, f), Orientation = rot }; _pointList[index] = p; angelInRads += deltaAngle; } if (closeCircle) { _pointList[listCount - 1] = Point.Separator(); } ResultList.Value = _pointList; }
public override void Save() { MDictionary.Clear(); XmlHelperPaint.ShapeType = TrackType; MDictionary.Add("RecX", Rectangle.X.ToString()); MDictionary.Add("RecY", Rectangle.Y.ToString()); MDictionary.Add("RecW", Rectangle.Width.ToString()); MDictionary.Add("RecH", Rectangle.Height.ToString()); MDictionary.Add("StartAngle", StartAngle.ToString()); MDictionary.Add("EndAngle", EndAngle.ToString()); XmlHelperPaint.SavePaintSetting(MDictionary); }
/// <inheritdoc /> public override Vector3 GetNormalAt(Vector2 uv) { float u = uv.X; float v = uv.Y; Vector3 curveTangent = Vector3.Normalize(CenterCurve.GetTangentAt(v)); Vector3 curveNormal = Vector3.Normalize(CenterCurve.GetNormalAt(v)); Vector3 curveBinormal = Vector3.Cross(curveTangent, curveNormal); float startAngle = StartAngle.GetValueAt(v); float endAngle = EndAngle.GetValueAt(v); return((float)Math.Cos(u) * curveNormal + (float)Math.Sin(u) * curveBinormal); }
/// <inheritdoc /> public override dvec3 GetNormalAt(dvec2 uv) { DebugUtil.AssertAllFinite(uv, nameof(uv)); double u = uv.x; double v = uv.y; dvec3 curveTangent = CenterCurve.GetTangentAt(v).Normalized; dvec3 curveNormal = CenterCurve.GetNormalAt(v).Normalized; dvec3 curveBinormal = dvec3.Cross(curveTangent, curveNormal); double startAngle = StartAngle.GetValueAt(v); double endAngle = EndAngle.GetValueAt(v); return(Math.Cos(u) * curveNormal + Math.Sin(u) * curveBinormal); }
/// <summary> /// 속성들을 Xml Attribute로 생성합니다. /// </summary> /// <param name="writer">Attribute를 쓸 Writer</param> public override void GenerateXmlAttributes(System.Xml.XmlWriter writer) { base.GenerateXmlAttributes(writer); if (Sides.HasValue) { writer.WriteAttributeString("Sides", Sides.ToString()); } if (StartAngle.HasValue) { writer.WriteAttributeString("StartAngle", StartAngle.ToString()); } if (EndAngle.HasValue) { writer.WriteAttributeString("EndAngle", EndAngle.ToString()); } }
/// <inheritdoc /> public float RayIntersect(Ray ray) { Vector3 rayStart = ray.StartPosition; Vector3 rayDirection = ray.Direction; // Since we raytrace only using a cylindrical surface that is horizontal and at the origin, we // first shift and rotate the ray such that we get the right orientation: Vector3 start = CenterCurve.GetStartPosition(); Vector3 end = CenterCurve.GetEndPosition(); Vector3 tangent = Vector3.Normalize(CenterCurve.GetTangentAt(0.0f)); Vector3 normal = Vector3.Normalize(CenterCurve.GetNormalAt(0.0f)); Vector3 binormal = Vector3.Normalize(CenterCurve.GetBinormalAt(0.0f)); float length = Vector3.Distance(start, end); // CenterCurve is guaranteed to be a LineSegment, since the base property CenterCurve is masked by this // class' CenterCurve property that only accepts a LineSegment, and similarly this class' constructor only // accepts a LineSegment. The following mathematics, which assumes that the central axis is a line segment, // is therefore valid. Matrix4x4 rotationMatrix = new Matrix4x4(normal.X, binormal.X, tangent.X / length, 0.0f, normal.Y, binormal.Y, tangent.Y / length, 0.0f, normal.Z, binormal.Z, tangent.Z / length, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); Vector3 rescaledRay = Vector3.Transform(rayStart - start, rotationMatrix); Vector3 newDirection = Vector3.TransformNormal(Vector3.Normalize(rayDirection), rotationMatrix); float x0 = rescaledRay.X; float y0 = rescaledRay.Y; float z0 = rescaledRay.Z; float a = newDirection.X; float b = newDirection.Y; float c = newDirection.Z; // Raytrace using a cylindrical surface equation x^2 + y^2. The parameters in the following line // represent the coefficients of the expanded cylindrical surface equation, after the substitution // x = x_0 + a t and y = y_0 + b t: QuarticFunction surfaceFunction = new QuarticFunction(x0 * x0 + y0 * y0, 2.0f * (x0 * a + y0 * b), a * a + b * b, 0.0f, 0.0f); IEnumerable <float> intersections = Radius.SolveRaytrace(surfaceFunction, z0, c); // The previous function returns a list of intersection distances. The value closest to 0.0f represents the // closest intersection point. float minimum = Single.PositiveInfinity; foreach (float i in intersections) { // Calculate the 3d point at which the ray intersects the cylinder: Vector3 intersectionPoint = rayStart + i * rayDirection; // Find the closest point to the intersectionPoint on the centerLine. // Get the vector v from the start of the cylinder to the intersection point: Vector3 v = intersectionPoint - start; // ...And project this vector onto the center line: float t = -Vector3.Dot(intersectionPoint, tangent * length) / (length * length); // Now we have the parameter t on the surface of the SymmetricCylinder at which the ray intersects. // Find the angle to the normal of the centerLine, so that we can determine whether the // angle is within the bound of the pie-slice at position t: Vector3 centerLineNormal = CenterCurve.GetNormalAt(t); Vector3 centerLineBinormal = CenterCurve.GetBinormalAt(t); Vector3 d = intersectionPoint - CenterCurve.GetPositionAt(t); float correctionShift = (float)Math.Sign(Vector3.Dot(d, centerLineBinormal)); float phi = (correctionShift * (float)Math.Acos(Vector3.Dot(d, centerLineNormal))) % (2.0f * (float)Math.PI); // Determine if the ray is inside the pie-slice of the cylinder that is being displayed, // otherwise discard: if (phi > StartAngle.GetValueAt(t) && phi < EndAngle.GetValueAt(t) && i >= 0.0f) { minimum = Math.Sign(i) * (float)Math.Min(Math.Abs(minimum), Math.Abs(i)); } } return(minimum); }
public override int GetHashCode() { unchecked { return((Location.GetHashCode() * 397) ^ (RadiusX.GetHashCode() * 397) ^ (RadiusY.GetHashCode() * 397) ^ (StartAngle.GetHashCode() * 397) ^ SweepAngle.GetHashCode()); } }
protected override void ExecuteCore(CarSignalInfo signalInfo) { if (!InitializedExamParms) { return; } //乱打灯不扣分,20160323,李 if (!IsOpenLeftIndicatorLight && signalInfo.Sensor.LeftIndicatorLight) { IsOpenLeftIndicatorLight = true; } //掉头打完左转向,在打右转向不扣分,20160323 if (!isSpeakIndicator && !IsOpenLeftIndicatorLight && CarSignalSet.Query(StartTime).Count(d => d.Sensor.RightIndicatorLight) >= Constants.ErrorSignalCount) { isSpeakIndicator = true; BreakRule(DeductionRuleCodes.RC40212); } //喇叭检测 if (signalInfo.Sensor.Loudspeaker) { IsLoudSpeakerCheck = true; } //检测远近光交替 if (Settings.TurnRoundLightCheck && !IsCheckedLowAndHighBeam) { IsCheckedLowAndHighBeam = signalInfo.Sensor.HighBeam; } if (StepState == TurnRoundStep.None) { //检测方向角是否开始调头 if (signalInfo.BearingAngle.IsValidAngle() && StartAngle.IsValidAngle() && !GeoHelper.IsBetweenDiffAngle(signalInfo.BearingAngle, StartAngle, Settings.TurnRoundStartAngleDiff)) { StepState = TurnRoundStep.StartTurnRound; } } else if (StepState == TurnRoundStep.StartTurnRound) { //开始掉头检测灯光 if (!IsCheckedTurnRoundLight) { IsCheckedTurnRoundLight = true; if (!CarSignalSet.Query(StartTime).Any(d => d.Sensor.LeftIndicatorLight)) { BreakRule(DeductionRuleCodes.RC41503); } else { //打了右转向灯进行评判 if (!IsOpenLeftIndicatorLight && CarSignalSet.Query(StartTime).Any(d => d.Sensor.RightIndicatorLight)) { BreakRule(DeductionRuleCodes.RC30205); return; } var isOk = AdvancedSignal.CheckOperationAheadSeconds(x => x.Sensor.LeftIndicatorLight, StartTime, Settings.TurnLightAheadOfTime); if (!isOk) { BreakRule(DeductionRuleCodes.RC30206, DeductionRuleCodes.SRC3020607); } } } //检测是否掉头完毕 if (signalInfo.BearingAngle.IsValidAngle() && StartAngle.IsValidAngle() && !GeoHelper.IsBetweenDiffAngle(signalInfo.BearingAngle, StartAngle, Settings.TurnRoundEndAngleDiff)) { if (Settings.TurnRoundBrakeRequired && !CarSignalSet.Query(StartTime).Any(x => x.Sensor.Brake)) { BreakRule(DeductionRuleCodes.RC41505); } StepState = TurnRoundStep.EndTurnRound; } } else { IsSuccess = true; return; //StopCore(); } base.ExecuteCore(signalInfo); }
/// <inheritdoc /> public double RayIntersect(Ray ray) { dvec3 rayStart = ray.StartPosition; dvec3 rayDirection = ray.Direction; DebugUtil.AssertAllFinite(rayStart, nameof(rayStart)); DebugUtil.AssertAllFinite(rayDirection, nameof(rayDirection)); // Since we raytrace only using a cylindrical surface that is horizontal and at the origin, we // first shift and rotate the ray such that we get the right orientation: dvec3 start = CenterCurve.GetStartPosition(); dvec3 end = CenterCurve.GetEndPosition(); DebugUtil.AssertAllFinite(start, nameof(start)); DebugUtil.AssertAllFinite(end, nameof(end)); dvec3 tangent = CenterCurve.GetTangentAt(0.0).Normalized; dvec3 normal = CenterCurve.GetNormalAt(0.0).Normalized; dvec3 binormal = CenterCurve.GetBinormalAt(0.0).Normalized; DebugUtil.AssertAllFinite(tangent, nameof(tangent)); DebugUtil.AssertAllFinite(normal, nameof(normal)); DebugUtil.AssertAllFinite(binormal, nameof(binormal)); double length = dvec3.Distance(start, end); DebugUtil.AssertFinite(length, nameof(length)); // CenterCurve is guaranteed to be a LineSegment, since the base property CenterCurve is masked by this // class' CenterCurve property that only accepts a LineSegment, and similarly this class' constructor only // accepts a LineSegment. The following mathematics, which assumes that the central axis is a line segment, // is therefore valid. dmat3 rotationMatrix = new dmat3(normal, binormal, tangent / length).Transposed; dvec3 rescaledRay = rotationMatrix * (rayStart - start); dvec3 newDirection = rotationMatrix * rayDirection.Normalized; double x0 = rescaledRay.x; double y0 = rescaledRay.y; double z0 = rescaledRay.z; double a = newDirection.x; double b = newDirection.y; double c = newDirection.z; // Raytrace using a cylindrical surface equation x^2 + y^2. The parameters in the following line // represent the coefficients of the expanded cylindrical surface equation, after the substitution // x = x_0 + a t and y = y_0 + b t: QuarticFunction surfaceFunction = new QuarticFunction(x0 * x0 + y0 * y0, 2.0 * (x0 * a + y0 * b), a * a + b * b, 0.0, 0.0); IEnumerable <double> intersections = Radius.SolveRaytrace(surfaceFunction, z0, c); // The previous function returns a list of intersection distances. The value closest to 0.0f represents the // closest intersection point. double minimum = Single.PositiveInfinity; foreach (double i in intersections) { // Calculate the 3d point at which the ray intersects the cylinder: dvec3 intersectionPoint = rayStart + i * rayDirection; // Find the closest point to the intersectionPoint on the centerLine. // Get the vector v from the start of the cylinder to the intersection point: dvec3 v = intersectionPoint - start; // ...And project this vector onto the center line: double t = -dvec3.Dot(intersectionPoint, tangent * length) / (length * length); // Now we have the parameter t on the surface of the SymmetricCylinder at which the ray intersects. // Find the angle to the normal of the centerLine, so that we can determine whether the // angle is within the bound of the pie-slice at position t: dvec3 centerLineNormal = CenterCurve.GetNormalAt(t); dvec3 centerLineBinormal = CenterCurve.GetBinormalAt(t); dvec3 d = intersectionPoint - CenterCurve.GetPositionAt(t); double correctionShift = Math.Sign(dvec3.Dot(d, centerLineBinormal)); double phi = (correctionShift * Math.Acos(dvec3.Dot(d, centerLineNormal))) % (2.0 * Math.PI); // Determine if the ray is inside the pie-slice of the cylinder that is being displayed, // otherwise discard: if (phi > StartAngle.GetValueAt(t) && phi < EndAngle.GetValueAt(t) && i >= 0.0) { minimum = Math.Sign(i) * Math.Min(Math.Abs(minimum), Math.Abs(i)); } } return(minimum); }
protected override void ExecuteCore(CarSignalInfo signalInfo) { if (!InitializedExamParms) { return; } //喇叭检测 if (signalInfo.Sensor.Loudspeaker) { IsLoudSpeakerCheck = true; } //检测远近光交替 if (Settings.TurnRoundLightCheck && !IsCheckedLowAndHighBeam) { IsCheckedLowAndHighBeam = signalInfo.Sensor.HighBeam; } //检测右转 if (Settings.TurnRoundErrorLight && !IsCheckedTurnRoundLight) { if (signalInfo.Sensor.RightIndicatorLight) { IsCheckedTurnRoundLight = true; CheckRule(true, DeductionRuleCodes.RC41503); } } ///停车不检测角度 if (signalInfo.CarState == CarState.Stop) { return; } if (StepState == TurnRoundStep.None) { //检测方向角是否开始调头 //Gps角度其实也是可以通过一些方法滤波的 if (signalInfo.BearingAngle.IsValidAngle() && StartAngle.IsValidAngle() && !GeoHelper.IsBetweenDiffAngle(signalInfo.BearingAngle, StartAngle, Settings.TurnRoundStartAngleDiff)) { StepState = TurnRoundStep.StartTurnRound; } } else if (StepState == TurnRoundStep.StartTurnRound) { //开始掉头检测灯光 if (!IsCheckedTurnRoundLight) { IsCheckedTurnRoundLight = true; if (!CarSignalSet.Query(StartTime).Any(d => d.Sensor.LeftIndicatorLight)) { CheckRule(true, DeductionRuleCodes.RC41503); } else { var isOk = AdvancedSignal.CheckOperationAheadSeconds(x => x.Sensor.LeftIndicatorLight, StartTime, Settings.TurnLightAheadOfTime); if (!isOk) { BreakRule(DeductionRuleCodes.RC30206, DeductionRuleCodes.SRC3020607); } } //// //if (CarSignalSet.Query(StartTime).Any(d => d.Sensor.RightIndicatorLight)) //{ // BreakRule(DeductionRuleCodes.RC30206); //} } //检测是否掉头完毕 if (signalInfo.BearingAngle.IsValidAngle() && StartAngle.IsValidAngle() && !GeoHelper.IsBetweenDiffAngle(signalInfo.BearingAngle, StartAngle, Settings.TurnRoundEndAngleDiff)) { if (Settings.TurnRoundBrakeRequired && !CarSignalSet.Query(StartTime).Any(x => x.Sensor.Brake)) { BreakRule(DeductionRuleCodes.RC41505); } StepState = TurnRoundStep.EndTurnRound; } } else { StopCore(); } base.ExecuteCore(signalInfo); }
public string ToString(string format, IFormatProvider formatProvider) { if (this == null) { return(nameof(Ellipse2D)); } var sep = ((formatProvider as CultureInfo) ?? CultureInfo.InvariantCulture).GetNumericListSeparator(); return($"{nameof(EllipticalArc2D)}({nameof(X)}: {X.ToString(format, formatProvider)}{sep} {nameof(Y)}: {Y.ToString(format, formatProvider)}{sep} {nameof(RadiusA)}: {RadiusA.ToString(format, formatProvider)}{sep} {nameof(RadiusB)}: {RadiusB.ToString(format, formatProvider)}{sep} {nameof(Angle)}: {Angle.ToString(format, formatProvider)}{sep} {nameof(StartAngle)}: {StartAngle.ToString(format, formatProvider)}{sep} {nameof(SweepAngle)}: {SweepAngle.ToString(format, formatProvider)})"); }
/// <inheritdoc /> public override List <Vertex> GenerateVertexList(int resolutionU, int resolutionV) { List <Vertex> output = new List <Vertex>(CalculateVertexCount(resolutionU, resolutionV)); for (int j = 0; j < (resolutionV + 1); j++) { float v = (float)j / (float)resolutionV; // Find the values at each ring: Vector3 curveTangent = Vector3.Normalize(CenterCurve.GetTangentAt(v)); Vector3 curveNormal = Vector3.Normalize(CenterCurve.GetNormalAt(v)); Vector3 curveBinormal = Vector3.Cross(curveTangent, curveNormal); Vector3 translation = CenterCurve.GetPositionAt(v); float startAngle = StartAngle.GetValueAt(v); float endAngle = EndAngle.GetValueAt(v); for (int i = 0; i < resolutionU; i++) { // First find the normalized uv-coordinates, u = [0, 2pi], v = [0, 1]: float u = startAngle + (endAngle - startAngle) * (float)i / (float)resolutionU; float radius = Radius.GetValueAt(new Vector2(u, v)); // Calculate the position of the rings of vertices: Vector3 surfaceNormal = (float)Math.Cos(u) * curveNormal + (float)Math.Sin(u) * curveBinormal; Vector3 surfacePosition = translation + radius * surfaceNormal; output.Add(new Vertex(surfacePosition, surfaceNormal)); } } // Recalculate the surface normal after deformation: for (int j = 1; j < resolutionV; j++) { for (int i = 0; i < (resolutionU - 1); i++) { Vector3 surfacePosition = output[(j - 1) * resolutionU + i].Position; Vector3 du = surfacePosition - output[(j - 1) * resolutionU + i + 1].Position; Vector3 dv = surfacePosition - output[(j) * resolutionU + i].Position; // Calculate the position of the rings of vertices: Vector3 surfaceNormal = Vector3.Cross(Vector3.Normalize(du), Vector3.Normalize(dv)); output[(j - 1) * resolutionU + i] = new Vertex(surfacePosition, surfaceNormal); } // Stitch the end of the triangles: Vector3 surfacePosition2 = output[(j - 1) * resolutionU + resolutionU - 1].Position; Vector3 du2 = surfacePosition2 - output[(j - 1) * resolutionU].Position; Vector3 dv2 = surfacePosition2 - output[(j) * resolutionU + resolutionU - 1].Position; // Calculate the position of the rings of vertices: Vector3 surfaceNormal2 = Vector3.Cross(Vector3.Normalize(du2), Vector3.Normalize(dv2)); output[(j - 1) * resolutionU + resolutionU - 1] = new Vertex(surfacePosition2, surfaceNormal2); } return(output); }
protected override void ExecuteCore(CarSignalInfo signalInfo) { //启用角度 if (Settings.PulloverAngle > 1 && CheckAngleLight && PullOverStepState < PullOverStep.StopCar) { if (signalInfo.BearingAngle.IsValidAngle() && StartAngle.IsValidAngle() && !GeoHelper.IsBetweenDiffAngle(signalInfo.BearingAngle, StartAngle, Settings.PulloverAngle)) { CheckAngleLight = false; if (CarSignalSet.Query(StartTime).Any(d => d.Sensor.LeftIndicatorLight) || !signalInfo.Sensor.RightIndicatorLight) { CheckRule(true, DeductionRuleCodes.RC40610); } else { var lastSignal = CarSignalSet.QueryCachedSeconds(Settings.TurnLightAheadOfTime).LastOrDefault(); if (lastSignal == null || !lastSignal.Sensor.RightIndicatorLight) { CheckRule(true, DeductionRuleCodes.RC40611); } } } } //如果车停了又继续走了,并且状态在结束 标识之前 充值状态 //要求是下车前 //if ((int)PullOverStepState >= (int)PullOverStep.StopCar && signalInfo.CarState != CarState.Stop && PullOverStepState != PullOverStep.CloseDoor && PullOverStepState != PullOverStep.CheckStop) //{ // PullOverStepState = PullOverStep.None; // _isTouchExteriorMirror = false; //} if ((int)PullOverStepState >= (int)PullOverStep.StopCar && !_isTouchExteriorMirror) { if (signalInfo.Sensor.ExteriorMirror) { _isTouchExteriorMirror = true; //...... //...... //...... //...... Speaker.PlayAudioAsync("观望镜确认"); } } if (PullOverStepState == PullOverStep.None) { if (signalInfo.Sensor.Handbrake) { PullOverStepState = PullOverStep.StopCar; StopCarTime = DateTime.Now; Messenger.Send(new EngineRuleMessage(false)); Logger.DebugFormat("{0}-关闭发动机熄火评判规则", Name); } //if (signalInfo.CarState == CarState.Stop) //{ // PullOverStepState = PullOverStep.StopCar; // StopCarTime = DateTime.Now; // Messenger.Send(new EngineRuleMessage(false)); // Logger.DebugFormat("{0}-关闭发动机熄火评判规则", Name); //} } else if (PullOverStepState == PullOverStep.StopCar) { //停车转向灯检查 停车前不使用或错误使用转向灯 PullOverStepState = PullOverStep.OpenPullOverLight; if (CarSignalSet.Query(StartTime).Any(d => d.Sensor.LeftIndicatorLight) || !signalInfo.Sensor.RightIndicatorLight) { CheckRule(true, DeductionRuleCodes.RC40610); } else { var lastSignal = CarSignalSet.QueryCachedSeconds(Settings.TurnLightAheadOfTime).LastOrDefault(); if (lastSignal == null || !lastSignal.Sensor.RightIndicatorLight) { CheckRule(true, DeductionRuleCodes.RC40611); } //var advancedSignal = Resolve<IAdvancedCarSignal>(); //var rightIndicator = AdvancedSignal.CheckOperationAheadSeconds(x => x.Sensor.RightIndicatorLight, StartTime, Settings.TurnLightAheadOfTime); //if (!rightIndicator) //{ // BreakRule(DeductionRuleCodes.RC40611); //} } } //开光车门之后再检查手刹 else if (PullOverStepState == PullOverStep.OpenPullOverLight) { CheckHandbrake(signalInfo); PullOverStepState = PullOverStep.PullHandbrake; } else if (PullOverStepState == PullOverStep.PullHandbrake) { //判断靠边停车是否结束 CheckEndMark(signalInfo); } else if (PullOverStepState == PullOverStep.CheckStop) { //if (signalInfo.Sensor.ExteriorMirror) //{ // _isTouchExteriorMirror = true; // Speaker.PlayAudioAsync("sanya/ExteriorMirror.wav", Infrastructure.Speech.SpeechPriority.Normal); //} //检测手刹 // if (!_isCheckedPulloverStop) { _isCheckedPulloverStop = true; CheckPullOverStop(signalInfo); } //如果结束标识 不是开关车门 if (!(Settings.PullOverEndMark == PullOverEndMark.None || Settings.PullOverEndMark == PullOverEndMark.OpenCloseDoorCheck)) { StopCore(); return; } if (!OpenDoorTime.HasValue) { OpenDoorTime = DateTime.Now; } if (!signalInfo.Sensor.Door) { PullOverStepState = PullOverStep.CloseDoor; Messenger.Send(new DoorChangedMessage(signalInfo.Sensor.Door)); StopCore(); return; } //在规定的时间内没有关闭车门 if (CloseDoorTimeOut()) { BreakRule(DeductionRuleCodes.RC40605); StopCore(); } } }
protected override void ExecuteCore(CarSignalInfo signalInfo) { //设置了变道角度后 //设置了变道 if (Constants.PullOverDistance == 0) { Constants.PullOverDistance = signalInfo.Distance; } if (Settings.PulloverAngle > 0.5 && signalInfo.BearingAngle.IsValidAngle() && StartAngle.IsValidAngle() && !GeoHelper.IsBetweenDiffAngle(signalInfo.BearingAngle, StartAngle, Settings.PulloverAngle)) { CheckRightIndicatorLight(); } if (Settings.PullOverEndMark == PullOverEndMark.OpenCloseDoorCheck && PullOverStepState < PullOverStep.StopCar && signalInfo.Sensor.Door) { if (!signalInfo.Sensor.Handbrake) { CheckRule(true, DeductionRuleCodes.RC40607, DeductionRuleCodes.SRC4060701); } CheckEndMark(signalInfo); } if (PullOverStepState == PullOverStep.None) { if ((signalInfo.CarState == CarState.Stop && Settings.PullOverMark == PullOverMark.CarStop) || (signalInfo.Sensor.Handbrake && Settings.PullOverMark == PullOverMark.Handbrake)) { PullOverStepState = PullOverStep.StopCar; StopCarTime = DateTime.Now; Messenger.Send(new EngineRuleMessage(false)); } } else if (PullOverStepState == PullOverStep.StopCar) { //停车转向灯检查 PullOverStepState = PullOverStep.OpenPullOverLight; CheckRightIndicatorLight(); } else if (PullOverStepState == PullOverStep.OpenPullOverLight) { CheckHandbrake(signalInfo); } else if (PullOverStepState == PullOverStep.PullHandbrake) { //判断靠边停车是否结束 CheckEndMark(signalInfo); } else if (PullOverStepState == PullOverStep.CheckStop) { if (!_isCheckedPulloverStop) { _isCheckedPulloverStop = true; CheckPullOverStop(signalInfo); } if (Settings.PullOverEndMark == PullOverEndMark.OpenDoorCheck) { StopCore(); return; } //true false if (!(Settings.PullOverEndMark == PullOverEndMark.None || Settings.PullOverEndMark == PullOverEndMark.OpenCloseDoorCheck)) { StopCore(); return; } if (!OpenDoorTime.HasValue) { OpenDoorTime = DateTime.Now; } //关车门 if (!signalInfo.Sensor.Door) { //海南版本特殊要求开关车门两次 if (DataBase.VersionNumber.Contains("海南")) { if (CloseDoorCount >= 2) { PullOverStepState = PullOverStep.CloseDoor; //关车门 Messenger.Send(new DoorChangedMessage(signalInfo.Sensor.Door)); StopCore(); return; } } else { PullOverStepState = PullOverStep.CloseDoor; //关车门 Messenger.Send(new DoorChangedMessage(signalInfo.Sensor.Door)); StopCore(); return; } } //在规定的时间内没有关闭车门 if (CloseDoorTimeOut()) { BreakRule(DeductionRuleCodes.RC40605); StopCore(); } } }
/// <summary></summary> /// <returns></returns> public override string ToString() { return(ToString("Center=" + Center.ToString("0.00") + ", StartAngle=" + StartAngle.ToString("0.0") + ", SweepAngle=" + SweepAngle.ToString("0.0"))); }
/// <inheritdoc /> public override List <Vertex> GenerateVertexList(int resolutionU, int resolutionV) { // If asked to sample at zero points, return an empty list. if (resolutionU <= 0 || resolutionV <= 0) { return(new List <Vertex>()); } var roughs = ParallelEnumerable.Range(0, resolutionV + 1).AsOrdered().SelectMany((j => { double v = (double)j / (double)resolutionV; // Find the values at each ring: dvec3 curveTangent = CenterCurve.GetTangentAt(v).Normalized; dvec3 curveNormal = CenterCurve.GetNormalAt(v).Normalized; dvec3 curveBinormal = dvec3.Cross(curveTangent, curveNormal); dvec3 translation = CenterCurve.GetPositionAt(v); double startAngle = StartAngle.GetValueAt(v); double endAngle = EndAngle.GetValueAt(v); return(Enumerable.Range(0, resolutionU).Select((i) => { double u = startAngle + (endAngle - startAngle) * (double)i / (double)resolutionU; double radius = Radius.GetValueAt(new dvec2(u, v)); // Calculate the position of the rings of vertices: dvec3 surfaceNormal = (double)Math.Cos(u) * curveNormal + (double)Math.Sin(u) * curveBinormal; dvec3 surfacePosition = translation + radius * surfaceNormal; return new Vertex((vec3)surfacePosition, (vec3)surfaceNormal); })); })); List <Vertex> output = roughs.ToList(); // Recalculate the surface normal after deformation: for (int j = 1; j < resolutionV; j++) { for (int i = 0; i < (resolutionU - 1); i++) { dvec3 surfacePosition = output[(j - 1) * resolutionU + i].Position; dvec3 du = surfacePosition - output[(j - 1) * resolutionU + i + 1].Position; dvec3 dv = surfacePosition - output[(j) * resolutionU + i].Position; // Calculate the position of the rings of vertices: dvec3 surfaceNormal = dvec3.Cross(du.Normalized, dv.Normalized); output[(j - 1) * resolutionU + i] = new Vertex((vec3)surfacePosition, (vec3)surfaceNormal); } // Stitch the end of the triangles: dvec3 surfacePosition2 = output[(j - 1) * resolutionU + resolutionU - 1].Position; dvec3 du2 = surfacePosition2 - output[(j - 1) * resolutionU].Position; dvec3 dv2 = surfacePosition2 - output[(j) * resolutionU + resolutionU - 1].Position; // Calculate the position of the rings of vertices: dvec3 surfaceNormal2 = dvec3.Cross(du2.Normalized, dv2.Normalized); output[(j - 1) * resolutionU + resolutionU - 1] = new Vertex((vec3)surfacePosition2, (vec3)surfaceNormal2); } return(output); }
protected override void ExecuteCore(CarSignalInfo signalInfo) { //设置了变道角度后 //todo:bug if (Settings.PulloverAngle > 0.5 && signalInfo.BearingAngle.IsValidAngle() && StartAngle.IsValidAngle() && !GeoHelper.IsBetweenDiffAngle(signalInfo.BearingAngle, StartAngle, Settings.PulloverAngle)) { CheckRightIndicatorLight(); } queueOpenDoor.Enqueue(signalInfo.Sensor.Door); if (queueOpenDoor.Count > 3) { queueOpenDoor.Dequeue(); } //有可能错误检测到了开门信号导致直接结束考试流程 //判断下是否停车肯定是停车状态下 //判断下最近 //if (Settings.PullOverEndMark == PullOverEndMark.OpenCloseDoorCheck && // //停车状态下至少是3个连续信号 // //保证OpenDoor都是开门信号 // //保证基本上是车停的时候 // PullOverStepState < PullOverStep.StopCar&& signalInfo.Sensor.SpeedInKmh<=1&& signalInfo.Sensor.Door&&queueOpenDoor.Where(s=>s==true).Count()>=2) //{ // //闪过一个信号后判断 // if(!signalInfo.Sensor.Handbrake) // CheckRule(true,DeductionRuleCodes.RC40607, DeductionRuleCodes.SRC4060701); // CheckEndMark(signalInfo); //} if (PullOverStepState == PullOverStep.None) { if ((signalInfo.CarState == CarState.Stop && Settings.PullOverMark == PullOverMark.CarStop) || (signalInfo.Sensor.Handbrake && Settings.PullOverMark == PullOverMark.Handbrake)) { if (signalInfo.Sensor.Handbrake) { Speaker.PlayAudioAsync("请下车", SpeechPriority.High); } PullOverStepState = PullOverStep.StopCar; StopCarTime = DateTime.Now; Messenger.Send(new EngineRuleMessage(false)); } } else if (PullOverStepState == PullOverStep.StopCar) { //停车转向灯检查 PullOverStepState = PullOverStep.OpenPullOverLight; CheckRightIndicatorLight(); } else if (PullOverStepState == PullOverStep.OpenPullOverLight) { CheckHandbrake(signalInfo); } else if (PullOverStepState == PullOverStep.PullHandbrake) { //判断靠边停车是否结束 CheckEndMark(signalInfo); } else if (PullOverStepState == PullOverStep.CheckStop) { if (!_isCheckedPulloverStop) { _isCheckedPulloverStop = true; CheckPullOverStop(signalInfo); } if (Settings.PullOverEndMark == PullOverEndMark.OpenDoorCheck) { StopCore(); return; } //true false if (!(Settings.PullOverEndMark == PullOverEndMark.None || Settings.PullOverEndMark == PullOverEndMark.OpenCloseDoorCheck)) { StopCore(); return; } if (!OpenDoorTime.HasValue) { OpenDoorTime = DateTime.Now; } //开车门维持3秒 if (OpenDoorTime.HasValue && (DateTime.Now - OpenDoorTime.Value).TotalSeconds > 3 && signalInfo.Sensor.Door && isCheckOverOpendoor == false) { isCheckOverOpendoor = true; Speaker.PlayAudioAsync("请下车", SpeechPriority.High); } if (!signalInfo.Sensor.Door && isCheckOverOpendoor) { PullOverStepState = PullOverStep.CloseDoor; Messenger.Send(new DoorChangedMessage(signalInfo.Sensor.Door)); StopCore(); return; } //在规定的时间内没有关闭车门 if (CloseDoorTimeOut() && isCheckOverOpendoor) { BreakRule(DeductionRuleCodes.RC40605); StopCore(); } } }