예제 #1
0
    public static DubinInput LSRInput(List <Pair <Vector2, Vector2> > LRTangents, Circle agentLeft, Circle queryRight)
    {
        DubinInput next = new DubinInput();

        DubinInput.Steer nextInput;

        if (LRTangents.Count > 3)
        {
            double arc1, arc2, arc3;
            // L
            arc1      = ArcLength(agentLeft.pos, start.pos, LRTangents[3].first, r1, true);
            nextInput = new DubinInput.Steer(start.v, (float)o1, (float)(arc1 / start.v));
            next.steer.Add(nextInput);
            // S
            arc2      = (LRTangents[3].first - LRTangents[3].second).magnitude;
            nextInput = new DubinInput.Steer(MAX_SPEED, 0, (float)(arc2 / MAX_SPEED));
            if (constAcc)
            {
                var at = computeAT(arc2, start.v, goal.v);
                nextInput = new DubinInput.Steer(start.v, 0, (float)at.second, (float)at.first);
            }
            next.steer.Add(nextInput);
            // R
            arc3      = ArcLength(queryRight.pos, LRTangents[3].second, goal.pos, r2, false);
            nextInput = new DubinInput.Steer(goal.v, (float)-o2, (float)(arc3 / goal.v));
            next.steer.Add(nextInput);
            next.updateTime();
        }
        return(next);
    }
예제 #2
0
    public static DubinInput bestCSCInput(Circle agentLeft, Circle agentRight, Circle queryLeft, Circle queryRight)
    {
        List <Pair <Vector2, Vector2> > RRTangents = TangentLines(agentRight, queryRight);
        List <Pair <Vector2, Vector2> > LLTangents = TangentLines(agentLeft, queryLeft);
        List <Pair <Vector2, Vector2> > RLTangents = TangentLines(agentRight, queryLeft);
        List <Pair <Vector2, Vector2> > LRTangents = TangentLines(agentLeft, queryRight);

        DubinInput best = new DubinInput(), next;

        next = RSRInput(RRTangents, agentRight, queryRight);
        if (next.time < best.time)
        {
            best = next;
        }
        next = LSLInput(LLTangents, agentLeft, queryLeft);
        if (next.time < best.time)
        {
            best = next;
        }
        next = RSLInput(RLTangents, agentRight, queryLeft);
        if (next.time < best.time)
        {
            best = next;
        }
        next = LSRInput(LRTangents, agentLeft, queryRight);
        if (next.time < best.time)
        {
            best = next;
        }
        return(best);
    }
    bool pathFeasible(DubinNode from, DubinNode to, DubinInput input)
    {
        // TODO: check for max condition
        foreach (DubinInput.Steer steer in input.steer)
        {
            if (Mathf.Abs(steer.a) > MAX_ACCEL)
            {
                return(false);
            }
        }
        var dubinsCollision = DDrive.dubinsTransition(true, null, from, to, input);

        return(dubinsCollision);
    }
예제 #4
0
    public static DubinInput DubinSP(DubinState start, DubinState goal, bool constAcc = false)
    {
        DubinUtils.constAcc = constAcc;

        DubinUtils.start = start;
        DubinUtils.goal  = goal;

        DubinUtils.o1 = start.omega;
        DubinUtils.o2 = goal.omega;

        DubinUtils.r1 = start.v / o1;
        DubinUtils.r2 = goal.v / o2;

        Circle agentLeft;
        Circle agentRight;
        Circle queryLeft;
        Circle queryRight;

        double theta = start.theta;

        theta += Math.PI / 2.0;
        if (theta > Math.PI)
        {
            theta -= 2.0 * Math.PI;
        }

        agentLeft = new Circle(start.pos.x + r1 * Math.Cos(theta), start.pos.y + r1 * Math.Sin(theta), r1);

        theta  = start.theta;
        theta -= Math.PI / 2.0;

        if (theta < -Math.PI)
        {
            theta += 2.0 * Math.PI;
        }

        agentRight = new Circle(start.pos.x + r1 * Math.Cos(theta), start.pos.y + r1 * Math.Sin(theta), r1);

        theta  = goal.theta;
        theta += Math.PI / 2.0;

        if (theta > Math.PI)
        {
            theta -= 2.0 * Math.PI;
        }

        queryLeft = new Circle(goal.pos.x + r2 * Math.Cos(theta), goal.pos.y + r2 * Math.Sin(theta), r2);

        theta  = goal.theta;
        theta -= Math.PI / 2.0;

        if (theta < -Math.PI)
        {
            theta += 2.0 * Math.PI;
        }

        queryRight = new Circle(goal.pos.x + r2 * Math.Cos(theta), goal.pos.y + r2 * Math.Sin(theta), r2);

        DubinInput bestCSC = bestCSCInput(agentLeft, agentRight, queryLeft, queryRight);
//        DubinInput bestCCC = bestCCCInput(agentLeft, agentRight, queryLeft, queryRight);
//        DubinInput shortest = bestCCC.time > bestCSC.time ? bestCSC : bestCCC;
        DubinInput shortest = bestCSC;

        return(shortest);
    }
예제 #5
0
    public static DubinInput bestCCCInput(Circle agentLeft, Circle agentRight, Circle queryLeft, Circle queryRight)
    {
        DubinInput best = new DubinInput();

        return(best);
    }
    /*
     * dubins transition function, multiple uses
     * 1. if collision param is true: check for collision, will return bool
     * 2. else: put interpolated nodes into list
     */

    public static bool dubinsTransition(bool collision, List <Node> list, DubinNode from, DubinNode to, DubinInput input)
    {
        DubinNode prev = from;
        double    tx = from.pos.x, ty = from.pos.y, ttheta = from.theta; // HACK: to improve precision

        foreach (DubinInput.Steer steer in input.steer)
        {
            float  sumT = 0;
            double v    = steer.v;
            while (sumT < steer.time)
            {
                var dt = Mathf.Min(DELTA_T, steer.time);
                tx = tx + dt * v * Math.Cos(prev.theta);
                ty = ty + dt * v * Math.Sin(prev.theta);
                var pos = new Vector2((float)tx, (float)ty);
                v     += dt * steer.a;
                ttheta = ttheta + dt * steer.omega;
                while (ttheta > 2 * Mathf.PI)
                {
                    ttheta -= 2 * Mathf.PI;
                }
                while (ttheta < 0)
                {
                    ttheta += 2 * Mathf.PI;
                }
                if (collision && !Cheetah.instance.IsValid(pos))
                {
                    return(false);
                }
                DubinNode nextPoint = new DubinNode(pos, steer.v, (float)ttheta, steer.omega, prev.time + dt);
                if (!collision)
                {
                    list.Add(nextPoint);
                }
//                if ((nextPoint.pos - prev.pos).magnitude > 0.5) // TODO: debug
//                {
//                    Debug.Log("WTF");
//                    dubinInput(from, to);
//                    return false;
//                }
                prev  = nextPoint;
                sumT += dt;
            }
        }
//        // TODO: debug
//        if ((prev.pos - to.pos).magnitude > 0.5 || Mathf.Abs(prev.theta - to.theta) > 0.3)
//        {
//            Debug.Log("WTF");
//            dubinInput(from, to);
//            return false;
//        }
        return(true);
    }