# Objective: linear # Constraints: convex epsilon-second-order cone # Feasible set: convex # This model finds the smallest amount of normal force required # to "grasp" an object given a set of possible grasping points. # # Reference: "Applications of Second-Order Cone Programming", # M.S. Lobo, L. Vandenberghe, S. Boyd, and H. Lebret, 1998 param pi := 4*atan(1); param n := 5; # number of lifting points param mu := 0.3; # coeff. of friction # p = (p1,p2,p3) is a contact point on a parabolic "nose cone" to be lifted param p1 {j in 1..n} := 0.3 + cos(2*pi*j/n); param p2 {j in 1..n} := sin(2*pi*j/n); param p3 {j in 1..n} := p1[j]^2 + p2[j]^2; # v = (v1,v2,v3) is the unit normal vector at contact point p = (p1,p2,p3) param grad_norm {j in 1..n} := sqrt( (2*p1[j])^2 + (2*p2[j])^2 + 1); param v1 {j in 1..n} := -2*p1[j]/grad_norm[j]; param v2 {j in 1..n} := -2*p2[j]/grad_norm[j]; param v3 {j in 1..n} := 1/grad_norm[j]; # external applied force param f1_ext := 0; param f2_ext := 0; param f3_ext := -1; # external applied torque param torq1_ext := 0; param torq2_ext := 0; param torq3_ext := 0; # f = (f1,f2,f3) is the contact force at point p = (p1,p2,p3) var f1 {j in 1..n}; var f2 {j in 1..n}; var f3 {j in 1..n}; # nf is the normal force at point p = (p1,p2,p3) var nf {j in 1..n} = v1[j]*f1[j] + v2[j]*f2[j] + v3[j]*f3[j]; # tf = (tf1,tf2,tf3) is the tangential force at point p = (p1,p2,p3) var tf1 {j in 1..n} = f1[j] - v1[j]*nf[j]; var tf2 {j in 1..n} = f2[j] - v2[j]*nf[j]; var tf3 {j in 1..n} = f3[j] - v3[j]*nf[j]; # torq = (torq1,torq2,torq3) is the torq about (0,0,0) at point p = (p1,p2,p3) var torq1 {j in 1..n} = p2[j]*f3[j] - f2[j]*p3[j]; var torq2 {j in 1..n} = f1[j]*p3[j] - p1[j]*f3[j]; var torq3 {j in 1..n} = p1[j]*f2[j] - f1[j]*p2[j]; var t; # an upper bound on the normal contact force minimize pressure: t; subject to t_bnds {j in 1..n}: nf[j] <= t; subject to friction {j in 1..n}: sqrt(tf1[j]^2 + tf2[j]^2 + tf3[j]^2) <= mu*nf[j]; subject to f_balance1: sum {j in 1..n} f1[j] = -f1_ext; subject to f_balance2: sum {j in 1..n} f2[j] = -f2_ext; subject to f_balance3: sum {j in 1..n} f3[j] = -f3_ext; subject to t_balance1: sum {j in 1..n} torq1[j] = -torq1_ext; subject to t_balance2: sum {j in 1..n} torq2[j] = -torq2_ext; subject to t_balance3: sum {j in 1..n} torq3[j] = -torq3_ext; let {j in 1..n} f1[j] := 1; let {j in 1..n} f2[j] := 1; let {j in 1..n} f3[j] := 1; solve; display f1, f2, f3;