@@ -2066,6 +2066,7 @@ def link_collision_damper(
20662066 j = 0
20672067 Ain = None
20682068 bin = None
2069+ din = None
20692070
20702071 def indiv_calculation (link , link_col , q ):
20712072 d , wTlp , wTcp = link_col .closest_point (shape , di )
@@ -2074,22 +2075,30 @@ def indiv_calculation(link, link_col, q):
20742075 lpTcp = - wTlp + wTcp
20752076
20762077 norm = lpTcp / d
2078+ # norm = self.fkine(q, end=link, fast=True)[:3, :3] @ norm
20772079 norm_h = np .expand_dims (np .r_ [norm , 0 , 0 , 0 ], axis = 0 )
20782080
2079- Je = self .jacobe (
2080- q , start = self .base_link , end = link , tool = link_col .base .A , fast = True
2081+ tool = SE3 ((np .linalg .inv (self .fkine (q , end = link , fast = True )) @ SE3 (wTlp ).A )[:3 , 3 ])
2082+
2083+ Je = self .jacob0 (
2084+ q , end = link , tool = tool .A , fast = True
20812085 )
2086+ Je [:3 , :] = self ._base .A [:3 , :3 ] @ Je [:3 , :]
2087+
2088+
2089+ # print(Je)
2090+
20822091 n_dim = Je .shape [1 ]
20832092 dp = norm_h @ shape .v
2084- l_Ain = np .zeros ((1 , n ))
2093+ l_Ain = np .zeros ((1 , self . n ))
20852094 l_Ain [0 , :n_dim ] = norm_h @ Je
2086- l_bin = (xi * (d - ds ) / (di - ds )) + dp
2095+ l_bin = (xi * (d - ds ) / (di - ds )) + 0
20872096 else :
20882097 l_Ain = None
20892098 l_bin = None
20902099
20912100 return l_Ain , l_bin , d , wTcp
2092-
2101+
20932102 for link in links :
20942103 if link .isjoint :
20952104 j += 1
@@ -2113,8 +2122,256 @@ def indiv_calculation(link, link_col, q):
21132122 else :
21142123 bin = np .r_ [bin , l_bin ]
21152124
2125+ if din is None :
2126+ din = d
2127+ else :
2128+ din = np .r_ [din , d ]
2129+
21162130 return Ain , bin
21172131
2132+ def vision_collision_damper (
2133+ self ,
2134+ shape ,
2135+ q = None ,
2136+ di = 0.3 ,
2137+ ds = 0.05 ,
2138+ xi = 1.0 ,
2139+ end = None ,
2140+ start = None ,
2141+ collision_list = None ,
2142+ camera = None
2143+ ):
2144+ """
2145+ Formulates an inequality contraint which, when optimised for will
2146+ make it impossible for the robot to run into a collision. Requires
2147+ See examples/neo.py for use case
2148+ :param ds: The minimum distance in which a joint is allowed to
2149+ approach the collision object shape
2150+ :type ds: float
2151+ :param di: The influence distance in which the velocity
2152+ damper becomes active
2153+ :type di: float
2154+ :param xi: The gain for the velocity damper
2155+ :type xi: float
2156+ :param from_link: The first link to consider, defaults to the base
2157+ link
2158+ :type from_link: ELink
2159+ :param to_link: The last link to consider, will consider all links
2160+ between from_link and to_link in the robot, defaults to the
2161+ end-effector link
2162+ :type to_link: ELink
2163+ :returns: Ain, Bin as the inequality contraints for an omptimisor
2164+ :rtype: ndarray(6), ndarray(6)
2165+ """
2166+
2167+ if start is None :
2168+ start = self .base_link
2169+
2170+ if end is None :
2171+ end = self .ee_link
2172+
2173+ links , n , _ = self .get_path (start = start , end = end )
2174+
2175+ # if q is None:
2176+ # q = np.copy(self.q)
2177+ # else:
2178+ # q = getvector(q, n)
2179+
2180+ j = 0
2181+ Ain = None
2182+ bin = None
2183+ din = None
2184+
2185+ def indiv_calculation (link , link_col , q ):
2186+ d , wTlp , wTcp = link_col .closest_point (shape , di )
2187+
2188+ if d is not None :
2189+ lpTcp = - wTlp + wTcp
2190+
2191+ norm = lpTcp / d
2192+ norm_h = np .expand_dims (np .r_ [norm , 0 , 0 , 0 ], axis = 0 )
2193+
2194+ tool = SE3 ((np .linalg .inv (self .fkine (q , end = link , fast = True )) @ SE3 (wTlp ).A )[:3 , 3 ])
2195+
2196+ Je = self .jacob0 (
2197+ q , end = link , tool = tool .A , fast = True
2198+ )
2199+ Je [:3 , :] = self ._base .A [:3 , :3 ] @ Je [:3 , :]
2200+
2201+ wTc = camera .fkine (camera .q , fast = True )
2202+ Jv = camera .jacob0 (
2203+ camera .q , tool = SE3 (np .linalg .inv (wTc [:3 , :3 ]) @ (wTcp - wTc [:3 , - 1 ])).A , fast = True
2204+ )
2205+ Jv [:3 , :] = self ._base .A [:3 , :3 ] @ Jv [:3 , :]
2206+
2207+ n_dim = Je .shape [1 ]
2208+ dp = norm_h @ Jv
2209+ l_Ain = np .zeros ((1 , self .n + 2 + 10 ))
2210+ l_Ain [0 , :n_dim ] = norm_h @ Je
2211+ l_Ain -= np .r_ [dp [0 , :3 ], np .zeros (7 ), dp [0 , 3 :], np .zeros (9 ), 1 ]
2212+ l_bin = (xi * (d - ds ) / (di - ds ))
2213+ else :
2214+ l_Ain = None
2215+ l_bin = None
2216+
2217+ return l_Ain , l_bin , d , wTcp
2218+
2219+ for link in links :
2220+ if link .isjoint :
2221+ j += 1
2222+
2223+ if collision_list is None :
2224+ col_list = link .collision
2225+ else :
2226+ col_list = collision_list [j - 1 ]
2227+
2228+ for link_col in col_list :
2229+ l_Ain , l_bin , d , wTcp = indiv_calculation (link , link_col , q )
2230+
2231+ if l_Ain is not None and l_bin is not None :
2232+ if Ain is None :
2233+ Ain = l_Ain
2234+ else :
2235+ Ain = np .r_ [Ain , l_Ain ]
2236+
2237+ if bin is None :
2238+ bin = np .array (l_bin )
2239+ else :
2240+ bin = np .r_ [bin , l_bin ]
2241+
2242+ if din is None :
2243+ din = d
2244+ else :
2245+ din = np .r_ [din , d ]
2246+
2247+ return Ain , bin , din
2248+
2249+ def new_vision_collision_damper (
2250+ self ,
2251+ shape ,
2252+ q = None ,
2253+ di = 0.3 ,
2254+ ds = 0.05 ,
2255+ xi = 1.0 ,
2256+ end = None ,
2257+ start = None ,
2258+ collision_list = None ,
2259+ camera = None ,
2260+ obj = None
2261+ ):
2262+ """
2263+ Formulates an inequality contraint which, when optimised for will
2264+ make it impossible for the robot to run into a collision. Requires
2265+ See examples/neo.py for use case
2266+ :param ds: The minimum distance in which a joint is allowed to
2267+ approach the collision object shape
2268+ :type ds: float
2269+ :param di: The influence distance in which the velocity
2270+ damper becomes active
2271+ :type di: float
2272+ :param xi: The gain for the velocity damper
2273+ :type xi: float
2274+ :param from_link: The first link to consider, defaults to the base
2275+ link
2276+ :type from_link: ELink
2277+ :param to_link: The last link to consider, will consider all links
2278+ between from_link and to_link in the robot, defaults to the
2279+ end-effector link
2280+ :type to_link: ELink
2281+ :returns: Ain, Bin as the inequality contraints for an omptimisor
2282+ :rtype: ndarray(6), ndarray(6)
2283+ """
2284+
2285+ if start is None :
2286+ start = self .base_link
2287+
2288+ if end is None :
2289+ end = self .ee_link
2290+
2291+ links , n , _ = self .get_path (start = start , end = end )
2292+
2293+ # if q is None:
2294+ # q = np.copy(self.q)
2295+ # else:
2296+ # q = getvector(q, n)
2297+
2298+ j = 0
2299+ Ain = None
2300+ bin = None
2301+ din = None
2302+
2303+ def indiv_calculation (link , link_col , q ):
2304+ d , wTlp , wTcp = link_col .closest_point (shape , di )
2305+
2306+ if d is not None :
2307+ lpTcp = - wTlp + wTcp
2308+
2309+ norm = lpTcp / d
2310+
2311+ norm_e = self .fkine (q , end = link , fast = True )[:3 , :3 ] @ norm
2312+ norm_v = camera .fkine (camera .q , fast = True )[:3 , :3 ] @ norm
2313+
2314+ norm_e = np .expand_dims (np .r_ [norm_e , 0 , 0 , 0 ], axis = 0 )
2315+ norm_v = np .expand_dims (np .r_ [norm_v , 0 , 0 , 0 ], axis = 0 )
2316+
2317+ norm_h = np .expand_dims (np .r_ [norm , 0 , 0 , 0 ], axis = 0 )
2318+
2319+ tool = SE3 ((np .linalg .inv (self .fkine (q , end = link , fast = True )) @ SE3 (wTlp ).A )[:3 , 3 ])
2320+
2321+ Je = self .jacobe (
2322+ q , end = link , tool = tool .A , fast = True
2323+ )
2324+
2325+ Jv = camera .jacobe (camera .q , fast = True )
2326+
2327+ total_length = shape ._length
2328+ length = np .linalg .norm (wTcp - obj )
2329+ Jv *= length / total_length
2330+
2331+ n_dim = Je .shape [1 ]
2332+ dp = norm_v @ Jv
2333+ l_Ain = np .zeros ((1 , self .n + 2 + 10 ))
2334+ l_Ain [0 , :n_dim ] = norm_e @ Je
2335+ l_Ain -= np .r_ [dp [0 , :3 ], np .zeros (7 ), dp [0 , 3 :], np .zeros (9 ), 1 ]
2336+ l_bin = (xi * (d - ds ) / (di - ds ))
2337+
2338+ else :
2339+ l_Ain = None
2340+ l_bin = None
2341+
2342+ return l_Ain , l_bin , d , wTcp
2343+
2344+ for link in links :
2345+ if link .isjoint :
2346+ j += 1
2347+
2348+ if collision_list is None :
2349+ col_list = link .collision
2350+ else :
2351+ col_list = collision_list [j - 1 ]
2352+
2353+ for link_col in col_list :
2354+ l_Ain , l_bin , d , wTcp = indiv_calculation (link , link_col , q )
2355+
2356+ if l_Ain is not None and l_bin is not None :
2357+ if Ain is None :
2358+ Ain = l_Ain
2359+ else :
2360+ Ain = np .r_ [Ain , l_Ain ]
2361+
2362+ if bin is None :
2363+ bin = np .array (l_bin )
2364+ else :
2365+ bin = np .r_ [bin , l_bin ]
2366+
2367+ if din is None :
2368+ din = d
2369+ else :
2370+ din = np .r_ [din , d ]
2371+
2372+ return Ain , bin , din
2373+
2374+
21182375 # inverse dynamics (recursive Newton-Euler) using spatial vector notation
21192376 def rne (robot , q , qd , qdd , symbolic = False , gravity = None ):
21202377
0 commit comments