Beispiel #1
0
        /// <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();
            }
        }
Beispiel #2
0
        /// <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();
            }
        }
Beispiel #3
0
        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());
        }
Beispiel #4
0
        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;
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
        /// <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);
        }
Beispiel #8
0
        /// <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());
            }
        }
Beispiel #9
0
        /// <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());
     }
 }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        /// <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);
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        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)})");
        }
Beispiel #15
0
        /// <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);
        }
Beispiel #16
0
        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();
                }
            }
        }
Beispiel #17
0
        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")));
 }
Beispiel #19
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);
        }
Beispiel #20
0
        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();
                }
            }
        }