Python-Extend类实例方法
我正在创建控制六足动物的“框架”。 所以(简化)我有一个伺服类:Python-Extend类实例方法,python,Python,我正在创建控制六足动物的“框架”。 所以(简化)我有一个伺服类: class Servo(object): ... def setAngle(self, angle): ##Executes order to move servo to specified angle ##Returns False if not possible or True if OK offsetAngle=s
class Servo(object):
...
def setAngle(self, angle):
##Executes order to move servo to specified angle
##Returns False if not possible or True if OK
offsetAngle=self.offset+angle
if not self.checkServoAngle(offsetAngle):
#Angle not within servo range
return=False
else:
pwmvalue=self._convAngleToPWM(offsetAngle)
self._setPWM(pwmvalue)
self.angle=value
return=True
...
还有一个儿童六角骨课程:
class HexBone(Servo):
## Servo.__init__ override:
def __init__(self, I2C_ADDRESS, channel, length, startAngle, reversed=False, minAngle=NULL, maxAngle):
self = Servo(I2C_ADDRESS, channel, reversed, minAngle, maxAngle)
#Setting bone length
self.length=length
#Positions bone in Starting Position
self.setAngle(startAngle)
还有一个六肢类:
class HexLimb(object):
def __init__(self, I2C_ADDRESS, femurLength, tibiaLength, femurInv, tibiaInv):
#Setting precision of Limb Positioning
self.precision=1
#Setting i2c address and servo channels
self.femur = HexBone(I2C_ADDRESS, 1, femurLength, 45, femurInv, 5, 190)
self.tibia = HexBone(I2C_ADDRESS, 2, tibiaLength, 90, tibiaInv, 5, 190)
def calcPosition(self):
L1=self.femur.length
L2=self.tibia.length
try:
a1=90-self.femur.angle#########!!!!!!
a2=180-self.tibia.angle
self.x=L1*math.cos(math.radians(a1))+L2*math.cos(math.radians(a1-a2))
self.y=L1*math.sin(math.radians(a1))+L2*math.sin(math.radians(a1-a2))
except:
return False
else:
return True
在Hexlipm类中,每当我执行以下操作时:
self.femor.setAngle(30)我想调用self.calcPosition()来重新计算肢体的尖端位置
我一直在到处寻找,找不到任何答案……我是不是做错了
(下面编辑了相应的注释)您的
六肢
需要了解附在其上的六骨
以计算其位置。但是HexBones
作为Servo
s,还需要了解它们所连接的HexBones
,以便能够触发肢体位置的重新计算
一种解决方案是将HexBones
上的back引用保留到它们所连接的HexLimb
在本例中,我在hexlipm.\uuuu init\uuuu()
中创建了一个名为limb
的反向引用,它位于两块骨骼上-您也可以将其称为parent
,以便更为通用
from random import random
class Servo(object):
"""Servo controller"""
def __init__(self):
self.angle = 0
def set_angle(self, angle):
print "Setting angle to %s" % angle
self.angle = angle
# Let limb recalculate its position
self.limb.calc_position()
class HexBone(Servo):
"""A bone that can be attached to a limb and moved."""
def __init__(self, length):
super(HexBone, self).__init__()
self.length = length
# Will be assigned later when attached to a limb
self.limb = None
class HexLimb(object):
"""A limb consisting of several bones."""
def __init__(self):
self.femur = HexBone(42)
self.femur.limb = self
self.tibia = HexBone(30)
self.tibia.limb = self
def calc_position(self):
print "Calculating position..."
# Something that needs self.femur and self.tibia
self.x = self.femur.length * random()
self.y = self.tibia.length * random()
def extend(self):
self.tibia.set_angle(0) # extend knee
left_leg = HexLimb()
left_leg.extend()
根据Lukas Graf的建议,我对代码做了一些修改,以使伺服类更通用。 基本上,Servo(及其固有的子类HexBone)将回调函数引用作为init的可选参数(默认为None)。 最后调用Servo.setAngle时,将执行回调函数。 代码如下:
from random import random
class Servo(object):
"""Servo controller"""
def __init__(self, callback=None): #Servo takes a callback function as argument
self.angle = 0
self.callback=callback
def set_angle(self, angle):
print("Setting angle to %s" % angle)
self.angle = angle
# After angle set executes the callback function
if self.callback is not None: self.callback()
class HexBone(Servo):
"""A bone that can be attached to a limb and moved."""
def __init__(self, length, callback):
super(HexBone, self).__init__(callback)
self.length = length
class HexLimb(object):
"""A limb consisting of several bones."""
def __init__(self):
self.femur = HexBone(42, self.calc_position)
self.femur.limb = self
self.tibia = HexBone(30, self.calc_position)
self.tibia.limb = self
def calc_position(self):
print("Calculating position...")
# Something that needs self.femur and self.tibia
self.x = self.femur.length * random()
self.y = self.tibia.length * random()
def extend(self):
self.tibia.set_angle(0) # extend knee
left_leg = HexLimb()
left_leg.extend()
在
hexlipm
类中,您没有执行self.femur.setAngle(30)
任何操作,并且hexlipm
没有从任何其他类继承-因此我不太明白您的问题。另外,在设置HexBone.length
之前,您有一条注释#设置肢体的长度
-那么HexBone
是肢体吗?如果是的话,hexlipm
有什么意义?谢谢你的回复。我还没有完成创建all类(这就是为什么我没有self.femor.setAngle(30))的原因,而且这个类是不完整的,因为它非常复杂。不客气。因为这可能会涉及很多来回,如果你愿意的话,我很乐意帮助你-只是我对你希望你的框架是什么样子和如何使用感到困惑。我编辑了代码。一个肢体是由几个骨骼组成的(我已经更正了评论)调用伺服实例方法setAngle,我假装重新计算运行HexLimb.calcposition的所有位置,这解决了问题,但没有办法保持伺服类完整且更“通用”。因为如果我尝试在其他地方使用它,我会得到一个错误,因为没有设置limb…首先,很抱歉回复太晚。我认为你的版本带有回调函数,可能会传递,也可能不会传递。我会按照这些思路提出建议。完全不同的方法是使用(或者自己实现一个简单的)。Servo.set_angle()
然后可以触发AngleChangedEvent
(使用limb
参数),并且hexframbs
可以订阅这些事件。