예제 #1
0
        public static IBodyRestriction DontTwistHipRestriction(int degreesThreshold = 15)
        {
            Z3Point3D up = new Z3Point3D(0, 1, 0);

            var result = new SimpleBodyRestriction(body =>
            {
                // Shoulders, hips and feet must be aligned
                Z3Point3D leftToRightShoulderVec = body.Joints[JointType.ShoulderLeft].GetInverted() + body.Joints[JointType.ShoulderRight];
                Z3Point3D leftToRightHipVec      = body.Joints[JointType.HipLeft].GetInverted() + body.Joints[JointType.HipRight];

                Z3Point3D leftAnklePosition =
                    body.Joints[JointType.HipLeft] +
                    body.Joints[JointType.KneeLeft] +
                    body.Joints[JointType.AnkleLeft];

                Z3Point3D rightAnklePosition =
                    body.Joints[JointType.HipRight] +
                    body.Joints[JointType.KneeRight] +
                    body.Joints[JointType.AnkleRight];

                Z3Point3D leftToRightAnkleVec = rightAnklePosition - leftAnklePosition;

                BoolExpr expr1 = leftToRightShoulderVec.IsDegreesBetweenLessThan(leftToRightHipVec, degreesThreshold);
                BoolExpr expr2 = leftToRightShoulderVec.IsDegreesBetweenLessThan(leftToRightAnkleVec, degreesThreshold);
                BoolExpr expr3 = leftToRightAnkleVec.IsDegreesBetweenLessThan(leftToRightHipVec, degreesThreshold);

                BoolExpr expr = Z3.Context.MkAnd(expr1, expr2, expr3);

                return(expr);
            },
                                                   body => { return(1.0); });

            return(result);
        }
예제 #2
0
        public static IBodyRestriction DontTwistHipRestriction(int angleThreshold = 15)
        {
            Z3Point3D up = new Z3Point3D(0, 1, 0);

            var result = new SimpleBodyRestriction(body =>
            {
                // Shoulders, hips and feet must be aligned
                Z3Point3D leftToRightShoulderVec = body.Joints[JointType.ShoulderLeft].GetInverted() + body.Joints[JointType.ShoulderRight];
                Z3Point3D leftToRightHipVec = body.Joints[JointType.HipLeft].GetInverted() + body.Joints[JointType.HipRight];

                Z3Point3D leftAnklePosition =
                    body.Joints[JointType.HipLeft] +
                    body.Joints[JointType.KneeLeft] +
                    body.Joints[JointType.AnkleLeft];

                Z3Point3D rightAnklePosition =
                    body.Joints[JointType.HipRight] +
                    body.Joints[JointType.KneeRight] +
                    body.Joints[JointType.AnkleRight];

                Z3Point3D leftToRightAnkleVec = rightAnklePosition - leftAnklePosition;

                BoolExpr expr1 = leftToRightShoulderVec.IsAngleBetweenLessThan(leftToRightHipVec, angleThreshold);
                BoolExpr expr2 = leftToRightShoulderVec.IsAngleBetweenLessThan(leftToRightAnkleVec, angleThreshold);
                BoolExpr expr3 = leftToRightAnkleVec.IsAngleBetweenLessThan(leftToRightHipVec, angleThreshold);

                BoolExpr expr = Z3.Context.MkAnd(expr1, expr2, expr3);

                return expr;
            });

            return result;
        }
예제 #3
0
        public static IBodyRestriction DistributeWeightRestriction(int angleThreshold = 15)
        {
            var result = new SimpleBodyRestriction(body =>
            {
                Z3Point3D up          = new Z3Point3D(0, 1, 0);
                Z3Point3D legLeft     = body.Joints[JointType.KneeLeft] + body.Joints[JointType.AnkleLeft];
                Z3Point3D legRight    = body.Joints[JointType.KneeRight] + body.Joints[JointType.AnkleRight];
                Z3Point3D legsAverage = (legLeft + legRight) / 2;

                BoolExpr expr = legsAverage.IsAngleBetweenLessThan(up, angleThreshold);

                return(expr);
            });

            return(result);
        }
예제 #4
0
        public static IBodyRestriction DistributeWeightRestriction(int angleThreshold = 15)
        {
            var result = new SimpleBodyRestriction(body =>
            {
                Z3Point3D up = new Z3Point3D(0, 1, 0);
                Z3Point3D legLeft = body.Joints[JointType.KneeLeft] + body.Joints[JointType.AnkleLeft];
                Z3Point3D legRight = body.Joints[JointType.KneeRight] + body.Joints[JointType.AnkleRight];
                Z3Point3D legsAverage = (legLeft + legRight) / 2;

                BoolExpr expr = legsAverage.IsAngleBetweenLessThan(up, angleThreshold);

                return expr;
            });

            return result;
        }
예제 #5
0
        // Therapy restrictions
        public static IBodyRestriction StraightPostureRestriction(int angleThreshold = 15)
        {
            Z3Point3D up = new Z3Point3D(0, 1, 0);

            double distanceThreshold = TrigonometryHelper.GetSine(angleThreshold);

            var result = new SimpleBodyRestriction(body =>
            {
                BoolExpr expr = body.Joints[JointType.SpineMid].IsNearerThan(up, distanceThreshold);
                expr          = Z3.Context.MkAnd(expr, body.Joints[JointType.SpineShoulder].IsNearerThan(up, distanceThreshold));
                expr          = Z3.Context.MkAnd(expr, body.Joints[JointType.Neck].IsNearerThan(up, distanceThreshold));
                expr          = Z3.Context.MkAnd(expr, body.Joints[JointType.Head].IsNearerThan(up, distanceThreshold));
                return(expr);
            });

            return(result);
        }
예제 #6
0
        public static IBodyRestriction ShouldersRelaxedRestriction(int angleThreshold = -5)
        {
            double maxY = TrigonometryHelper.GetSine(angleThreshold);

            var result = new SimpleBodyRestriction
                             (body =>
            {
                // Check if both shoulders have a lower Y than maxY
                BoolExpr expr1 = Z3.Context.MkLt(body.Joints[JointType.ShoulderLeft].Y, Z3Math.Real(maxY));
                BoolExpr expr2 = Z3.Context.MkLt(body.Joints[JointType.ShoulderRight].Y, Z3Math.Real(maxY));

                BoolExpr expr = Z3.Context.MkAnd(expr1, expr2);

                return(expr);
            });

            return(result);
        }
예제 #7
0
        public static IBodyRestriction ShouldersRelaxedRestriction(int angleThreshold = -5)
        {
            double maxY = TrigonometryHelper.GetSine(angleThreshold);

            var result = new SimpleBodyRestriction
                (body =>
                {
                    // Check if both shoulders have a lower Y than maxY
                    BoolExpr expr1 = Z3.Context.MkLt(body.Joints[JointType.ShoulderLeft].Y, Z3Math.Real(maxY));
                    BoolExpr expr2 = Z3.Context.MkLt(body.Joints[JointType.ShoulderRight].Y, Z3Math.Real(maxY));

                    BoolExpr expr = Z3.Context.MkAnd(expr1, expr2);

                    return expr;
                });

            return result;
        }
예제 #8
0
 public void And(SimpleBodyRestriction that)
 {
     this.Restrictions.Add(that);
 }
예제 #9
0
 public CompositeBodyRestriction(SimpleBodyRestriction soleBodyRestriction)
 {
     this.Restrictions = new List <SimpleBodyRestriction>();
     this.Restrictions.Add(soleBodyRestriction);
 }
예제 #10
0
        public static IBodyRestriction TestBodyRestriction()
        {
            var result = new SimpleBodyRestriction(body =>
            {
                double distanceThreshold = 0.4;

                ArithExpr distanceThresholdSquared = Z3Math.Real(distanceThreshold * distanceThreshold);

                ArithExpr x1 = body.Joints[JointType.SpineMid].X;
                ArithExpr y1 = body.Joints[JointType.SpineMid].Y;
                ArithExpr z1 = body.Joints[JointType.SpineMid].Z;

                ArithExpr x2 = Z3Math.Zero;
                ArithExpr y2 = Z3Math.One;
                ArithExpr z2 = Z3Math.Zero;

                //ArithExpr x2 = body.Joints[JointType.SpineBase].X;
                //ArithExpr y2 = body.Joints[JointType.SpineBase].Y;
                //ArithExpr z2 = body.Joints[JointType.SpineBase].Z;

                var xExpr = Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2));
                var yExpr = Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, y2));
                var zExpr = Z3Math.Mul(Z3Math.Sub(z1, z2), Z3Math.Sub(z1, z2));

                var distanceSquared = Z3Math.Add(xExpr, yExpr, zExpr);

                // This is runs fine
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), y2));

                // This runs fine
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, y1)));

                // This runs fine
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y2, y2)));

                // This runs fine
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Add(y1, y1)));

                // This runs fine
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Add(y1, y2)));

                // This runs fine
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Mul(y1, y2)));

                // This runs fine
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Add(y1, y2)));

                // But this does not
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Add(y1, y2), Z3Math.Add(y1, y2)));

                // This fine
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, Z3.Context.MkReal(0))));

                // This does not
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, Z3.Context.MkReal(1))));

                // This runs fine
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, Z3.Context.MkReal(1, 7))));

                // This runs fine
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Sub(y1, Z3.Context.MkReal(1, 6)), Z3Math.Sub(y1, Z3.Context.MkReal(1, 6))));

                // This runs fine
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Sub(y1, Z3.Context.MkReal(1, 3)), Z3Math.Sub(y1, Z3.Context.MkReal(1, 3))));

                // This does not
                // asserting: (x1 - 0)² + (y1 - 1/2)² <= 0.4²
                // which is x1² + y1² - y/2 - y/2 + 1/4 <= 0.16
                // which is x1² + y1² - y + 0.25 <= 0.16
                // which is x1² + y1² - y <= -0.09
                // if x1 = 0 and y1 = 0.1 we would have a solution
                // 0 + 0.01 - 0.1 <= 0.09
                // 0.09 <= 0.09
                // but z3 is taking too long to solve this.
                var addExpr = Z3Math.Add(
                    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                    Z3Math.Mul(Z3Math.Sub(y1, Z3.Context.MkReal(1, 2)), Z3Math.Sub(y1, Z3.Context.MkReal(1, 2))));

                // But this is not (Z3 just stops while solving it)
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, y2)));
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, y1)));

                //BoolExpr expr = Z3.Context.MkLt(distanceSquared, distanceThresholdSquared);
                BoolExpr expr = Z3.Context.MkLe(addExpr, distanceThresholdSquared);

                // Why it complains about this Greater-Than case?
                //BoolExpr expr = Z3.Context.MkGt(xExpr, distanceThresholdSquared);

                return(expr);
            },
                                                   body => { return(1.0); });

            return(result);
        }
예제 #11
0
 public CompositeBodyRestriction(SimpleBodyRestriction soleBodyRestriction)
 {
     this.Restrictions = new List<SimpleBodyRestriction>();
     this.Restrictions.Add(soleBodyRestriction);
 }
예제 #12
0
        /// <summary>
        /// This is a basic safety check to make sure we don't break any bones.
        /// </summary>
        /// <returns>True if safe</returns>
        public static CompositeBodyRestriction DefaultSafetyRestriction()
        {
            var result = new CompositeBodyRestriction();

            //int inclinationThreshold = 45;

            //// Head
            //// Make sure neck is not inclinated beyond the threshold
            //var head = new SimpleBodyRestriction(body =>
            //{
            //    Z3Point3D up = new Z3Point3D(0, 1, 0);
            //    BoolExpr expr1 = body.Joints[JointType.Head].IsDegreesBetweenLessThan(up, inclinationThreshold);
            //    BoolExpr expr2 = body.Joints[JointType.Neck].IsDegreesBetweenLessThan(up, inclinationThreshold);
            //    BoolExpr expr = Z3.Context.MkAnd(expr1, expr2);

            //    return expr;
            //},
            //body => { return 1.0; });
            //result.And(head);

            //// Spine
            //// Make sure spine is not inclinated beyond the threshold
            //var spine = new SimpleBodyRestriction(body =>
            //{
            //    Z3Point3D up = new Z3Point3D(0, 1, 0);
            //    BoolExpr expr1 = body.Joints[JointType.SpineMid].IsDegreesBetweenLessThan(up, inclinationThreshold);
            //    BoolExpr expr2 = body.Joints[JointType.SpineShoulder].IsDegreesBetweenLessThan(up, inclinationThreshold);
            //    BoolExpr expr3 =
            //        body.Joints[JointType.SpineMid].IsDegreesBetweenLessThan(
            //        body.Joints[JointType.SpineShoulder], inclinationThreshold);
            //    BoolExpr expr = Z3.Context.MkAnd(expr1, expr2, expr3);

            //    return expr;
            //},
            //body => { return 1.0; });
            //result.And(spine);

            //// Shoulders
            //// Make sure shoulders are not bent
            //var shoulders = new SimpleBodyRestriction(body =>
            //{
            //    BoolExpr expr =
            //        body.Joints[JointType.SpineMid].IsDegreesBetweenGreaterThan(
            //        body.Joints[JointType.SpineShoulder], 120);
            //    return expr;
            //},
            //body => { return 1.0; });
            //result.And(shoulders);

            // Elbows
            // Make sure elbows are not behind the back
            // And also that they are not on the top/back sub-space
            var elbows1 = new SimpleBodyRestriction(body =>
            {
                var joint1Position = body.GetJointZ3Position(JointType.ElbowRight);
                var joint2Position = body.GetJointZ3Position(JointType.ShoulderRight);
                BoolExpr expr      = Z3.Context.MkNot(Z3.Context.MkAnd(
                                                          Z3.Context.MkLt(joint1Position.Z, joint2Position.Z),
                                                          Z3.Context.MkGt(joint1Position.Y, joint2Position.Y)));
                return(expr);
            }, body => { return(1.0); },
                                                    "don't put your right elbow behind you and above your shoulders.\n");
            var elbows2 = new SimpleBodyRestriction(body =>
            {
                var joint1Position = body.GetJointZ3Position(JointType.ElbowLeft);
                var joint2Position = body.GetJointZ3Position(JointType.ShoulderLeft);
                BoolExpr expr      = Z3.Context.MkNot(Z3.Context.MkAnd(
                                                          Z3.Context.MkLt(joint1Position.Z, joint2Position.Z),
                                                          Z3.Context.MkGt(joint1Position.Y, joint2Position.Y)));
                return(expr);
            }, body => { return(1.0); },
                                                    "don't put your left elbow behind you and above your shoulders.\n");
            var elbows3 = new SimpleBodyRestriction(body =>
            {
                var joint1Position = body.GetJointZ3Position(JointType.ElbowRight);
                var joint2Position = body.GetJointZ3Position(JointType.ShoulderRight);
                BoolExpr expr      = Z3.Context.MkNot(Z3.Context.MkAnd(
                                                          Z3.Context.MkLt(joint1Position.Z, joint2Position.Z),
                                                          Z3.Context.MkLt(joint1Position.X, joint2Position.X)));
                return(expr);
            }, body => { return(1.0); },
                                                    "don't put your right elbow behind you crossing your back.\n");
            var elbows4 = new SimpleBodyRestriction(body =>
            {
                var joint1Position = body.GetJointZ3Position(JointType.ElbowLeft);
                var joint2Position = body.GetJointZ3Position(JointType.ShoulderLeft);
                BoolExpr expr      = Z3.Context.MkNot(Z3.Context.MkAnd(
                                                          Z3.Context.MkLt(joint1Position.Z, joint2Position.Z),
                                                          Z3.Context.MkGt(joint1Position.X, joint2Position.X)));
                return(expr);
            }, body => { return(1.0); },
                                                    "don't put your right elbow behind you crossing your back.\n");

            result.And(elbows1);
            result.And(elbows2);
            result.And(elbows3);
            result.And(elbows4);

            //// Wrists
            //// Make sure the inclination of wrists towards the back is not higher than the inclinatin of the elbows
            //// unless elbows are up or wrists are directed to torso
            //// TODO

            //// Hips
            //// Make sure hips are aligned with the shoulders or at lest within the range
            //var hips = new SimpleBodyRestriction(body =>
            //{
            //    Z3Point3D shouldersSum =
            //        body.Joints[JointType.ShoulderLeft].GetInverted() +
            //        body.Joints[JointType.ShoulderRight];

            //    Z3Point3D hipsSum =
            //        body.Joints[JointType.HipLeft].GetInverted() +
            //        body.Joints[JointType.HipRight];

            //    BoolExpr expr = shouldersSum.IsDegreesBetweenLessThan(hipsSum, 45);
            //    return expr;
            //},
            //body => { return 1.0; });
            //result.And(hips);

            // Legs
            // Make sure knees do not bent towards your back
            var knees1 = new SimpleBodyRestriction(body =>
            {
                var joint1Position = body.GetJointZ3Position(JointType.KneeLeft);
                var joint2Position = body.GetJointZ3Position(JointType.HipLeft);
                var joint3Position = body.GetJointZ3Position(JointType.AnkleLeft);
                BoolExpr expr      = Z3.Context.MkNot(Z3.Context.MkAnd(
                                                          Z3.Context.MkLt(joint1Position.Z, joint2Position.Z),
                                                          Z3.Context.MkLt(joint1Position.Z, joint3Position.Z)));
                return(expr);
            }, body => { return(1.0); },
                                                   "don't bend your left knee towards your back.\n");
            var knees2 = new SimpleBodyRestriction(body =>
            {
                var joint1Position = body.GetJointZ3Position(JointType.KneeRight);
                var joint2Position = body.GetJointZ3Position(JointType.HipRight);
                var joint3Position = body.GetJointZ3Position(JointType.AnkleRight);
                BoolExpr expr      = Z3.Context.MkNot(Z3.Context.MkAnd(
                                                          Z3.Context.MkLt(joint1Position.Z, joint2Position.Z),
                                                          Z3.Context.MkLt(joint1Position.Z, joint3Position.Z)));
                return(expr);
            }, body => { return(1.0); },
                                                   "don't bend your right knee towards your back.\n");

            result.And(knees1);
            result.And(knees2);

            // Ankles
            // Make sure ankles are not inclinated up more than knees
            // unless ankles are pointing back
            // TODO

            return(result);
        }
예제 #13
0
        public static IBodyRestriction TestBodyRestriction()
        {
            var result = new SimpleBodyRestriction(body =>
            {
                double distanceThreshold = 0.4;

                ArithExpr distanceThresholdSquared = Z3Math.Real(distanceThreshold * distanceThreshold);

                ArithExpr x1 = body.Joints[JointType.SpineMid].X;
                ArithExpr y1 = body.Joints[JointType.SpineMid].Y;
                ArithExpr z1 = body.Joints[JointType.SpineMid].Z;

                ArithExpr x2 = Z3Math.Zero;
                ArithExpr y2 = Z3Math.One;
                ArithExpr z2 = Z3Math.Zero;

                //ArithExpr x2 = body.Joints[JointType.SpineBase].X;
                //ArithExpr y2 = body.Joints[JointType.SpineBase].Y;
                //ArithExpr z2 = body.Joints[JointType.SpineBase].Z;

                var xExpr = Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2));
                var yExpr = Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, y2));
                var zExpr = Z3Math.Mul(Z3Math.Sub(z1, z2), Z3Math.Sub(z1, z2));

                var distanceSquared = Z3Math.Add(xExpr, yExpr, zExpr);

                // This is runs fine
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), y2));

                // This runs fine
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, y1)));

                // This runs fine
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y2, y2)));

                // This runs fine
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Add(y1, y1)));

                // This runs fine
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Add(y1, y2)));

                // This runs fine
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Mul(y1, y2)));

                // This runs fine
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Add(y1, y2)));

                // But this does not
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Add(y1, y2), Z3Math.Add(y1, y2)));

                // This fine
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, Z3.Context.MkReal(0))));

                // This does not
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, Z3.Context.MkReal(1))));

                // This runs fine
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, Z3.Context.MkReal(1, 7))));

                // This runs fine
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Sub(y1, Z3.Context.MkReal(1, 6)), Z3Math.Sub(y1, Z3.Context.MkReal(1, 6))));

                // This runs fine
                //var addExpr = Z3Math.Add(
                //    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                //    Z3Math.Mul(Z3Math.Sub(y1, Z3.Context.MkReal(1, 3)), Z3Math.Sub(y1, Z3.Context.MkReal(1, 3))));

                // This does not
                // asserting: (x1 - 0)² + (y1 - 1/2)² <= 0.4²
                // which is x1² + y1² - y/2 - y/2 + 1/4 <= 0.16
                // which is x1² + y1² - y + 0.25 <= 0.16
                // which is x1² + y1² - y <= -0.09
                // if x1 = 0 and y1 = 0.1 we would have a solution
                // 0 + 0.01 - 0.1 <= 0.09
                // 0.09 <= 0.09
                // but z3 is taking too long to solve this.
                var addExpr = Z3Math.Add(
                    Z3Math.Mul(Z3Math.Sub(x1, x2), Z3Math.Sub(x1, x2)),
                    Z3Math.Mul(Z3Math.Sub(y1, Z3.Context.MkReal(1, 2)), Z3Math.Sub(y1, Z3.Context.MkReal(1, 2))));

                // But this is not (Z3 just stops while solving it)
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, y2)));
                //var addExpr = Z3Math.Add(xExpr, Z3Math.Mul(Z3Math.Sub(y1, y2), Z3Math.Sub(y1, y1)));

                //BoolExpr expr = Z3.Context.MkLt(distanceSquared, distanceThresholdSquared);
                BoolExpr expr = Z3.Context.MkLe(addExpr, distanceThresholdSquared);

                // Why it complains about this Greater-Than case?
                //BoolExpr expr = Z3.Context.MkGt(xExpr, distanceThresholdSquared);

                return expr;
            });

            return result;
        }
예제 #14
0
        // Therapy restrictions
        public static IBodyRestriction StraightPostureRestriction(int angleThreshold = 15)
        {
            Z3Point3D up = new Z3Point3D(0, 1, 0);

            double distanceThreshold = TrigonometryHelper.GetSine(angleThreshold);

            var result = new SimpleBodyRestriction(body =>
            {
                BoolExpr expr = body.Joints[JointType.SpineMid].IsNearerThan(up, distanceThreshold);
                expr = Z3.Context.MkAnd(expr, body.Joints[JointType.SpineShoulder].IsNearerThan(up, distanceThreshold));
                expr = Z3.Context.MkAnd(expr, body.Joints[JointType.Neck].IsNearerThan(up, distanceThreshold));
                expr = Z3.Context.MkAnd(expr, body.Joints[JointType.Head].IsNearerThan(up, distanceThreshold));
                return expr;
            });

            return result;
        }
예제 #15
0
 public void And(SimpleBodyRestriction that)
 {
     this.Restrictions.Add(that);
 }
예제 #16
0
        /// <summary>
        /// This is a basic safety check to make sure we don't break any bones.
        /// </summary>
        /// <returns>True if safe</returns>
        public static IBodyRestriction DefaultSafetyRestriction()
        {
            var result = new CompositeBodyRestriction();

            int inclinationThreshold = 45;

            // Head
            // Make sure neck is not inclinated beyond the threshold
            var head = new SimpleBodyRestriction(body =>
            {
                Z3Point3D up   = new Z3Point3D(0, 1, 0);
                BoolExpr expr1 = body.Joints[JointType.Head].IsAngleBetweenLessThan(up, inclinationThreshold);
                BoolExpr expr2 = body.Joints[JointType.Neck].IsAngleBetweenLessThan(up, inclinationThreshold);
                BoolExpr expr  = Z3.Context.MkAnd(expr1, expr2);

                return(expr);
            });

            result.And(head);

            // Spine
            // Make sure spine is not inclinated beyond the threshold
            var spine = new SimpleBodyRestriction(body =>
            {
                Z3Point3D up   = new Z3Point3D(0, 1, 0);
                BoolExpr expr1 = body.Joints[JointType.SpineMid].IsAngleBetweenLessThan(up, inclinationThreshold);
                BoolExpr expr2 = body.Joints[JointType.SpineShoulder].IsAngleBetweenLessThan(up, inclinationThreshold);
                BoolExpr expr3 =
                    body.Joints[JointType.SpineMid].IsAngleBetweenLessThan(
                        body.Joints[JointType.SpineShoulder], inclinationThreshold);
                BoolExpr expr = Z3.Context.MkAnd(expr1, expr2, expr3);

                return(expr);
            });

            result.And(spine);

            // Shoulders
            // Make sure shoulders are not bent
            var shoulders = new SimpleBodyRestriction(body =>
            {
                BoolExpr expr =
                    body.Joints[JointType.SpineMid].IsAngleBetweenGreaterThan(
                        body.Joints[JointType.SpineShoulder], 120);

                return(expr);
            });

            result.And(shoulders);

            // Elbows
            // Make sure elbows are not behind the back
            // And also that they are not on the top/back sub-space
            var elbows = new SimpleBodyRestriction(body =>
            {
                BoolExpr exprRight1 =
                    Z3.Context.MkNot(
                        Z3.Context.MkAnd(
                            Z3.Context.MkLt(body.Joints[JointType.ElbowRight].Z, Z3Math.Zero),
                            Z3.Context.MkLt(body.Joints[JointType.ElbowRight].X, Z3Math.Zero)));

                BoolExpr exprRight2 =
                    Z3.Context.MkNot(
                        Z3.Context.MkAnd(
                            Z3.Context.MkLt(body.Joints[JointType.ElbowRight].Z, Z3Math.Zero),
                            Z3.Context.MkGt(body.Joints[JointType.ElbowRight].Y, Z3Math.Zero)));

                BoolExpr exprLeft1 =
                    Z3.Context.MkNot(
                        Z3.Context.MkAnd(
                            Z3.Context.MkLt(body.Joints[JointType.ElbowLeft].Z, Z3Math.Zero),
                            Z3.Context.MkGt(body.Joints[JointType.ElbowLeft].X, Z3Math.Zero)));

                BoolExpr exprLeft2 =
                    Z3.Context.MkNot(
                        Z3.Context.MkAnd(
                            Z3.Context.MkLt(body.Joints[JointType.ElbowLeft].Z, Z3Math.Zero),
                            Z3.Context.MkGt(body.Joints[JointType.ElbowLeft].Y, Z3Math.Zero)));

                BoolExpr expr = Z3.Context.MkAnd(exprLeft1, exprLeft2, exprRight1, exprRight2);

                return(expr);
            });

            result.And(elbows);

            // Wrists
            // Make sure the inclination of wrists towards the back is not higher than the inclinatin of the elbows
            // unless elbows are up or wrists are directed to torso
            // TODO

            // Hips
            // Make sure hips are aligned with the shoulders or at lest within the range
            var hips = new SimpleBodyRestriction(body =>
            {
                Z3Point3D shouldersSum =
                    body.Joints[JointType.ShoulderLeft].GetInverted() +
                    body.Joints[JointType.ShoulderRight];

                Z3Point3D hipsSum =
                    body.Joints[JointType.HipLeft].GetInverted() +
                    body.Joints[JointType.HipRight];

                BoolExpr expr = shouldersSum.IsAngleBetweenLessThan(hipsSum, 45);
                return(expr);
            });

            result.And(hips);

            // Legs
            // Make sure legs are not higher than threshold
            var legs = new SimpleBodyRestriction(body =>
            {
                BoolExpr expr1 = Z3.Context.MkLt(body.Joints[JointType.KneeLeft].Y, Z3Math.Real(0));
                BoolExpr expr2 = Z3.Context.MkLt(body.Joints[JointType.KneeRight].Y, Z3Math.Real(0));
                BoolExpr expr  = Z3.Context.MkAnd(expr1, expr2);

                return(expr);
            });

            result.And(legs);

            // Ankles
            // Make sure ankles are not inclinated up more than knees
            // unless ankles are pointing back
            // TODO

            return(result);
        }
예제 #17
0
파일: Safety.cs 프로젝트: lsfcin/prepose
        /// <summary>
        /// This is a basic safety check to make sure we don't break any bones.
        /// </summary>
        /// <returns>True if safe</returns>
        public static IBodyRestriction DefaultSafetyRestriction()
        {
            var result = new CompositeBodyRestriction();

            int inclinationThreshold = 45;

            // Head
            // Make sure neck is not inclinated beyond the threshold
            var head = new SimpleBodyRestriction(body =>
            {
                Z3Point3D up = new Z3Point3D(0, 1, 0);
                BoolExpr expr1 = body.Joints[JointType.Head].IsDegreesBetweenLessThan(up, inclinationThreshold);
                BoolExpr expr2 = body.Joints[JointType.Neck].IsDegreesBetweenLessThan(up, inclinationThreshold);
                BoolExpr expr = Z3.Context.MkAnd(expr1, expr2);

                return expr;
            },
            body => { return 1.0; });
            result.And(head);

            // Spine
            // Make sure spine is not inclinated beyond the threshold
            var spine = new SimpleBodyRestriction(body =>
            {
                Z3Point3D up = new Z3Point3D(0, 1, 0);
                BoolExpr expr1 = body.Joints[JointType.SpineMid].IsDegreesBetweenLessThan(up, inclinationThreshold);
                BoolExpr expr2 = body.Joints[JointType.SpineShoulder].IsDegreesBetweenLessThan(up, inclinationThreshold);
                BoolExpr expr3 =
                    body.Joints[JointType.SpineMid].IsDegreesBetweenLessThan(
                    body.Joints[JointType.SpineShoulder], inclinationThreshold);
                BoolExpr expr = Z3.Context.MkAnd(expr1, expr2, expr3);

                return expr;
            },
            body => { return 1.0; });
            result.And(spine);

            // Shoulders
            // Make sure shoulders are not bent
            var shoulders = new SimpleBodyRestriction(body =>
            {
                BoolExpr expr =
                    body.Joints[JointType.SpineMid].IsDegreesBetweenGreaterThan(
                    body.Joints[JointType.SpineShoulder], 120);

                return expr;
            },
            body => { return 1.0; });
            result.And(shoulders);

            // Elbows
            // Make sure elbows are not behind the back
            // And also that they are not on the top/back sub-space
            var elbows = new SimpleBodyRestriction(body =>
            {
                BoolExpr exprRight1 =
                    Z3.Context.MkNot(
                    Z3.Context.MkAnd(
                    Z3.Context.MkLt(body.Joints[JointType.ElbowRight].Z, Z3Math.Zero),
                    Z3.Context.MkLt(body.Joints[JointType.ElbowRight].X, Z3Math.Zero)));

                BoolExpr exprRight2 =
                    Z3.Context.MkNot(
                    Z3.Context.MkAnd(
                    Z3.Context.MkLt(body.Joints[JointType.ElbowRight].Z, Z3Math.Zero),
                    Z3.Context.MkGt(body.Joints[JointType.ElbowRight].Y, Z3Math.Zero)));

                BoolExpr exprLeft1 =
                    Z3.Context.MkNot(
                    Z3.Context.MkAnd(
                    Z3.Context.MkLt(body.Joints[JointType.ElbowLeft].Z, Z3Math.Zero),
                    Z3.Context.MkGt(body.Joints[JointType.ElbowLeft].X, Z3Math.Zero)));

                BoolExpr exprLeft2 =
                    Z3.Context.MkNot(
                    Z3.Context.MkAnd(
                    Z3.Context.MkLt(body.Joints[JointType.ElbowLeft].Z, Z3Math.Zero),
                    Z3.Context.MkGt(body.Joints[JointType.ElbowLeft].Y, Z3Math.Zero)));

                BoolExpr expr = Z3.Context.MkAnd(exprLeft1, exprLeft2, exprRight1, exprRight2);

                return expr;
            },
            body => { return 1.0; });
            result.And(elbows);

            // Wrists
            // Make sure the inclination of wrists towards the back is not higher than the inclinatin of the elbows
            // unless elbows are up or wrists are directed to torso
            // TODO

            // Hips
            // Make sure hips are aligned with the shoulders or at lest within the range
            var hips = new SimpleBodyRestriction(body =>
            {
                Z3Point3D shouldersSum =
                    body.Joints[JointType.ShoulderLeft].GetInverted() +
                    body.Joints[JointType.ShoulderRight];

                Z3Point3D hipsSum =
                    body.Joints[JointType.HipLeft].GetInverted() +
                    body.Joints[JointType.HipRight];

                BoolExpr expr = shouldersSum.IsDegreesBetweenLessThan(hipsSum, 45);
                return expr;
            },
            body => { return 1.0; });
            result.And(hips);

            // Legs
            // Make sure legs are not higher than threshold
            var legs = new SimpleBodyRestriction(body =>
            {
                BoolExpr expr1 = Z3.Context.MkLt(body.Joints[JointType.KneeLeft].Y, Z3Math.Real(0));
                BoolExpr expr2 = Z3.Context.MkLt(body.Joints[JointType.KneeRight].Y, Z3Math.Real(0));
                BoolExpr expr = Z3.Context.MkAnd(expr1, expr2);

                return expr;
            },
            body => { return 1.0; });
            result.And(legs);

            // Ankles
            // Make sure ankles are not inclinated up more than knees
            // unless ankles are pointing back
            // TODO

            return result;
        }