[arduino] Servo controller maken, PID niet toereikend?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
Hallo allemaal,

Ik ben bezig met een stuurinrichting te maken, waarbij ik een ruitenwissermotor gebruik als stuurmotor.
Ik heb een potmeter op de as bevestigd om feedback over zijn positie te krijgen.

Nu dacht ik dat het een eitje zou zijn om hier een servo-achtige besturing van te maken. Dit blijkt echter een stuk lastiger dan gedacht..

Ik vroeg me af waarom ik zo'n enorme overshoot bleef krijgen en besloot wat metingen te maken.

deze kun je hier zien
blauw = potmeter
rood = pulse ( output )
geel = negeer

horizontale as = ms

Wat opvalt is dat de motor pas zeer laat op gang komt, ik vraag me af of dit nog op te vangen is mbv. een PID controller, of dat ik naar andere methoden moet kijken.

Hopelijk kunnen jullie mij helpen, als er meer metingen nodig zijn graag even aangeven, ik probeer vanavond wat nieuwe metingen te maken.

alvast bedankt!

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • lemming_nl
  • Registratie: Juli 2004
  • Niet online
Voor jouw website is een wachtwoord vereist. Wij kunnen daar dus niet bij.

Wat is je huidige regelschema?

Geluk is een weerloos oud vrouwtje, alleen op straat met een bom geld


Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
lemming_nl schreef op maandag 02 april 2012 @ 10:54:
Voor jouw website is een wachtwoord vereist. Wij kunnen daar dus niet bij.
:? Het is een simpele html pagina + google chart meuk, heb het via 3 verschillende internetverbindingen getest, maar een wachtwoord requester ben ik nog niet tegengekomen..
Wat is je huidige regelschema?
Ik heb zelf wat geprobeerd en vervolgens een PID implementatie opgezet op basis van http://arduino.cc/playground/Code/PIDLibrary

Maar omdat ik nooit zinnige resultaten kreeg ben ik deze metingen gaan uitvoeren, waarvoor ik simpelweg een pulse van 20/100ms gaf en de waardes wegschreef in de hoop erachter te komen waarom ik geen goede resultaten kreeg.

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • bobo1on1
  • Registratie: Juli 2001
  • Laatst online: 18-05 17:57
Het probleem wat je hier hebt is als je spanning op de motor zet, hij accelereert tot een bepaalde snelheid, terwijl de potmeter de positie teruggeeft, het signaal wat je terugkrijgt is dus al bijna een integraal van de uitgang.

Probeer eerst maar eens een simpele proportionele regeling stabiel te krijgen, en als dat niet voldoet kun je altijd nog een volledige PID gebruiken.
Wat ook helpt om het stabiel te krijgen is de proportionele regeling verminderen als je dichter bij het setpoint komt.

Impedance, a measure of opposition to time-varying electric current in an electric circuit.
Not to be confused with impotence.


Acties:
  • 0 Henk 'm!

  • Sissors
  • Registratie: Mei 2005
  • Niet online
Als je delay hebt kom je vaak nog best ver met een PI regelaar (de D wil je dan meestal wel eruit laten), als het snel moet zijn moet je nog wat extras toevoegen, maar dat ligt aan je eisen. Maar het zou handig zijn als we de grafiek konden zien, ik krijg enkel 403 forbidden pagina.

Als je goed een PID regelaar wil maken moet je toch kijken hoe je systeem precies reageert. Maar wat ik zou doen is wat bobo zegt, kijk eerst eens naar proportionele regeling. En daarna kan je dan misschien nog wat integerende toevoegen (ja ik weet dat effectief dubbel integreren het geheel niet noodzakelijkerwijs stabieler maakt, maar differentieren bij een flinke delay maakt het er ook niet beter op).

Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
Ik snap niet dat er problemen zijn met de pagina, maar ik heb de broncode van de pagina geupload op pastbin, dus voor wie de pagina niet kan zien: http://pastebin.com/X1j6atY6
bobo1on1 schreef op maandag 02 april 2012 @ 11:33:
[...]
Probeer eerst maar eens een simpele proportionele regeling stabiel te krijgen, en als dat niet voldoet kun je altijd nog een volledige PID gebruiken.
Wat ook helpt om het stabiel te krijgen is de proportionele regeling verminderen als je dichter bij het setpoint komt.
Zoiets heb ik geprobeerd maar wellicht niet correct.

code:
1
2
3
4
int error = target - analogRead( A0 );
if ( error < 0 ) stuurlinks
else if ( error > 0 ) stuurrechts
else niet_sturen

En variaties waarbij ik PWM gebruik afhankelijk van de grootte van error.
Het probleem bij de PWM variaties is dat de motor niet start onder een bepaalde waarde en vooral mijn H-brug het erg warm krijgt.. Waarschijnlijk helpt het als ik de PWM frequentie naar beneden schroef, maar het liefst zou ik het geheel zonder PWM werkend krijgen ( KISS ).

Ik heb dus ook variaties geprobeerd waarbij ik de motor stop nog voordat de target bereikt is, maar dit moment is dus heel erg afhankelijk van de belasting / motorsnelheid.

[ Voor 7% gewijzigd door Arjan op 02-04-2012 12:14 ]

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • bobo1on1
  • Registratie: Juli 2001
  • Laatst online: 18-05 17:57
Bij zo'n simpele regeling zal je wel een bepaalde toegestane foutmarge moeten inbouwen, anders blijft de motor steeds heen en weer bewegen, en zal je de motor uit moeten zetten als hij binnen een bepaalde afstand van het setpoint komt, en die afstand is ook nog eens afhankelijk van de snelheid.

Het beste kun je de motor kortsluiten als je wilt dat hij stopt, maar daar moet je misschien de H-brug voor aanpassen, als je mosfets gebruikt kun je simpelweg de twee onderste of bovenste mosfets tegelijk aanzetten.

Impedance, a measure of opposition to time-varying electric current in an electric circuit.
Not to be confused with impotence.


Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
Ik ben aan het experimenteren met het ompolen van de motor om deze te laten stoppen.
Dit geeft zeer hoopgevende resultaten, maar ik vraag me af waar ik rekening mee moet houden als ik mijn elektronica heel wil houden.. iemand die mij daar meer over kan vertellen :?

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • bobo1on1
  • Registratie: Juli 2001
  • Laatst online: 18-05 17:57
De stroom door de motor wordt groter, zorg dat de H-brug en voeding dat aankunnen, dat is eigenlijk alles.

Impedance, a measure of opposition to time-varying electric current in an electric circuit.
Not to be confused with impotence.


Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
hm, ik kom er nog niet uit, ik heb nu dit:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
void loop()
{
    static unsigned long last = millis();

    // loop 5ms
    while ( ( now = millis() ) < ( last + 5 ) ) { }

    const int dt = now - last;
    last = now;

    int rawValue = read( A0, 16 );
    static int lastRawValue = rawValue;

    // decrease sensitivity
    rawValue >>= 2;
    rawValue <<= 2;

    // distance to target
    int error = target - rawValue;

    int speed = rawValue - lastRawValue;

    // speed of movement ( scale to compensate )
    const int scaledSpeed = speed * 32 / dt;

    // if error < speed, the sign changes so the steering brakes
    int output = error - scaledSpeed;

    // check if accelerating
    if ( ( output < 0 ) == ( scaledSpeed < 0 ) )
    {
        if ( abs( output ) < 10 ) output = 0;
    }

    // pulse for debugging purpouses
    int pulse = 0;

    if ( output < 0 )
    {
        digitalWrite( 5, true );
        digitalWrite( 6, false );
        pulse = 50;
    }
    else if ( output > 0 )
    {
        digitalWrite( 5, false );
        digitalWrite( 6, true );
        pulse = -50;
    }
    else
    {
        digitalWrite( 5, false );
        digitalWrite( 6, false );
    }

    Debug() << "[" << now
            << ",\t" << rawValue
            << ",\t" << scaledSpeed
            << ",\t" << target + error
            << ",\t" << pulse
            << "],";

    lastRawValue = rawValue;
}


met dit als resultaat: http://arjanhouben.nl/arduino.html

Ik heb zelf met allerlei variabelen zitten spelen, maar heb het idee dat ik in een cirkeltje zit te redeneren..
Iemand enige suggestie hoe ik die oscillatie eruit kan halen?

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • Sissors
  • Registratie: Mei 2005
  • Niet online
met dit als resultaat: http://arjanhouben.nl/arduino.html
Vanaf een andere computer met andere internet verbinding, andere browser en ander OS: 403 forbidden.

Echt waar jouw site is ontoegankelijk.

Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
furby-killer schreef op woensdag 04 april 2012 @ 09:18:
[...]
Echt waar jouw site is ontoegankelijk.
Vervelend dit, ik snap het niet zo goed gezien het volgende:
http://validator.w3.org/c...en.nl%2Farduino.html;ss=1
http://www.downforeveryon...janhouben.nl/arduino.html
gewoon werkt..

resolved arjanhouben.nl bij diegene waar het niet werkt ook gewoon naar 84.28.15.87?

iig, voor wie zich de moeite wil nemen: http://pastebin.com/r6ynSF26

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • Rmg
  • Registratie: November 2003
  • Laatst online: 10:52

Rmg

Arjan schreef op woensdag 04 april 2012 @ 00:06:
hm, ik kom er nog niet uit, ik heb nu dit:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
void loop()
{
    static unsigned long last = millis();

    // loop 5ms
    while ( ( now = millis() ) < ( last + 5 ) ) { }

    const int dt = now - last;
    last = now;

    int rawValue = read( A0, 16 );
    static int lastRawValue = rawValue;

    // decrease sensitivity
    rawValue >>= 2;
    rawValue <<= 2;

    // distance to target
    int error = target - rawValue;

    int speed = rawValue - lastRawValue;

    // speed of movement ( scale to compensate )
    const int scaledSpeed = speed * 32 / dt;

    // if error < speed, the sign changes so the steering brakes
    int output = error - scaledSpeed;

    // check if accelerating
    if ( ( output < 0 ) == ( scaledSpeed < 0 ) )
    {
        if ( abs( output ) < 10 ) output = 0;
    }

    // pulse for debugging purpouses
    int pulse = 0;

    if ( output < 0 )
    {
        digitalWrite( 5, true );
        digitalWrite( 6, false );
        pulse = 50;
    }
    else if ( output > 0 )
    {
        digitalWrite( 5, false );
        digitalWrite( 6, true );
        pulse = -50;
    }
    else
    {
        digitalWrite( 5, false );
        digitalWrite( 6, false );
    }

    Debug() << "[" << now
            << ",\t" << rawValue
            << ",\t" << scaledSpeed
            << ",\t" << target + error
            << ",\t" << pulse
            << "],";

    lastRawValue = rawValue;
}


met dit als resultaat: http://arjanhouben.nl/arduino.html

Ik heb zelf met allerlei variabelen zitten spelen, maar heb het idee dat ik in een cirkeltje zit te redeneren..
Iemand enige suggestie hoe ik die oscillatie eruit kan halen?
Of leven met een kleine error, hysterese toevoegen. Of toch het I component in je PD regeling toevoegen. Hou tien cycles je error bij en reageer daarop bij

Acties:
  • 0 Henk 'm!

Verwijderd

Arjan schreef op woensdag 04 april 2012 @ 09:52:
[...]

Vervelend dit, ik snap het niet zo goed gezien het volgende:
http://validator.w3.org/c...en.nl%2Farduino.html;ss=1
http://www.downforeveryon...janhouben.nl/arduino.html
gewoon werkt..

resolved arjanhouben.nl bij diegene waar het niet werkt ook gewoon naar 84.28.15.87?

iig, voor wie zich de moeite wil nemen: http://pastebin.com/r6ynSF26
IPv6 fuckup denk ik ;)

Pinging arjanhouben.nl [2a01:7c8::beef]

Acties:
  • 0 Henk 'm!

  • Sissors
  • Registratie: Mei 2005
  • Niet online
Upload dan ofzo een screenshot desnoods, handiger dan je source code.

Hij resolved wel gewoon naar dat IP hier.

[ Voor 24% gewijzigd door Sissors op 04-04-2012 10:45 ]


Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
Ik heb de ipv6 entry weggehaald bij de dns server, aangezien ik nog geen ipv6 adres krijg. ( geen idee waar de default entry vandaan kwam )
Dus wellicht dat het binnenkort voor iedereen weer werkt.

Probleem met een screenshot is het feit dat de data handig is in detail als in overview en dat lukt niet goed in een screenshot. Wat betreft de broncode ( neem aan dat je de pastebin html bedoeld ) dat is gewoon opslaan als html en openen met je browser.

Het probleem dat ik met name ervaar, is dat ik voor een enkele stuurbeweging wel iets kan bedenken.
Dus stilstand -> ga naar positite X -> stop op positie X.

Echter, een dergelijke oplossing is in de praktijk te star op te reageren op:
stilstand -> ga naar positite X -> onderweg -> ga naar positie Y -> stop op positie Y.
Hierbij zijn de snelheden / opgebouwde momentum lastiger te anticiperen en kom ik dus weer in een oscillerende situatie terecht :(
Rmg schreef op woensdag 04 april 2012 @ 09:53:
[...]
Of toch het I component in je PD regeling toevoegen. Hou tien cycles je error bij en reageer daarop bij
Dit ga ik maar eens proberen :)

vvv

eerste stabiele versie is een feit!
http://arjanhouben.nl/succes.html
nu nog tweaken zodat hij wat energiezuiniger wordt...

bijbehorende code:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const int errorCount = 20;
int errc = 0;
int errors[ errorCount ];

void loop()
{
    static unsigned long last = millis();

    // loop 5ms
    while ( ( now = millis() ) < ( last + 5 ) ) { }

    const int dt = now - last;
    last = now;

    int rawValue = read( A0, 16 );
    static int lastRawValue = rawValue;

    // distance to target
    errors[ errc % errorCount ] = target - rawValue;

    if ( abs( errors[ errc % errorCount ] ) < 10 ) errors[ errc % errorCount ] = 0;

    while ( errc < (errorCount - 1) )
    {
        errors[ errc + 1 ] = errors[ errc ];
        ++errc;
    }
    ++errc;
    int error = 0;
    for ( int c = 0; c < errorCount; ++c ) error += errors[ c ];
    error /= errorCount;

    // speed of movement ( scale to compensate )
    const int speed = ( rawValue - lastRawValue ) * 120 / dt;

    // if errors < speed, the sign changes so the steering brakes
    int output = error - speed;
    if ( !error ) output = 0;

    // pulse for debugging purpouses 
    int pulse = 0; 

    etc...

[ Voor 48% gewijzigd door Arjan op 04-04-2012 17:18 ]

oprecht vertrouwen wordt nooit geschaad


Acties:
  • 0 Henk 'm!

  • Sissors
  • Registratie: Mei 2005
  • Niet online
Heb maar even de moeite enomen om dat te doen, en ik moet zeggen dat ik niet echt inzie waarom een screenshot niet voldoende zou zijn, ik heb niet neiging gehad in te zoomen. Het zou handiger zijn om target ook te hebben in dat grafiekje, dan kan je de raw value met target vergelijken.

Je Kan gewoon natuurlijk groter gebied opgeven waarin hij het wel goed moet vinden. Probleem blijft ook dat met jouw absolute regeling het lastig is een beetje nauwkeurig te maken.

Acties:
  • 0 Henk 'm!

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

Topicstarter
furby-killer schreef op woensdag 04 april 2012 @ 15:13:
[...]
Je Kan gewoon natuurlijk groter gebied opgeven waarin hij het wel goed moet vinden. Probleem blijft ook dat met jouw absolute regeling het lastig is een beetje nauwkeurig te maken.
Hier een run waarbij ik met een potmeter verschillende targets instel.
Ik merk vooral bij kleine aanpassingen dat er veel correcties nodig zijn.

Ik heb zelf niet echt het gevoel hier nog veel aan te kunnen tweaken, hoewel er nu veel nodeloos geremd wordt.
Als iemand daar nog ideeen over heeft hoor ik ze graag :)

hier de run http://arjanhouben.nl/response.html
( hoop dat de dns problemen voor iedereen nu weg zijn )

oprecht vertrouwen wordt nooit geschaad

Pagina: 1