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
可以订阅这些事件。