Seite 1 von 3

P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 22. Jan 2011 17:12
von MuldeR
Hallo.

Beim letzten Teil der 7. Programmieraufgabe ist mir leider die Syntax zur Verwendung von numdiff() völlig unklar. Ein erhellendes Beispiel fehlt ja leider. Also, angenommen ich habe eine Funktion L = funL(qdot, dh, q, g) und möchte diese nun nach q oder qdot ableiten, wie muss ich numdiff() aufrufen? Ich nehme an numdiff(@funL, ...), aber wie weiter?

Außerdem stellt sich mir die Frage, wie ich mit Hilfe von numdiff() nach t ableiten kann, wenn t nicht explizit als Parameter auftritt...

Falls es schon jemandem gelungen ist, die Syntax von numdiff() zu entschlüsseln, wäre ich für Hinweise sehr dankbar! :wink:

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 24. Jan 2011 16:49
von TCE
Hallo,

die Syntax ist eigentlich nicht weiter schwer:
Du musst nur eine Funktion als functionhandle deklarieren: f=@myfun. Hierbei ist myfun z.B. function g = myfun(x,y,z).
Dann kann man schon numdiff wie folgt aufrufen. numdiff(f,x,y,z). Dabei ist die zweite Stelle die Variable nach der Du ableiten willst. Die restlichen Variablen werden von einer varargin-Funktion in numdiff gecatched. D.h. sämtliche Variablen die hinter der zweiten Stelle an numdiff übergeben werden, werden in numdiff verarbeitet und an die function übergeben.

Jetzt hat sich bei mir aber eine Frage ergeben:
Wenn ich nun nicht nach x sondern nach y ableiten will: Wie kann ich die Variablen in richtiger Reihenfolge an die function übergeben? In numdiff steht:

y0 = f(x, varargin{:});

f ist die function "calcManipulatorEnergy". x=q, denn danach will man ja ableiten. q steht bei einem Aufruf von "calcManipulatorEnergy" aber nicht an erster Stelle sondern an zweiter!? Können wir numdiff abändern oder muss man da eine Art Umsortierungsfunktion schreiben??

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 24. Jan 2011 16:50
von TCE
Was die Frage nach dem Ableiten nach t angeht, schau mal hier:

http://www.fachschaft.informatik.tu-dar ... 49&t=18088

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 24. Jan 2011 20:11
von MuldeR
TCE hat geschrieben:Hallo,

die Syntax ist eigentlich nicht weiter schwer:
Du musst nur eine Funktion als functionhandle deklarieren: f=@myfun. Hierbei ist myfun z.B. function g = myfun(x,y,z).
Dann kann man schon numdiff wie folgt aufrufen. numdiff(f,x,y,z). Dabei ist die zweite Stelle die Variable nach der Du ableiten willst. Die restlichen Variablen werden von einer varargin-Funktion in numdiff gecatched. D.h. sämtliche Variablen die hinter der zweiten Stelle an numdiff übergeben werden, werden in numdiff verarbeitet und an die function übergeben.
Ah okay. Danke! Ich gebe nach dem Funktions-Handle also einfach nacheinander alle Parameter an, die meine Funktion erwartet. Quasi wie man es von printf(...) kennt. Und zwar genau in der Reihenfolge, in der sie bei meiner Funktion deklariert sind, wobei das erste Parameter (nach dem Funktions-Handle) implizit die Variable ist, nach der Abgeleitet werden soll. Das heißt also auch, dass meine Funktion so geschrieben sein muss, dass sie die Variable, nach der ich ableiten möchte, als erstes Parameter erwartet...
TCE hat geschrieben:Jetzt hat sich bei mir aber eine Frage ergeben:
Wenn ich nun nicht nach x sondern nach y ableiten will: Wie kann ich die Variablen in richtiger Reihenfolge an die function übergeben? In numdiff steht:

y0 = f(x, varargin{:});

f ist die function "calcManipulatorEnergy". x=q, denn danach will man ja ableiten. q steht bei einem Aufruf von "calcManipulatorEnergy" aber nicht an erster Stelle sondern an zweiter!? Können wir numdiff abändern oder muss man da eine Art Umsortierungsfunktion schreiben??
Wenn numdiff() so funktioniert, wie ich es verstanden habe, wird man sich wohl eine "Wrapper" Funktion um die eigentliche Funktion herumbasteln müsse, die die Parameter so "umsortiert", dass das Parameter, nach dem wir ableiten möchten, an erster Stelle steht. Intern wird die eigentliche Funktion dann mit der "richtigen" (vorgegebenen) Parameter-Reihenfolge aufgerufen.

Ich denke numdiff() abändern ist keine gute Idee, da diese Funktion ja vorgegeben ist und nicht mit hochgeladen werden soll...
numdiff leitet nach dem ersten Parameter in der Liste ab. Falls das ein Vektor ist, werden alle Ableitungen gebildet und als Array zurückgegeben:
x = numdiff(list(funktionX, param1, param2), param1) mit param1 aus R3 liefert in x(1) die x-Komponente.
In dem Original-Beitrag war scheinbar von Scilab die Rede. Geht das mit dem Vektor in Matlab auch so? Und brauch ich diese list(..) ebenfalls?

Danke!

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 25. Jan 2011 11:10
von TCE
Wie würdest eine solche "Wrapper"-Funktion denn angehen? Ich verstehe nicht ganz wie man umsortiert, wenn innerhalb von numdiff dann doch wieder die falsche Reihenfolge verwendet wird. Also müsste man numdiff ändern oder? Jedenfalls soweit, dass man einen "Wrapper"-Funktionsaufruf einfügt, oder??

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 25. Jan 2011 12:06
von cpunkt
Du könntest zB f(x, y, z) mit g(a, b, c) := f(b, a, c) wrappen. Damit könntest Du die Reihenfolge quasi selbst bestimmen.

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 25. Jan 2011 12:55
von TCE
Gibt es dafür einen bestimmten Befehl in Matlab?
Vergiss es, hab schon verstanden. Über eine weitere Funktion welche ich dann aufrufe...

Danke

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 25. Jan 2011 16:51
von TCE
Wie implentiert man denn die Formel

\(\frac{d}{dt}f(x, xdot) = \frac{\partial f}{\partial x}xdot + \frac{\partial f}{\partial xdot}xdotdot\)

denn f(x, xdot) =\(\frac{\partial K(q(t),qDot(t))}{\partial qDot_i}\)

kann man numdiff an numdiff übergeben?

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 25. Jan 2011 18:28
von MisterD123
du schreibst dir einfach ne funktion, die (mit benutzung von numdiff) den inneren ausdruck dL/dqdot_i - dL/dq_i zum zeitpunkt t berechnet. Die funktion übergibst du dann nochmal an numdiff und leitest sie nach der zeit ab.

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 25. Jan 2011 20:50
von TCE
Das ist doch aber nicht richtig. (dL/dqdoti) muss nach dt abgeleitet werden und nicht (dL/dqdoti - dL/dqi)!?

Wenn ich numdiff in numdiff "verschachtele" kommt bei mir folgender Fehler:

??? Subscripted assignment dimension mismatch.

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 25. Jan 2011 21:08
von MisterD123
öh kann auch sein dass die klammerung da ander is als ich sie jetzt interpretiert hatte, ich schau nochmal nach und schreib mal n vernünftigen test.. hatte nur einen gemacht und der hat geklappt gehabt, deswegen nich weiter drüber nachgedacht.

/edit: Update: natürlich muss man wirklich nur dL/dqdot_i in ne funktion abpacken und noch ein zweites mal differenzieren.

Hier sind ne reihe testcases an die dynamik-berechnung mittles lagrange, hab ich von T6 kopiert und die parameter entsprechend angepasst (und den einen testcase der ne fTcp vorgegeben hat rausgeschmissen). Bei mir laufen die tests jetzt sogar alle durch nachdem ich die Formel entsprechend korrigiert hab.

Code: Alles auswählen

% Speichern als: T7b.m
function t = T7b()
  clc;
  t = 1:8;

  dh = rob3();
  tau = calcInverseDynamicsLg(dh,[0 0 0]',[0 0 0]',[0 0 0]',[0 0 0]');
  if (norm(clean(tau - [0 0 0]')) == 0) t = t(t~=1); end

  tau = calcInverseDynamicsLg(dh,[0 0 0]',[0 0 0]',[1 0 0]',[0 0 0]');
  if (norm(clean(tau - [9 6 0]')) == 0) t = t(t~=2); end

  tau = calcInverseDynamicsLg(dh,[0 0 0]',[0 0 0]',[0 1 0]',[0 0 0]');
  if (norm(clean(tau - [6 4 0]')) == 0) t = t(t~=3); end

  tau = calcInverseDynamicsLg(dh,[0 0 0]',[0 0 0]',[0 0 1]',[0 0 0]');
  if (norm(clean(tau - [0 0 1]')) == 0) t = t(t~=4); end

  tau = calcInverseDynamicsLg(dh,[0 0 0]',[0 0 0]',[0 0 0]',[0 -1 0]');
  if (norm(clean(tau - [3 2 0]')) == 0) t = t(t~=5); end

  dh(3).inertiaTensor = eye(3,3);
  tau = calcInverseDynamicsLg(dh,[0 0 0]',[0 0 0]',[1 0 0]',[0 0 0]');
  if (norm(clean(tau - [10 7 0]')) == 0) t = t(t~=6); end

  dh = rob3();
  dh(3).centerOfMass = [1 1 0]';
  tau = calcInverseDynamicsLg(dh,[0 0 0]',[0 0 0]',[1 0 0]',[0 0 0]');
  if (norm(clean(tau - [16 12 0]')) == 0) t = t(t~=7); end

  dh(2).mass = 2;
  tau = calcInverseDynamicsLg(dh,[0 0 0]',[0 0 0]',[1 0 0]',[0 0 0]');
  if (norm(clean(tau - [24 16 0]')) == 0) t = t(t~=8); end

  if (size(t) == 0)
	disp(['[MatNr: ', num2str(matNr),  '] Test erfolgreich.']);
  else
	disp(['[MatNr: ', num2str(matNr),  '] Fehler in Testfall/Testfällen ' ,num2str(t)]);
  end

  %% Beispielroboter 1, der von T6 verwendet wird
  function rob = rob3()
	rob(1).theta = 0;
	rob(1).alpha = 0;
	rob(1).a = 1;
	rob(1).d = 0;
	rob(1).rho = 1;
	rob(1).mass = 0;
	rob(1).centerOfMass = [0 0 0]';
	rob(1).inertiaTensor = zeros(3,3);
	rob(2).theta = 0;
	rob(2).alpha = 1 * pi/2;
	rob(2).a = 1;
	rob(2).d = 0;
	rob(2).rho = 1;
	rob(2).mass = 0;
	rob(2).centerOfMass = [0 0 0]';
	rob(2).inertiaTensor = zeros(3,3);
	rob(3).theta = 0;
	rob(3).alpha = 0;
	rob(3).a = 1;
	rob(3).d = 0;
	rob(3).rho = 1;
	rob(3).mass = 1;  
	rob(3).centerOfMass = [0 0 0]';
	rob(3).inertiaTensor = zeros(3,3);
  end
end

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 26. Jan 2011 00:11
von MuldeR
MisterD123 hat geschrieben:du schreibst dir einfach ne funktion, die (mit benutzung von numdiff) den inneren ausdruck dL/dqdot_i - dL/dq_i zum zeitpunkt t berechnet. Die funktion übergibst du dann nochmal an numdiff und leitest sie nach der zeit ab.
Aber wie führe ich denn dann die "äußere" Ableitung durch?

Wenn numdiff() immer nach dem ersten Parameter ableitet, müsste ich ja in diesem Fall 't' angeben. Nur tritt hier doch 't' gar nicht als Argument auf...

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 26. Jan 2011 02:13
von MisterD123
richtig, die aufgabe ist mehr als nur die formel abzuschreiben :) du hast q(t0), qdot(t0) und qdotdot(t0), damit kannst du, wenn du qdotdot mal als konstant annimmst, dir q(t) und qdot(t) hinreichend konstruieren, damit man die formeln numerisch in t=t0 ableiten kann.

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 26. Jan 2011 08:49
von TCE
Muss ich die numdiff-Aufrufe eigentlich in eine for-Schleife packen und immer nur q(i) oder gdot(i) übergeben. oder kann ich auch den gesamten Vektor q oder qdot an numdiff übergeben.

Re: P7: Syntax zur Verwendung von numdiff() ?

Verfasst: 26. Jan 2011 11:49
von cpunkt
Ich dachte das man die Formel einfach konkret umsetzen kann und damit die Ableitung nach t umgeht. Also erst die Ableitungen nach \(q\) und \(\dot q\) berechnen und dann mit dem entsprechenden Wert multipliziern:
\(\frac{d}{dt} \frac{d K}{d \dot q_i} = \frac{d K}{d q_i} \cdot \dot q_i + \frac{d K}{d \dot q_i} \cdot \ddot q_i\)

Leider bin ich noch nicht dazu gekommen das zu überprüfen, weil ich numdiff() noch nicht zum laufen bekomme.
Ich habe jetzt eine wrapper-Funktion, die auch nur einen Vektor zurückgibt, also zB :

function k = f(a,b,c,d)
[p,k] = g(b, a, c, d)
end
Wenn ich dann numdiff(f, w, x, y, z) aufrufe, bekomme ich die Fehlermeldung, dass x nicht definiert ist. Ich hänge also an der Übergabe der übrigen Argumente...
Wie habt ihr das gemacht?