Brushless Gimbal Controller - SOFTWARE

Status
Nicht offen für weitere Antworten.

meister

Erfahrener Benutzer
Hallo zusammen

Frage: Software für B-Gimbul und BruGi verwirrt mich etwas. Ich habe ein Martinez-Board. Ist nun die BruGi-Software die richtige Wahl oder geht auch die B-Gimbal-Version?

Danke für eine kurze Aufklärung und Gruss
Robert

http://code.google.com/p/b-gimbal/:
B-Gimbal is a GUI application for RC FAN2/Lonestar/Alois gimbal controller software, and is written in Visual Basic 6 for Windows environment.

http://code.google.com/p/brushless-gimbal/
Brushless Gimbal Controller by Ludwig Färber (Hardware and Software) , Alexander Rehfeldt (Software) and Christian Winkler (Software)
 

OlliW

Erfahrener Benutzer
es sind zwei Dinge zu unterscheiden

1) die Software/Firmware mit welcher das BG-Controllerboard (bei dir Martinez Board) läuft
2) die GUI Software welche auf einem PC läuft

bei 1) gibt es open source nur BruGi
=> in jedem Fall benutzt du BruGi für dein Martinez Board

bei 2) gibt es ZWEI verschiedene GUI's, welche Beide mit BruGi zusammenarbeiten, d.h. im Prinzip das Gleiche machen:
- die von meister, welche beim BruGi.zip mit dabei ist
- das grüne B-Gimbal von quadraf, welches du dir extra downloaden musst
=> welche der GUI's du benutzt ist reine Geschmacksfrage
 

rdeutsch

Erfahrener Benutzer
Hallo meister und OlliW

Vielen Dank für die schnellen Antworten.
Nun ist mir klar, welche die Richtige ist. Habe bisher auch die BruGi installiert, war mir aber aufgrund der B-Gimbal-Updatemeldung nicht mehr sicher.

Grüsse
Robert
 

quadraf

Erfahrener Benutzer
Den BruGi software ist firmware inclusive standard GUI Blg-tool.
B-Gimbal ist nur ein alternatieve zum Blg-tool GUI und hat was andere visual tools und der moglichkeit Definitions an zu passen, aber im grunde gleich an Blg-tool.
Probiert mahl beide GUI aus und du wirdt es sehn...;)

Hans

Edit: Oops, der frage wurde schon beantwortet...
 
Zuletzt bearbeitet:

ahahn

Erfahrener Benutzer
Power Scaling: möchte jemand ein neues Feature testen?

Hallo Leute,

bei der derzeitigen BruGi sind Schwankungen der Versorgungsspannung immer wieder problematisch.
Die Einstellung richtigen Regler Parameter hängt von der Motorleistung ab und diese verändert sich leider, zum Beispiel, wenn während des Fluges die Akkusspannung sinkt.
Die beste Abhilfe ist derzeit eine extra Stabilisierung der BruGi Versorgung, z.B. mit einem BEC auf 8V (Jeti, Castle BEC).

Ich hab nun eine Variante ausprobiert, welche ohne externer Stabiliserung auskommt.
Das neue Feature habe ich "Power Scaling" genannt.

Bei dieser Software wird die Motorleistung von der aktuellen Akkusspannung abhängig gemacht d.h. es wird die Akkuspannung gemessen und davon abhängig wird die PWM Einstellung der Motoren laufend angepasst.

Am Tisch, mit dem Netzgerät funktioniert es sehr gut. Im Flug habe ich es allerdings noch nicht probieren können (bei meinem Mikrokopter ist ein Motor gestorben).

Den Code gibt es erst einmal hier als Testversion zum Herunterladen.

BruGi_049B_r166.zip
https://www.dropbox.com/s/8qkiw2gw4bsprv9/BruGi_049B_r166.zip

Bitte beachtet dass die blg-tool GUI nur provisorisch geändert ist. Falls das neue Feature Sinn macht wird meister die GUI sicherlich noch feintunen.

Und jetzt kommt die schlechte Nachricht ;.)
Für das Power Scaling ist eine kleiner Hardwarezusätz nötig, es müssen zwei Widerstände nachgerüstet werden.
Ein Spannungsteiler von der Versorgungsspannung zum A3 (MULTI) Eingang, mit R1=10k und R2=2.2k.

Die beiliegende Bilder zeigen den Umbau für das Martinez Board und für das RC-Timer Board.

Was ist in der GUI tun ?

(1.) Die Brugi Parameter wie gewohnt einstellen.
(2.) Im Settings->Motor Power, "Power Scale" aktivieren
(3.) Mit Taste "Get Battery Voltage" die aktuelle Batteriespannung lesen, diese wird als "Battery Voltage" angezeigt. Dieser Wert wird dann als Referenz (config.refVoltageBat) mit den Parametern im Flash/EEPROM mitgespeichert.
(4.) Save to Flash

Wenn die Widerstände richtig eingelötet sind sollte man mit "Get Battery Voltage" immer die aktuelle Versorgungsspannung sehen, z.B. etwa 12V bei 3S Betrieb.

Natürlich funktionierts auch ohne GUI (siehe Kommand "sbv" und parameter refVoltageBat und motorPowerScale).

Noch ein Hinweis:
Da neue Parameter hinzugekommen sind wird das EEPROM neu initialisiert und die alten Werte gehen verloren. Am besten die Paramter in der vorigen Version per "Save to File" speichern.
Und dann in der neuen per "Load from File" einlesen.


Bin schon auf Feedback gespannt :)

Alois
 

Anhänge

OlliW

Erfahrener Benutzer
ha ha, ist ja immer wieder lustig wie ähnliche Geister zu ähnlichen Lösungen kommen...
die mBGC Platine hat so nen Spannungsteiler schon mit drauf :wow:

und ja, Vmax anzupassen ist der richtige Weg! (den I Term mit der Spannung runterzunehmen bringt auch was, aber Vmax ist am Wirkungsvollsten/Wichtigsten)

Übrigens: in der PID Theorie schmeissen die Leut immer mit dem Begriff "Robustness" umher, bei uns, also den Brushless Gimbals, wird die Robustness quasi aussschliesslich durch den I Term bestimmt... also, bei einer mittleren Spannung tunen, und dann den I Term etwas runternehmen macht die Regelung "robuster", und damit auch Versorgungsspannungs unempfindlicher. Hilft auch ein gutes Stück. :)
 

OlliW

Erfahrener Benutzer
jetzt habe ich direkt mal wieder in den BruGi Code rein geschaut...
super, das ist jetzt ja richtiger Code geworden! Applaus.
und super das sich jetzt endlich jemand auch Gedanken zu den Resourcen macht! Applaus.

daher gerne ein paar Anregungen von mir

die Motor ISR zu optimieren lohnt, da sie ja sehr oft aufgerufen wird; das ist nun schon gut kurz geworden, es geht aber immer noch kürzer, das Kürzeste was mir einfiele wäre
Code:
// this saves 15 cylce or almost 1us
#define freqCounter GPIOR0
#define motorUpdate GPIOR1

ISR( TIMER1_OVF_vect , ISR_NAKED )
{
  asm volatile ("push r0");
  asm volatile ("in r0, 0x3f");
  asm volatile ("push r24");
  freqCounter++;
  if(freqCounter==(CC_FACTOR*1000/MOTORUPDATE_FREQ))
  {
    asm volatile ("ldi r24, 0x00");
    asm volatile ("out %0, r24" : : "I" (_SFR_IO_ADDR(freqCounter)) );
    motorUpdate = 1;
  }
  asm volatile ("pop r24");
  asm volatile ("out 0x3f,r0");
  asm volatile ("pop r0");
  asm volatile ("reti");
}
Das "ldi r24, 0x00" kann man sich eigentlich auch noch spaaren da r1 immer Null ist und gleich "out %0, r1" schreiben, dann sind's genau 16 Cycles die man sich spaart. Ein Gewinn von über 30% :)
(und es geht noch schneller ;))

eine andere Bemerkung, ich weis nicht wie du den ADC aufgesetzt hast, aber es steht etwas von 118 us da... das kannst du dir auch spaaren wenn du den ADC im free running mode aufsetzt... kostet gar nichts und du kannst immer einfach den ADC Wert gleich lesen (mit cli/sei natürlich)

eine letzte Bemerkung, ich habe jetzt natürlich nicht alles ins Detail durchgefieselt, aber wenn nicht irgendwo anders irgendwie an der Bedeutung von Roll und Pitch gewerkelt wird, dann ist IMHO das
Code:
void getAttiduteAngles() {
  // attitude of the estimated vector  
  // 200us
  angle[ROLL]  = ((int32_t)config.angleOffsetRoll * 10) +  Rajan_FastArcTan2_deg1000(EstG.V.X , sqrt(EstG.V.Z*EstG.V.Z+EstG.V.Y*EstG.V.Y));
  // 142 us
  angle[PITCH] = ((int32_t)config.angleOffsetPitch * 10) + Rajan_FastArcTan2_deg1000(EstG.V.Y , EstG.V.Z);

}
genau verkehrt rum, also das Wurzel-Dings gehört bei Pitch hin (ist bei mir so, und im übrigen auch bei Wii).

Viel Spass :)
 
Zuletzt bearbeitet:

ray_tracer

Erfahrener Benutzer
Für eine stabile Spannung empfehle ich ja einen Step-Up Regler. Gibt es billigst unter "LM2577" bei eBay...

Aber mit der Spannungsüberwachung könnten wir ja auch jetzt eine Abschaltschwelle für die Motortreiber definieren, wenn der Akku leer ist. Eventuell ist ja noch ein Pin für eine LED frei über die man Blink-Codes ausgeben könnte.


Grüße, Ray
 

ahahn

Erfahrener Benutzer
Danke für das Lob :)
Die 500Hz Abstastrate wurde in den vorigen Versionen nicht mehr zuverlässig erreicht, speziell wenn die RC Kanäle laufen.
Möglichweise ist das auch die Ursache für die kleinen Zuckungen, die hier jemand beoabachtet hatte.

Jedenfalls bin ich dem Ganzen etwas genauer nachgegangen und die 2ms sind jetzt wieder garantiert.

Bei der Interruptroutine macht die weitere Einsparung von Zyklen sicherlich Sinn, weil einerseits fehlt die Zeit bei der Rechengeschwindigkeit und andererseits sollte auch die Latenzzeit der RC Interrupts besser werden, und damit die RC Kanäle ruhiger.
Ich schau mir deinen Vorschlag genauer genauer an, mit den ATMega Assembler habe ich mich bisher nicht beschäftigt, wollte ich mir ersparen :) Ist aber soweit kein Problem.

Zum ADC; ist ein guter Punkt. Ich habe mit gar nicht damit beschäftigt, habe einfach den Standardaufruf genommen.
Hier habe ich aber genügend Zeit, sodass es auch so funktioniert.

Zum Wurzel-Ding;
Es funktioniert auf jeden Fall so wie es ist :)

Auf jeden Fall danke für die hilfreichen Inputs

lg
Alois


jetzt habe ich direkt mal wieder in den BruGi Code rein geschaut...
super, das ist jetzt ja richtiger Code geworden! Applaus.
und super das sich jetzt endlich jemand auch Gedanken zu den Resourcen macht! Applaus.

daher gerne ein paar Anregungen von mir

die Motor ISR zu optimieren lohnt, da sie ja sehr oft aufgerufen wird; das ist nun schon gut kurz geworden, es geht aber immer noch kürzer, das Kürzeste was mir einfiele wäre
Code:
// this saves 15 cylce or almost 1us
#define freqCounter GPIOR0
#define motorUpdate GPIOR1

ISR( TIMER1_OVF_vect , ISR_NAKED )
{
  asm volatile ("push r0");
  asm volatile ("in r0, 0x3f");
  asm volatile ("push r24");
  freqCounter++;
  if(freqCounter==(CC_FACTOR*1000/MOTORUPDATE_FREQ))
  {
    asm volatile ("ldi r24, 0x00");
    asm volatile ("out %0, r24" : : "I" (_SFR_IO_ADDR(freqCounter)) );
    motorUpdate = 1;
  }
  asm volatile ("pop r24");
  asm volatile ("out 0x3f,r0");
  asm volatile ("pop r0");
  asm volatile ("reti");
}
....
Viel Spass :)
 

ahahn

Erfahrener Benutzer
Für eine stabile Spannung empfehle ich ja einen Step-Up Regler. Gibt es billigst unter "LM2577" bei eBay...

Aber mit der Spannungsüberwachung könnten wir ja auch jetzt eine Abschaltschwelle für die Motortreiber definieren, wenn der Akku leer ist. Eventuell ist ja noch ein Pin für eine LED frei über die man Blink-Codes ausgeben könnte.


Grüße, Ray
Hallo Ray,

die Abschaltung ist ein guter Punkt. Sie ist derzeit auch schon drinnen, nur bei einem konstenten Wert, ich glaube bei 6V.
Ich dachte zuerst nur daran zu verhindern dass im USB Betrieb die Motoren zucken.
Ein programmierbare Schwelle wäre auf jeden Fall besser, ich nehm Mal in die Liste. Sollte kein Problem sein.

lg
Alois
 

OlliW

Erfahrener Benutzer
Bei der Interruptroutine macht die weitere Einsparung von Zyklen sicherlich Sinn, weil einerseits fehlt die Zeit bei der Rechengeschwindigkeit und andererseits sollte auch die Latenzzeit der RC Interrupts besser werden, und damit die RC Kanäle ruhiger. Ich schau mir deinen Vorschlag genauer genauer an,
dann mach es gleich "richtig" und lagere die if Abfrage ganz aus... statt if(motorUpdate) kannst du auch timediff= time -time last; if( timediff>=xxx) in der main loop schreiben.. ist sogar aus anderen Gründen besser... die ISR braucht dann nur noch 21 Zyklen (inkl Einsprung und RETI!!!), kürzer habe ich's jedenfalls noch nicht bekommen...
PS: dieser "Trick" mit den if Anfragen geht auch bein RC ISRs... da lässt sich auch noch einiges verbessern!
 

ahahn

Erfahrener Benutzer
dann mach es gleich "richtig" und lagere die if Abfrage ganz aus... statt if(motorUpdate) kannst du auch timediff= time -time last; if( timediff>=xxx) in der main loop schreiben.. ist sogar aus anderen Gründen besser... die ISR braucht dann nur noch 21 Zyklen (inkl Einsprung und RETI!!!), kürzer habe ich's jedenfalls noch nicht bekommen...
PS: dieser "Trick" mit den if Anfragen geht auch bein RC ISRs... da lässt sich auch noch einiges verbessern!
Du weisst es sicher, wird für time() ein Hardware Zähler verwendet ?
Wenn man die Motor PWM Counter Updates asynchron machen darf, dann kann man die ISR überhaupt weglassen.
Stimmt doch?
 

OlliW

Erfahrener Benutzer
ha, das diese Gedanken zum Arduino-Timer erst jetzt kommen... :)
dann verrate ich mal alle meine Geheimnisse... (womit euer Code in wesentlichen Punkten meinem sehr ähnlich werden wird, naja LOL)

Zunächst nur als Einschub, die Motor PWM Counter Updates werden durch die Umschichtung der If kein bischen mehr oder weniger asynchron als wie mit der If in der ISR!!!!!! Das ist gehupft wie gesprungen. Warum: in jedem Fall wird erst reagiert wenn die Haupt-Loop zur entsprechenden Abfrage kommt...
Und tatsächlich hat das gar nichts mit der "alten" micros-Zeitvergleichs-Methode in den älteren BrugiVersionen, ala Wii, zu tun! (warum kommt gleich). Es war - IMHO - ein richtiger zu der Semaphoren-Method mit motorUpdate - wie das im übrigen eigentliche jeder machen würde - überzugehen :)


Zum Problem bei/mit Arduino...
1. Arduino benutzt einen Timer und entsprechende ISR zum Zählen
2. es rechnet in der ISR eine ganze Menge, z.B. mit so Sachen wie long etc. pp
3. weil wir alle 6 PWM brachen bleibt keiner für den Arduino Counter übrig
4. wir wollen auf keinen Fall 8kHz haben, sodnern unbedingt 32 kHz haben

und jetzt die Katastrophe: um die 32kHz zu realiseren stellen wir die Timer auf fast-PWM, aber der übliche und damit auch Arduino Zeitmess-Code geht davon aus dass der Timer immer nur in EINE Richtung zählt....

durchdenke das mal kurz was da gerade gesagt wurde...

=> für die Hauptloop-Steuerung geht das mit der ISR völlig i.O. aber das mit der Zeitmessung über z.B. micros ist VÖLLIG für die Tonne!!!!

=> bei der "alten" Brugi Methode konnte das nicht gut klappen da ja der Timer selber schon unsauber zählt => die Standard Semaphoren-Metode, wie du es jetzt auch hast, ist quasi ein muss
=> die Konsequenzen für die RC-Zeitmessung sollten klar sein...

Was tun? Tja, die Zählroutine so schreiben dass sie mit hoch und runter Zählen klappt (nicht ganz einfach, meiner Meinung nach DER Grund warum es bei AlexMos etwas dauerte bis er mehr als 8kHz konnte... er wollte wohl den Timer nicht auf fast-PWM stellen)

hoffe ich habe in dem ganzen Wust auch deine Frage(n) beantwortet
:)


EDIT: auch wenn ich's glaube ich schon 2mal sagte, will ich, weil wir gerade dabei sind, nochmals draufstossen... bei mir dauert das I2C einlesen ALLER Werte (gyro+adc) 250ms... und keine 350ms oder was es ist nur für'n Gyro (und ich mache nichts besonderes!)... ;)

EDITII: sorry, gerade gemerkt, ich meine oben natürlich phase-correct PWM Modi und nicht fast PWM... mea culpa
 
Zuletzt bearbeitet:

ray_tracer

Erfahrener Benutzer
Hallo Ray,

die Abschaltung ist ein guter Punkt. Sie ist derzeit auch schon drinnen, nur bei einem konstenten Wert, ich glaube bei 6V.

Alois
Ah! Werde mal in den Code schauen...

Wo gerade dabei sind... :)

RCFAN2 hatte ein Video veröffentlicht zum Thema: Effektivere Motoransteuerung für mehr Drehmoment.
Ist der Code dafür schon im Prozess der Integration oder läuft das dann erst auf der neuen 3-Achs Hardware?

Grüße, Ray
 

ahahn

Erfahrener Benutzer
EDIT: auch wenn ich's glaube ich schon 2mal sagte, will ich, weil wir gerade dabei sind, nochmals draufstossen... bei mir dauert das I2C einlesen ALLER Werte (gyro+adc) 250ms... und keine 350ms oder was es ist nur für'n Gyro (und ich mache nichts besonderes!)... ;)
Die 386 us habe ich gemessen.
Hab den I2C Code nie genau angesehen, war schon so im Projekt, ich vermute das I2Cdev package hat zuviel Overhead.

Wo kann ich deinen I2C Code finden? Ich nehm ihn aber nur wenn gyro+acc 250 usec benötigen und nicht 250ms :)
 
Status
Nicht offen für weitere Antworten.
FPV1

Banggood

Oben Unten