Commit 9dae8052 authored by Jan Koniarik's avatar Jan Koniarik
Browse files

finished Unit works, now got complete unit system for config!

parent ab1d08b9
......@@ -7,21 +7,27 @@ servo_horn_holes_step = 2.0;
servo_horn_holes_first = 4.5;
servo_horn_holes_n = 6;
mg90s_horn_offset = 11.1;
mg90s_gimbal_vector = [-5.85,12.5,-17.05];
mg90s_stall_current = 0.65;
mg90s_servo_width = 12.5;
mg90s_servo_length = 22.9;
mg90s_servo_height = 22.9;
mg90s_min = -75.0;
mg90s_turret_diameter = 11.7;
mg90s_turret_margin_y = 11.2;
mg90s_turret_margin_x = 0.4;
mg90s_turret_height = 5.2;
mg90s_max = 75.0;
mg90s_frame_length = 32.2;
mg90s_frame_v_offset = 16.0;
mg90s_frame_thickness = 2.45;
mg90s_torque = 0.1568;
mg90s_horn_offset = 11.1;
mg90s_gimbal_vector = [-5.85,12.5,-17.05];
mg90s_axle_diameter = 4.82;
mg90s_axle_screw_diameter = 2.0;
mg90s_axle_height = 3.9;
mg90s_running_current = 0.22;
mg90s_velocity = 10.471975512;
mg90s_mounting_hole_slot = 1;
mg90s_mounting_hole_diameter = 2.0;
mg90s_mounting_hole_center_offset_y = 2.325;
......
mg90s:
mg90s: &MG90S
servo:
width: 12.5mm
length: 22.9mm
......@@ -29,6 +29,13 @@ mg90s:
- "% -mg90s.turret.diameter / 2 %"
- "% mg90s.servo.width %"
- "% -(mg90s.servo.length - mg90s.turret.diameter /2 ) %"
velocity: 0.1sec/60°
torque: 1.6kg/cm
stall_current: 650mA
running_current: 220mA
min: -75°
max: 75°
servo_horn:
t: 2mm # thickness
h: 6mm # height
......@@ -83,59 +90,44 @@ battery:
offset: [-5mm,0,0]
dim: [80mm,12mm,35mm]
default_leg:
default_leg: &DEFAULT_LEG
mirror: [0,0,0]
joint_chain: ["alfa", "beta", "gama"]
joints: # min( torque_needed / max_torque , 1 ) * ( stall_current - running_current ) + stall_current
alfa:
<<: *MG90S
pos: [0,0,0]
rot: [0,0,0]
axis: [0, 0, 1]
min: -75°
max: 75°
graph:
steps: 16
velocity: 0.1sec/60°
torque: 1.6kg/cm
stall_current: 650mA
running_current: 220mA
weight: 30g
mass_center: [0,0,0]
scad:
module: "coxa"
args: []
beta:
<<: *MG90S
pos:
- 0
- "% mg90s.servo.width %"
- "% -( mg90s.servo.length - mg90s.turret.diameter / 2 + strengthen.mount_h ) %"
rot: [, 0, 0]
axis: [1, 0, 0]
min: -75°
max: 75°
graph:
steps: 16
velocity: 0.1sec/60°
torque: 1.6kg/cm
stall_current: 650mA
running_current: 220mA
weight: 10g
mass_center: [0,0,0]
scad:
module: "femur"
args: ["% default_leg.joints.gama.pos.1 %"]
gama:
<<: *MG90S
pos: [0,45mm,0]
rot: [-90°, 0, 0]
axis: [1, 0, 0]
min: -75°
max: 75°
graph:
steps: 16
velocity: 0.1sec/60°
torque: 1.6kg/cm
stall_current: 650mA
running_current: 220mA
weight: 15g
mass_center: [0,0,0]
scad:
......@@ -145,24 +137,30 @@ default_leg:
legs:
fl:
<<: *DEFAULT_LEG
mirror: [1,0,0]
pos: [55mm, 25mm, 0]
rot: [0,0,-30°]
fr:
<<: *DEFAULT_LEG
pos: [55mm, -25mm, 0]
rot: [0,0,-150°]
ml:
<<: *DEFAULT_LEG
pos: [0, 30mm, 0]
rot: [0,0,0]
mr:
<<: *DEFAULT_LEG
mirror: [1,0,0]
pos: [0, -30mm, 0]
rot: [0,0,180°]
rl:
<<: *DEFAULT_LEG
pos: [-55mm, 25mm, 0]
rot: [0,0,30°]
rr:
<<: *DEFAULT_LEG
mirror: [1,0,0]
pos: [-55mm, -25mm, 0]
rot: [0,0,150°]
......
......@@ -4,66 +4,49 @@ import copy
import math
class Distance(float):
@classmethod
def from_mm(cls, val):
return cls(val / 1000)
def as_mm(self):
return float(self * 1000)
def as_m(self):
return float(self)
class Unit(float):
def __add__(self, other):
return Distance(float.__add__(self, other))
return self.__class__(float.__add__(self, other))
def __sub__(self, other):
return Distance(float.__sub__(self, other))
return self.__class__(float.__sub__(self, other))
def __div__(self, other):
return Distance(float.__div__(self, other))
return self.__class__(float.__div__(self, other))
def __floordiv__(self, other):
return Distance(float.__floordiv__(self, other))
return self.__class__(float.__floordiv__(self, other))
def __mul__(self, other):
return Distance(float.__mul__(self, other))
return self.__class__(float.__mul__(self, other))
def __str__(self):
return "Distance({})".format(float(self))
return "{}({})".format(self.__class__.__name__, float(self))
def __repr__(self):
return str(self)
def __neg__(self):
return Distance(-float(self))
return self.__class__(-float(self))
def __abs__(self):
return Distance(abs(float(self)))
distance_re = re.compile("^\s*([-\d.]+)(mm|m)\s*$")
def distance_constructor(loader, node):
value = loader.construct_scalar(node)
res = re.match(distance_re, value)
val, unit = res.group(1), res.group(2)
return self.__class__(abs(float(self)))
val = float(val)
class Distance(Unit):
@classmethod
def from_mm(cls, val):
return cls(val / 1000)
if unit == 'mm':
return Distance.from_mm(val)
elif unit == 'm':
return Distance(val)
def as_mm(self):
return float(self * 1000)
def as_m(self):
return float(self)
yaml.add_constructor(u'!distance', distance_constructor)
yaml.add_implicit_resolver(u'!distance', distance_re)
class Angle(float):
class Angle(Unit):
@classmethod
def from_degree(cls, val):
return cls(math.radians(val))
......@@ -74,53 +57,58 @@ class Angle(float):
def as_radians(self):
return float(self)
def __str__(self):
return "Angle({})".format(float(self))
def __add__(self, other):
return Angle(float.__add__(self, other))
def __sub__(self, other):
return Angle(float.__sub__(self, other))
def __div__(self, other):
return Angle(float.__div__(self, other))
def __floordiv__(self, other):
return Angle(float.__floordiv__(self, other))
class Current(Unit):
@classmethod
def from_ma(cls, val):
return cls(val/1000)
def __mul__(self, other):
return Angle(float.__mul__(self, other))
def as_ma(cls, val):
return float(val*1000)
def __neg__(self):
return Angle(-float(self))
class Torque(Unit):
@classmethod
def from_kg_cm(cls,val):
return cls((9.8*val)/100)
def __abs__(self):
return Angle(abs(float(self)))
def as_n_m(self):
return float(self)
class AngleVelocity(Unit):
@classmethod
def from_s_60_degree(cls, val):
degrees_sec = 60/val
angle_re = re.compile(u"^\s*([-\d.]+)(\xb0*|r)\s*$")
return cls( math.radians(degrees_sec) )
def as_radians_s(self):
return float(self)
def angle_constructor(loader, node):
unit_config = {
"mm": Distance.from_mm,
"m": Distance,
u"\xb0": Angle.from_degree,
"rad": Angle,
"r": Angle,
"A": Current,
"mA": Current.from_ma,
"kg/cm": Torque.from_kg_cm,
u"sec/60\xb0": AngleVelocity.from_s_60_degree
}
config_re = re.compile(u"^\s*([-\d.]+)({})\s*$".format("|".join(unit_config.keys())))
def cfg_constructor(loader, node):
value = loader.construct_scalar(node)
res = re.match(angle_re, value)
res = re.match(config_re, value)
val, unit = res.group(1), res.group(2)
val = float(val)
if unit == u'\xb0':
return Angle.from_degree(val)
elif unit == 'r':
return Angle(val)
elif unit == '':
return Angle(val)
yaml.add_constructor(u'!angle', angle_constructor)
yaml.add_implicit_resolver(u'!angle', angle_re)
return unit_config[unit](val)
yaml.add_constructor(u'!cfg', cfg_constructor)
yaml.add_implicit_resolver(u'!cfg', config_re)
def _parse_val(val, top_cfg):
......@@ -200,35 +188,6 @@ def _parse_config_rec(cfg, top_cfg):
return replaced_big_count, unreplaced_big_count
# overlay 'a' over 'b' and return result
def overlay(a, b):
if isinstance(a, list):
assert isinstance(b, list)
keys = range(len(a))
elif isinstance(a, dict):
assert isinstance(b, dict)
keys = a.keys()
res = copy.copy(b)
for key in keys:
if isinstance(a[key], (float, int, bool)):
res[key] = a[key]
elif isinstance(a[key], dict):
try:
res[key] = overlay(a[key], b[key])
except KeyError:
res[key] = a[key]
elif isinstance(a[key], list):
try:
res[key] = overlay(a[key], b[key])
except KeyError:
res[key] = a[key]
return res
def parse_config(filename):
config = yaml.load(file(filename, "r"))
......@@ -239,8 +198,5 @@ def parse_config(filename):
raise Exception("Some values in config expressions were not replaced ",
config)
for leg_key in config['legs'].keys():
config['legs'][leg_key] = overlay(config['legs'][leg_key],
config['default_leg'])
return config
......@@ -6,6 +6,8 @@ def convert_scad(val):
return val.as_mm()
elif isinstance(val, Angle):
return val.as_degrees()
elif isinstance(val, Unit):
return float(val)
elif isinstance(val, (list, tuple)):
res = list()
for item in val:
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment