Seite 1 von 1

Funktion aus Klasse nutzen

Verfasst: Dienstag 21. Mai 2013, 13:47
von RodBelaFarin
Hallo zusammen,

ganz kurz zu meinem Background: Ich bin kein Programmierer/Informatiker, sondern Mechatroniker, aktuell in der mobilen Robotik tätig. Da kommt man natürlich nicht dran vorbei sich auch mehr oder weniger intensiv mit der Programmierung auseinander zu setzen. Jetzt wurde ich das erste mal mit Python konfrontiert. Wir haben ein kleines, ferngesteuertes Auto, was nun autonom fahren soll. Dazu gibt es "Mavlink", was unseren "Boardcontroller" ansteuern kann. Daraus habe ich nun eine Klasse

Code: Alles auswählen

class MAVLink_set_roll_pitch_yaw_thrust_message(MAVLink_message):
        '''
        Set roll, pitch and yaw.
        '''
        def __init__(self, target_system, target_component, roll, pitch, yaw, thrust):
                MAVLink_message.__init__(self, MAVLINK_MSG_ID_SET_ROLL_PITCH_YAW_THRUST, 'SET_ROLL_PITCH_YAW_THRUST')
                self._fieldnames = ['target_system', 'target_component', 'roll', 'pitch', 'yaw', 'thrust']
                self.target_system = target_system
                self.target_component = target_component
                self.roll = roll
                self.pitch = pitch
                self.yaw = yaw
                self.thrust = thrust

        def pack(self, mav):
                return MAVLink_message.pack(self, mav, 100, struct.pack('<ffffBB', self.roll, self.pitch, self.yaw, self.thrust, self.target_system, self.target_component))
Aus der Klasse würde ich gerne die Funktion __init__ in meinem eigenen Python-Skript nutzen um den sogenannten Winkel "pitch" zu setzen. Dazu habe ich natürlich erstmal mavlink importiert (import mavlink). Und rufe dann die Funktion wie folgt auf:

Code: Alles auswählen

MAVLink_set_roll_pitch_yaw_thrust_message.__init__(self, master.target_system, master.target_component, 0, 1, 0, 0.5)
Bekomme aber dann die Fehlermeldung
NameError: global name 'MAVLink_set_roll_pitch_yaw_thrust_message' is not defined
zurück. Könnt ihr mir vielleicht weiterhelfen wie ich die Funktion richtig aufrufen muss um meinen Pitch zu setzen?

Danke :)

Re: Funktion aus Klasse nutzen

Verfasst: Dienstag 21. Mai 2013, 14:04
von BlackJack
@RodBelaFarin: Die `__init__()` ruft man nicht direkt auf, es sei denn man hat eine abgeleitete Klasse und will in deren `__init__()` die `__init__()` von einer Basisklasse aufrufen.

Kann es sein, dass Du nicht das `mavlink`-Modul importierst, das diese Klasse enthält, sondern ein anderes? Hast *Du* eventuell ein Modul so genannt?

Re: Funktion aus Klasse nutzen

Verfasst: Dienstag 21. Mai 2013, 14:13
von RodBelaFarin
danke schonmal für die schnelle antwort.

macht natürlich sinn, dass die init nicht direkt aufgerufen wird, kenne ich auch so aus c++, wo du es jetzt ansprichst ;)

und mit dem import: genau verhält es sich folgendermaßen... ich nutze ein python-skript aus dem netz (wen's interessiert: roscopter). das entwickle ich weiter. dort wird in zeile 26 mavutil importiert (das ist auch alles in dem ordner hinterlegt und alles fertig). in mavutil wiederum wird mavlinkv10 (version 1.0) importiert. da ist nix von mir, das ist alles fertig. ich will es nur benutzen :D

Re: Funktion aus Klasse nutzen

Verfasst: Dienstag 21. Mai 2013, 14:26
von BlackJack
@RodBelaFarin: Ich sehe bei dem `roscopter` kein `mavutil`. Und bei `pymavlink` ist das auch nicht dabei. `mavlinkv10` habe dort auch nicht als Modulnamen gefunden. In dem Modul `mavlink` gibt es auch keine `MAVLink_set_roll_pitch_yaw_thrust_message`-Klasse. Die ist in einem anderen Modul. Ich bin mir aber auch gar nicht sicher, dass die zum direkten Verwenden gedacht ist. Es gibt doch diese ganzen netten Methoden auf der `MAVLink`-Klasse dafür.

Re: Funktion aus Klasse nutzen

Verfasst: Dienstag 21. Mai 2013, 14:46
von RodBelaFarin
@BlackJack: die "mavutil" und "mavlinkv10" sind auch nicht unter dem link zu finden, sondern hier. die werden in "roscopter" eingebunden, das klappt auch. andere funktionen aus roscopter basieren auch auf mavlink, die funktionieren auch. sorry, wenn ich das nicht deutlich rübergebracht habe.

ob die zum direkten nutzen gedacht ist, weiß ich auch nicht. ich würde aber gerne (im 1. schritt erstmal nur) den "pitch" setzen. wenn das irgendwie anders möglich ist, lasse ich mich auch gerne darin belehren wie man es richtig macht. leider weiß ich nicht genau, was mit einer "methode" gemeint ist, aber ich finde auch nichts, was ich nutzen könnten um mein ziel zu erreichen.

Re: Funktion aus Klasse nutzen

Verfasst: Dienstag 21. Mai 2013, 15:00
von BlackJack
@RodBelaFarin: Wenn Du Grundbegriffe wie „Methode” nicht kennst, solltest Du vielleicht erst einmal ein Grundlagentutorial bis einschliesslich objektorientierter Programmierung (Klassen, Methoden, …) durcharbeiten. In der Python-Dokumentation ist eines enthalten.

Diese ganzen Message-Klassen werden von den Methoden der `MAVLink`-Klasse verwendet, und zwar gibt es zwei Methoden pro Message-Klasse, eine zum Enkodieren einer Nachricht und eine um sie gleich zu versenden, und deshalb denke ich, dass man die Message-Klassen nicht selbst benutzten soll, sondern eben über diese Methoden.

Re: Funktion aus Klasse nutzen

Verfasst: Dienstag 21. Mai 2013, 18:24
von RodBelaFarin
hallo, mir war nur der begriff der "methode" unklar. habe grundlagen in java und c++ bzw. objektorientierung ein halbes jahr lang besucht - leider nur theoretisch.

habe ich also jetzt nochmal nachgearbeitet und die entsprechenden methoden gefunden, danke. habe diese dann auch in meinem skript genutzt und "scheinbar" geht die message auch raus, aber es passiert nix. den passenden codesniff liefere ich morgen nach, für heute ist's jetzt genug ;)

Re: Funktion aus Klasse nutzen

Verfasst: Mittwoch 22. Mai 2013, 11:15
von RodBelaFarin
dann hier wie versprochen noch die codezeile, wo ich die methode nutze:

Code: Alles auswählen

mavlinkv10.set_roll_pitch_yaw_speed_thrust_send(master.target_system, master.target_component, 0, 1, 0, 0.8)
leider passiert nichts, was nun? :shock:

Re: Funktion aus Klasse nutzen

Verfasst: Mittwoch 22. Mai 2013, 11:28
von BlackJack
@RodBelaFarin: Nun? Heraus finden warum nichts passiert. ;-)

Das ist aber nicht einfach hier zu helfen, weil dafür anscheinend ziemlich spezielle Hardware und Wissen aus dem Fachgebiet benötigt wird. Mit reinen Python-Kenntnissen wird es schwierig und man kann das Problem ja auch nicht mal eben nachstellen.

Re: Funktion aus Klasse nutzen

Verfasst: Mittwoch 22. Mai 2013, 11:47
von RodBelaFarin
das dachte ich mir natürlich schon :wink:

danke für deine hilfe bis hier hin. vielleicht kannst du mir aber nochmal bei folgender fehlermeldung weiter helfen:
AttributeError: 'module' object has no attribute 'set_roll_pitch_yaw_speed_thrust_send'
das sagt er mir jetzt zu der zeile

Code: Alles auswählen

        mavlinkv10.set_roll_pitch_yaw_speed_thrust_send(master.target_system, master.target_component, 0, 1, 0, 0.8)

Re: Funktion aus Klasse nutzen

Verfasst: Mittwoch 22. Mai 2013, 11:58
von BlackJack
@RodBelaFarin: Die Meldung ist doch ziemlich deutlich. Das Modul kennt so ein Attribut nicht. Was nicht weiter verwundert, weil es so eine Funktion tatsächlich nicht gibt. Allerdings gibt es die auf der `MAVLink`-Klasse aus diesem Modul. Da muss man ein Exemplar von erstellen und dann kann man die Methode darauf aufrufen.

Re: Funktion aus Klasse nutzen

Verfasst: Mittwoch 22. Mai 2013, 12:01
von /me
RodBelaFarin hat geschrieben:
AttributeError: 'module' object has no attribute 'set_roll_pitch_yaw_speed_thrust_send'
Kurz gesagt: Die Funktion gibt es nicht im Modul.

Es gibt aber in dem Modul eine Klasse MAVLink die eine Methode mit gleichem Namen hat.

Re: Funktion aus Klasse nutzen

Verfasst: Mittwoch 22. Mai 2013, 12:25
von RodBelaFarin
BlackJack hat geschrieben:@RodBelaFarin: Die Meldung ist doch ziemlich deutlich. Das Modul kennt so ein Attribut nicht. Was nicht weiter verwundert, weil es so eine Funktion tatsächlich nicht gibt. Allerdings gibt es die auf der `MAVLink`-Klasse aus diesem Modul. Da muss man ein Exemplar von erstellen und dann kann man die Methode darauf aufrufen.
@BlackJack: erstmal großes lob an dich! dieses forum kann dankbar sein dich zu haben, leider fehlt hier der danke-button :wink: bin ja in vielen foren unterwegs und eigentlich wird einem immer geholfen. versuche auch selbst in den verschiedensten foren zu helfen, aber hier wird sich ja sehr hingebungsvoll gekümmert :D

nach diesem tipp hätte ich jetzt so was entworfen:

Code: Alles auswählen

def set_roll_pitch_yaw_speed(roll_speed, pitch_speed, yaw_speed, thrust):
    mavlinkv10.set_roll_pitch_yaw_speed_thrust_send(master.target_system, master.target_component, roll_speed, pitch_speed, yaw_speed, thrust)
und dann als funktionsaufruf folgendes:

Code: Alles auswählen

set_roll_pitch_yaw_speed(0, 1, 0, 0.8)
führt aber zur selben fehlermeldung, da fehlt also noch irgendwas?!

----------------------------------------------------------------------------------------
/me hat geschrieben:Es gibt aber in dem Modul eine Klasse MAVLink die eine Methode mit gleichem Namen hat.
daraufhin bin ich dann hingegangen und habe folgendes versucht um die methode zu nutzen:

Code: Alles auswählen

mavlinkv10.mavlink.set_roll_pitch_yaw_speed_thrust_send(0, 1, 0, 0.8)
führt aber zur selben fehlermeldung. habe da aber glaube ich eh was falsch verstanden, weil "set_roll_pitch_yaw_speed_thrust_send" befindet sich ja nicht in der klasse "MAVLink" in mavlinkv10.py, sondern ist dort direkt als methode definiert.

Re: Funktion aus Klasse nutzen

Verfasst: Mittwoch 22. Mai 2013, 12:55
von BlackJack
@RodBelaFarin: `set_roll_pitch_yaw_speed_thrust_send()` befindet sich eben *nicht* direkt im Modul sondern als Methode in der Klasse `MAVLink`. Und die heisst wirklich `MAVLink` und nicht `mavlink`. Gross- und Kleinschreibung macht einen Unterschied. Aber selbst wenn Du das richtig geschrieben hättest, dann könntest Du nicht die Methode auf der Klasse direkt aufrufen. Du musst erst ein Exemplar erstellen und dann *dort* die Methode aufrufen.

Dir fehlt es an Grundlagen, die ich an Deiner Stelle erst einmal allgemein lernen würde. Also ohne diese spezielle Bibliothek, sondern mit einem allgemeinen Python-Tutorial. Und erst wenn Du objektorientierte Programmierung verstanden hast, solltest Du IMHO mit Deinem konkreten Problem weiter machen.

In der Python-Dokumentation gibt es ein Tutorial und für Anfänger wird auch gerne Learn Python The Hard Way empfohlen. Nicht vom Titel irritieren lassen. ;-)