Motorsteuerung, brauche Hilfe

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Dominikin9
User
Beiträge: 13
Registriert: Mittwoch 4. Januar 2017, 17:39

Guten Abend an alle!
Ich bin gerade dabei eine Motorsteuerung mit zwei Motoren zu schreiben, für einen positionier Arm. Ich bin noch ziemlich unerfahren was Python betrifft. Daweil habe ich es nur für einen Motor geschrieben und wollte das ganze, mit Threads machen, damit ich beide Motoren gleichzeit steuern kann. Aber jetzt bekomme ich nurnoch beim Kompilieren den Fehler File
"dipl.py" , line 76
print ('ende')
SyntaxError: invalid syntax.

Code: Alles auswählen

from __future__ import print_function
import time
from dual_mc33926_rpi import motors, MAX_SPEED
import math
import threading

r_arm=70


def rechnenxy(xkoor,ykoor,rarm):
	a90grad=90*0.0174532925
	
	w2=math.atan(xkoor/ykoor)
	w1=a90grad-w2
	global amotor
	global bmotor
	z=ykoor/math.sin(w1)
	amotor=(a90grad*2-(math.asin(z/(2*rarm)))*2)/2+w1
	y1=(rarm*math.sin(a90grad-(a90grad-amotor)))/math.sin(a90grad)
	y2=ykoor-y1
	
	bmotor=(a90grad-amotor)+math.asin(y2/rarm)
	
	bmotor=bmotor*57.295779513
	amotor=amotor*57.295779513
	
def motor1(amotor_neu):
	global tm1
	global m1dir
	amotor_alt=0
	
	amotordiff = amotor_neu - amotor_alt
	
	if amotordiff<-1:
		m1dir=-1
		amotordiff = amotordiff * (-1)
	elif amotordiff>1:
		m1dir=1
		
	umdrehung=amotordiff/360	
	tm1=(umdrehung*5*2)/0.0041666666/1000 #bei einer min Auflösung von 5ms und bei einem PWM von 240 bei max 480
	
	amotor_alt=amotor_neu

def m1control():
	motors.motor1.enable()
	motors.motor1.setSpeed(0)
	motors.motor1.setSpeed(240*m1dir)
	time.sleep(tm1)
	motors.motor1.setSpeed(280*(-1)*m1dir)
	if tm1>0.250:
		time.sleep(tm1*0.0335522579)
	elif tm1<0.250 and tm1>0.150:
		time.sleep(tm1*0.086)
	else: time.sleep(tm1*0.144788403)
	motors.motor1.setSpeed(0)
	motors.motor1.disable()

class m1c(threading.Thread):
	def _init_(self):
		threading.Thread_init_(self)
		self.deamon=True
		self.start()
	def run(self):
		m1control()


try:
	x_koor = float(input('Eingabe für x Koordiante: '))
	y_koor = float(input('Eingabe für die y Koordiante: '))
	rechnenxy(x_koor,y_koor,r_arm)
	print('amotor= ',amotor)
	print('bmotor= ',bmotor)
	motor1(amotor)
	print('tmi= ', tm1, 'milli')
	print('ende')

Danke jetzt schon mal.
Mit freundlichen Grüßen
Dominic
Zuletzt geändert von Anonymous am Mittwoch 4. Januar 2017, 18:15, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@Dominikin9: Dem Compiler fehlt da etwas zu dem ``try`` in Zeile 68. Was dachtest Du denn was das so alleine machen soll?

Da liegt aber noch viel mehr im argen. Nimm mal von dem Projekt Abstand und lerne Python inklusive objektorientierter Programmierung (OOP). Momentan werden nicht einmal Funktionen richtig verwendet. ``global`` hat in einem ”normalen” Programm was man lesen und verstehen können möchte schon nichts zu suchen, mit Threads verlässt man dann aber endgültig die rationale Ebene. ;-)

Was die Namensschreibweise angeht wirf mal einen Blick in den Style Guide for Python Code.

Zudem sind da einige schlechte Namen dabei. Keine kryptischen Abkürzungen und sprechende Bezeichner. Ein Name soll dem Leser vermitteln was der Wert dahinter im Kontext des Programms bedeutet.

Ausserdem sind da so einige sehr magische Zahlen die vielleicht erklärt werden oder noch besser als aussagekräftige Konstanten definiert werden sollten.
Dominikin9
User
Beiträge: 13
Registriert: Mittwoch 4. Januar 2017, 17:39

Danke für die Antwort und ja wäre nicht schlecht das langsam anzugehen, doch leider brauche ich das bald und deswegen dachte ich mir, ich schreibs mal egal wie viele Fehler Hauptsache es funktioniert irgendwie. Und was fehlt bei dem 'try'?
BlackJack

@Dominikin9: Hauptsache es funktioniert irgendwie geht nicht wirklich wenn man sich da ohne wirkliches Verständnis hinarbeitet, denn dann weiss man ja gar nicht ob es tatsächlich funktioniert, oder man nur noch nicht in die Fehler rein gelaufen ist. Was insbesondere wenn dann Threads und das dann auch noch mit globalen Zuständen ins Spiel kommen, nicht mehr so einfach vorhersehbar ist, denn da fangen dann die nicht-deterministischen Fehler an, also die die man nicht einfach reproduzieren kann, weil sie ”zufällig” auftreten können.

Was bei dem ``try`` fehlt musst Du doch wissen. Du musst Dir doch irgendwas dabei gedacht haben den Code dort in einen ``try``-Block zu stecken. Fehlt da eventuell auch etwas, denn es wird nicht alles verwendet was da definiert wird‽
Dominikin9
User
Beiträge: 13
Registriert: Mittwoch 4. Januar 2017, 17:39

Ich hab mir ein Beispiel zu den Threads angeschaut und wollte das dann replizieren und damit es einen Zeitpunkt gibt wo der Task beginnt und einen wo er aufhört dachte ich mir kann man unteranderen das Try nehmen.

Und als ich mir nochmal den Code angeschaut habe, habe ich bemerkt das etwas fehlt und das ist der eigentliche Code.

Code: Alles auswählen

from __future__ import print_function
import time
from dual_mc33926_rpi import motors, MAX_SPEED
import math
import threading

r_arm=70 # Arm laenge in mm


def rechnenxy(xkoor, ykoor, rarm):
	
	a90grad = 90*0.0174532925 # um mit 90 Grad in Radiant zu rechnen
	
	w2 = math.atan(xkoor/ykoor)
	w1 = a90grad-w2
	global amotor
	global bmotor
	z = ykoor/math.sin(w1)
	amotor = (a90grad*2-(math.asin(z/(2*rarm)))*2)/2 + w1
	y1 = (rarm*math.sin(a90grad - (a90grad-amotor)))/math.sin(a90grad)
	y2 = ykoor - y1
	
	bmotor = (a90grad-amotor) + math.asin(y2/rarm)
	
	bmotor = bmotor * 57.295779513 #um mit Grad weiter zu rechnen
	amotor = amotor * 57.295779513


	
def motor1(amotor_neu):
	global tm1
	global m1dir
	amotor_alt = 0
	
	amotordiff = amotor_neu - amotor_alt
	
	if amotordiff < -1:
		m1dir = -1
		amotordiff = amotordiff * (-1)
	elif amotordiff > 1:
		m1dir = 1
		
	umdrehung = amotordiff/360	
	tm1 = (umdrehung*5*2) / 4.1666666 #bei einer min Aufloesung von 5ms und bei einem PWM von 240 bei max 480
	
	amotor_alt = amotor_neu




def m1control():
	motors.motor1.enable()
	motors.motor1.setSpeed(0)
	motors.motor1.setSpeed(240 * m1dir)
	time.sleep(tm1)
	motors.motor1.setSpeed(280 * (-1) * m1dir)
	if tm1 > 0.250:
		time.sleep(tm1 * 0.0335522579)
		
	elif tm1 < 0.250 and tm1 > 0.150:
		time.sleep(tm1 * 0.086)
		
	else:
		time.sleep(tm1 * 0.144788403)
	
	motors.motor1.setSpeed(0)
	motors.motor1.disable()



class m1c(threading.Thread):
	def _init_(self):
		threading.Thread_init_(self)
		self.deamon = True
		self.start()
		
	def run(self):
		m1control()

m1=m1c

try:
	x_koor = float(input('Eingabe für x Koordiante: '))
	y_koor = float(input('Eingabe für die y Koordiante: '))
	rechnenxy(x_koor, y_koor, r_arm)
	print('amotor= ',amotor)
	print('bmotor= ',bmotor)
	motor1(amotor)
	print('tmi= ', tm1, 'milli')
	m1.join()
	print('ende')
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@Dominikin9: der Code hat so viele Fehler, an denen man sieht, dass Du noch nie systematisch Python gelernt hast. Wenn Du das nicht nachholst, wird das mit dem Programm nichts. Zum Umrechnen von Grad in Rad sollte man keine Magischen Werte verwenden, sondern die math-Funktionen `degrees` und `radians`. Was die Zahlen bei den sleep-Aufrufen bedeuten sollen, habe ich nicht herausfinden können. Die Klasse m1c ist überflüssig, da man dasselbe mit dem target-Argument von Thread machen kann.
Warum Du überhaupt einen Thread startest, ist mir auch schleierhaft, weil Du ja eh gleich wieder `join´ aufrufst.
Dominikin9
User
Beiträge: 13
Registriert: Mittwoch 4. Januar 2017, 17:39

@Sirius: danke für deine Antwort und ja hab ich auch nicht und ich weiß auch nicht wie, da ich bis jetzt noch nichts gefunden habe, dass mir das ermöglichen könnte.
Und danke für den Hinweis der helfen mir ein bisschen weiter und die Zahlen sind Testwerte die ich probiert habe um mir die Zeit zu errechen, damit der Motor bremst aber nicht in die andere Richtung dreht.
Und das mit den Threads habe ich schon bemerkt, dass das ein sch* ist, weiß auch schon ca was Du meinst mit den target-Argument.

Mit freundlich Grüßen
Dominic
Antworten