PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/python/m3/toolbox.py

https://bitbucket.org/ensta/m3meka
Python | 286 lines | 255 code | 11 blank | 20 comment | 24 complexity | b3eaea9c87440301b4a684fd39e16907 MD5 | raw file
  1. #M3 -- Meka Robotics Robot Components
  2. #Copyright (c) 2010 Meka Robotics
  3. #Author: edsinger@mekabot.com (Aaron Edsinger)
  4. #M3 is free software: you can redistribute it and/or modify
  5. #it under the terms of the GNU Lesser General Public License as published by
  6. #the Free Software Foundation, either version 3 of the License, or
  7. #(at your option) any later version.
  8. #M3 is distributed in the hope that it will be useful,
  9. #but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. #GNU Lesser General Public License for more details.
  12. #You should have received a copy of the GNU Lesser General Public License
  13. #along with M3. If not, see <http://www.gnu.org/licenses/>.
  14. #import matplotlib
  15. #matplotlib.use('TkAgg')
  16. import pylab
  17. import os
  18. import sys
  19. import time
  20. import exceptions
  21. import yaml
  22. import Gnuplot
  23. import numpy as nu
  24. #import Numeric
  25. import glob
  26. import datetime
  27. from datetime import timedelta
  28. from m3.unit_conversion import *
  29. from threading import Thread
  30. import m3.component_base_pb2 as mbs
  31. from m3.toolbox_core import *
  32. def get_m3_animation_path():
  33. try:
  34. vpath = get_m3_robot_path()
  35. path = [p+'/animations/' for p in vpath]
  36. return path
  37. except KeyError:
  38. print 'SET YOUR M3_ROBOT ENVIRONMENT VARIABLE'
  39. return ''
  40. def get_component_pwr_name(name):
  41. try:
  42. with open(get_component_config_filename(name),'r') as f:
  43. return yaml.safe_load(f.read())['pwr_component']
  44. except (IOError, EOFError):
  45. print 'Config file not present for ',name
  46. return ''
  47. def get_pwr_component_config(name):
  48. return get_component_config(name)
  49. def get_omnibase_pwr_component_name(name):
  50. return get_component_pwr_name(name)
  51. def get_chain_pwr_component_name(name):
  52. names=get_chain_joint_names(name)
  53. if len(names)>0:
  54. return get_joint_pwr_component_name(names[0])
  55. else:
  56. return ''
  57. def get_joint_pwr_component_name(name):
  58. return get_actuator_pwr_component_name(get_joint_actuator_component_name(name))
  59. def get_actuator_pwr_component_name(name):
  60. return get_actuator_ec_pwr_component_name(get_actuator_ec_component_name(name))
  61. def get_sub_component_name(parent_component_name,sub_component):
  62. try:
  63. with open(get_component_config_filename(parent_component_name),'r') as f:
  64. return yaml.safe_load(f.read())[sub_component]
  65. except (IOError, EOFError,KeyError) as e:
  66. print e
  67. return ''
  68. def get_actuator_ec_pwr_component_name(name):
  69. return get_sub_component_name(name,'pwr_component')
  70. def get_joint_actuator_component_name(name):
  71. if get_component_config_type(name) == 'm3joint_slave':
  72. return ''
  73. return get_sub_component_name(name,'actuator_component')
  74. def get_joint_ctrl_component_name(name):
  75. if get_component_config_type(name) == 'm3joint_slave':
  76. return ""
  77. return get_sub_component_name(name,'control_component')
  78. def get_chain_dynamatics_component_name(name):
  79. return get_sub_component_name(name,'dynamatics_component')
  80. def get_chain_loadx6_name(chain_name):
  81. if (chain_name.find('arm')==-1):
  82. print 'Error: get_chain_loadx6_name() valid for arms only'
  83. return None
  84. joint_names=get_chain_joint_names(chain_name)
  85. j0=joint_names[0]
  86. return 'm3loadx6_'+j0[j0.find('_')+1:j0.find('_',j0.find('_')+1)]+'_l0'
  87. def get_chain_limb_name(name):
  88. return get_sub_component_name(name,'limb_name')
  89. def get_chain_joint_names(name):
  90. config= get_component_config(name)
  91. if config.has_key('joint_components'):
  92. #Have to sort keys by *_JID*'
  93. ret=[]
  94. for jid in xrange(len(config['joint_components'])):
  95. ret.append(config['joint_components']['J'+str(jid)])
  96. return ret
  97. else:
  98. return []
  99. def get_chain_joint_limits(name):
  100. l=[]
  101. names=get_chain_joint_names(name)
  102. for n in names:
  103. try:
  104. with open(get_component_config_filename(n),'r') as f:
  105. config= yaml.safe_load(f.read())
  106. l.append([config['param']['min_q'],config['param']['max_q']])
  107. except (IOError, EOFError):
  108. print 'Config file not present:',get_component_config_filename(name),'for',name
  109. return []
  110. return l
  111. def get_actuator_ec_component_name(name):
  112. return get_sub_component_name(name,'ec_component')
  113. def get_joint_chain_name(joint_name,m3_config=None):
  114. if not m3_config:
  115. m3_config= get_m3_config()
  116. comp_type='rt_components'
  117. for config in m3_config:
  118. try: ## new config
  119. for components in config[comp_type]: # ma17,mh28..
  120. for comp_dir in components:# ma17
  121. dict_of_comp={}
  122. for comp in components[comp_dir]: #actuator1:type1,actuator2:type2
  123. cname = comp.keys()[0]
  124. ctype = comp[cname]
  125. if ctype in ['m3arm','m3torso' ,'m3hand','m3head']:
  126. dict_of_comp['joint_chain'] = cname
  127. dict_of_comp[cname]=ctype
  128. if dict_of_comp.get(joint_name,None):
  129. return dict_of_comp['joint_chain']
  130. except TypeError:
  131. for cdir in config[comp_type]:
  132. if joint_name in config[comp_type][cdir]:
  133. for c in config[comp_type][cdir]:
  134. ctype = config[comp_type][cdir][c]
  135. if ctype in ['m3arm','m3torso' ,'m3hand','m3head']:
  136. return c
  137. return ''
  138. def get_robot_name(m3_config=None):
  139. if not m3_config:
  140. m3_config= get_m3_config()
  141. comp_type='rt_components'
  142. for config in m3_config:
  143. try:
  144. for components in config[comp_type]: # ma17,mh28..
  145. for comp_dir in components:# ma17
  146. dict_of_comp={}
  147. for comp in components[comp_dir]: #actuator1:type1,actuator2:type2
  148. cname = comp.keys()[0]
  149. ctype = comp[cname]
  150. if ctype in ['m3humanoid','m3humanoid_sea']:
  151. return cname
  152. except TypeError:
  153. for cdir in config[comp_type]:
  154. for c in config[comp_type][cdir]:
  155. ctype = config[comp_type][cdir][c]
  156. if ctype in ['m3humanoid','m3humanoid_sea']:
  157. return c
  158. return ''
  159. def __get_hand_name(name):
  160. config_all= get_m3_config()
  161. for config in config_all:
  162. try:
  163. return config[name]
  164. except KeyError:
  165. pass
  166. return ''
  167. def get_right_hand_name():
  168. return __get_hand_name('right_hand')
  169. def get_left_hand_name():
  170. return __get_hand_name('left_hand')
  171. """
  172. * Animation file reader for files provided by Andrea Thomaz
  173. * each line is a trajectory via point: ts q0 q1 ... qn qd0 qd1 ... qdn qdd0 qdd1 ... qddn
  174. * n dof (7 each arm + torso: n=17) (define joint ordering in the comments)
  175. * ts: timestamp (s)
  176. * qx: joint angle of dof x (rad)
  177. * qdx: joint velocity of dof x (rad/s)
  178. * qddx: joint accel of dof x (rad/s2)
  179. Note: the joint angles seem scale by a factor of 0.5, and the velocities are all >0
  180. we'll just use the joint angles anyhow
  181. """
  182. def get_animation_files():
  183. path=get_m3_animation_path()[-1]
  184. return glob.glob(path+'*.txt')
  185. def get_animation_names():
  186. path=get_m3_animation_path()[-1]
  187. full=glob.glob(path+'*.txt')
  188. names=[]
  189. for s in full:
  190. names.append(s[s.rfind('/')+1:s.rfind('.')])
  191. return names
  192. def load_animation(filename):
  193. f=open(filename,'rb')
  194. data=f.read()
  195. nl=data.find('\r\n')
  196. samples=[]
  197. while nl>=0:
  198. sample=[]
  199. line=data[:nl]
  200. ts=line.find('\t')
  201. while ts>=0:
  202. sample.append(float(line[:ts]))
  203. line=line[ts+1:]
  204. ts=line.find('\t')
  205. sample.append(float(line))
  206. samples.append(sample)
  207. data=data[nl+1:]
  208. nl=data.find('\r\n')
  209. x=nu.array(samples)
  210. #limb names should map to chain limb names
  211. animation={'timestamp':x[:,0],
  212. 'torso':{ 'theta':x[:,1:4],'thetadot':x[:,18:21],'thetadotdot':x[:,35:38]},
  213. 'left_arm':{'theta':-2*x[:,4:11], 'thetadot':x[:,21:28],'thetadotdot':x[:,38:45]},
  214. 'right_arm':{'theta':-2*x[:,11:18], 'thetadot':x[:,28:35],'thetadotdot':x[:,45:52]}}
  215. ##patch animation to work with meka bodies
  216. animation['torso']['theta'][:,1:3]=animation['torso']['theta'][:,1:2]*-1
  217. animation['torso']['thetadot'][:,1:3]=animation['torso']['thetadot'][:,1:2]*-1
  218. animation['torso']['thetadotdot'][:,1:3]=animation['torso']['thetadotdot'][:,1:2]*-1
  219. animation['right_arm']['theta'][:,2]=animation['right_arm']['theta'][:,2]*-1
  220. animation['right_arm']['thetadot'][:,2]=animation['right_arm']['thetadot'][:,2]*-1
  221. animation['right_arm']['thetadotdot'][:,2]=animation['right_arm']['thetadotdot'][:,2]*-1
  222. animation['left_arm']['theta'][:,2]=animation['left_arm']['theta'][:,2]*-1
  223. animation['left_arm']['thetadot'][:,2]=animation['left_arm']['thetadot'][:,2]*-1
  224. animation['left_arm']['thetadotdot'][:,2]=animation['left_arm']['thetadotdot'][:,2]*-1
  225. animation['left_arm']['theta'][:,1]=animation['left_arm']['theta'][:,1]*-1
  226. animation['left_arm']['thetadot'][:,1]=animation['left_arm']['thetadot'][:,1]*-1
  227. animation['left_arm']['thetadotdot'][:,1]=animation['left_arm']['thetadotdot'][:,1]*-1
  228. #animation['left_arm']['theta'][:,0]=animation['left_arm']['theta'][:,0]*-1
  229. #animation['left_arm']['thetadot'][:,0]=animation['left_arm']['thetadot'][:,0]*-1
  230. #animation['left_arm']['thetadotdot'][:,0]=animation['left_arm']['thetadotdot'][:,0]*-1
  231. return animation
  232. def get_via_files():
  233. path=get_m3_animation_path()[-1]
  234. return [glob.glob(p+'*.via')[0] for p in path]
  235. def get_via_names():
  236. path=get_m3_animation_path()[-1]
  237. full=[glob.glob(p+'*.via')[0] for p in path]
  238. names=[]
  239. for s in full:
  240. names.append(s[s.rfind('/')+1:s.rfind('.')])
  241. return names