Hur kan jag få tag på prestandaversionen av Nucleo?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
DanielM
Inlägg: 2192
Blev medlem: 5 september 2019, 14:19:58

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av DanielM »

Som jag ser så verkar inget orsaka. Det kanske inte är så att jag "kör för snabbt"?
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av Mr Andersson »

Nej du "kör inte för snabbt" om du inte medvetet överklockat processorn.
Mest troligt skriver du (eller tredjepartskod) till nånting du inte får röra, t.ex. en periferienhet som inte är startad.
Du får ett imprecise fault för att processorn kan inte säga exakt var felet inträffade, t.ex. på grund av write buffering.
Se http://infocenter.arm.com/help/topic/co ... UI0553.pdf ACTLR.DISDEFWBUF
When set to 1, disables write buffer use during default memory map accesses. This causes all
BusFaults to be precise BusFaults
but decreases performance because any store to memory must
complete before the processor can execute the next instruction.
Det skulle också kunna vara felkonfigurerad DMA.
DanielM
Inlägg: 2192
Blev medlem: 5 september 2019, 14:19:58

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av DanielM »

Min beräkningar utförs via qpOASES och qpOASES använder rekrusiva funktioner - mycket.

Så kanske jag ska titta mer på en annan algoritm som inte är rekrusiv?

Använde inte DMA då.
bearing
Inlägg: 11253
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av bearing »

Här hade det ju varit lämpligt att på något vis nämna att vad du skrev häromdan om rekursiv kod (då du tvärsäkert hävdade att rekursiv inte användes) inte stämde. Annars ser ju det här senaste inlägget mycket märkligt ut.
DanielM
Inlägg: 2192
Blev medlem: 5 september 2019, 14:19:58

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av DanielM »

Alltså jag skriver inte rekrusiv kod. Att QpOASES_e som hävdar att det är skapat för embedded, utan att tala om att funktionerna anropar sig själv, är inte mitt fel.

Just nu funderar jag på att använda Gradient Descent.
Rick81
Inlägg: 746
Blev medlem: 30 december 2005, 13:07:09

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av Rick81 »

Om det är rekursiva anrop, så öka stacken rejält (i .ld filen) och se om det hjälper.

Kolla också att de inte använde malloc nånstans i det biblioteket.
DanielM
Inlägg: 2192
Blev medlem: 5 september 2019, 14:19:58

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av DanielM »

Nu har jag löst problemet! Jag bytte ut följande:

\(min \frac{1}{2}u^THu + c^Tu\)
S.T
\(lb \le u \le ub \\ lba \le Au \le uba\)

Mot
\(\max : (A^TA + \alpha I)^Tb x\)
With S.t to:
\((A^TA + \alpha I)x \le A^Tb \\ x \ge 0\)

Sedan skrev jag en algorithm som optimerar att lösa en \(Ax=b\) ekvation. Testa den vet ja!

Skapa en array \(A\), vector \(b, c\) och stoppa in dom i funktionen tillsammans med lösningsvektorn \(x\).
Då ska \(x \ge 0\) och \(Ax \le b\). Jag använder endast 1D arrayer.

Kod: Markera allt

void linprog(float* c, float* A, float* b, float* x, int row_a, int column_a, int iteration_limit){

	// Clear the solution
	memset(x, 0, column_a*sizeof(float));

	// Create the tableau with space for the slack variables s and p as well
	float tableau[(row_a+1)*(column_a+row_a+2)]; // +1 because the extra row for objective function and +2 for the b vector and slackvariable for objective function
	memset(tableau, 0, (row_a+1)*(column_a+row_a+2)*sizeof(float));

	// Load the constraints
	int j = 0;
	for(int i = 0; i < row_a; i++){
		// First row
		memcpy(tableau + i*(column_a+row_a+2), A + i*column_a, column_a*sizeof(float));

		// Slack variable s
		j = column_a + i;
		tableau[i*(column_a+row_a+2) + j] = 1;

		// Add b vector
		tableau[i*(column_a+row_a+2) + (column_a+row_a+2-1)] = *(b+i);
	}

	// Negative objective function
	for(int i = 0; i < column_a; i++){
		tableau[(row_a+1-1)*(column_a+row_a+2) + i] = -*(c +i);
	}
	// Slack variable for the objective function
	tableau[(row_a+1-1)*(column_a+row_a+2) + (column_a+row_a+2-2)] = 1;
	// Done!

	// Do row operations
	float entry = 0.0;
	int pivotColumIndex = 0;
	int pivotRowIndex = 0;
	float pivot = 0.0;
	float value1 = 0.0;
	float value2 = 0.0;
	float value3 = 0.0;
	float smallest = 0.0;
	int count = 0;
	do{
		// Find our pivot column
		pivotColumIndex = 0;
		entry = 0.0;
		for(int i = 0; i < (column_a+row_a+2) -1; i++){ // -1 because we don't want to count with the last column
			value1 = *(tableau + (row_a+1-1)*(column_a+row_a+2) + i); // Bottom row
			if(value1 < entry){
				entry = value1;
				pivotColumIndex = i;
			}
		}
		// If the smallest entry is equal to 0 or larger than 0, break
		if(entry >= 0.0 || count >= iteration_limit)
			break;

		// Find our pivot row
		pivotRowIndex = 0;
		value1 = *(tableau + 0*(column_a+row_a+2) + pivotColumIndex); // Value in pivot column
		value2 = *(tableau + 0*(column_a+row_a+2) + (column_a+row_a+2-1)); // Value in the b vector
		smallest = value2/value1; // Initial smallest value
		for(int i = 1; i < row_a; i++){
			value1 = *(tableau + i*(column_a+row_a+2) + pivotColumIndex); // Value in pivot column
			value2 = *(tableau + i*(column_a+row_a+2) + (column_a+row_a+2-1)); // Value in the b vector
			value3 = value2/value1;
			if( (value3 > 0  && value3 < smallest ) || smallest < 0 ){
				smallest = value3;
				pivotRowIndex = i;
			}
		}

		// We know where our pivot is. Turn the pivot into 1
		// 1/pivot * PIVOT_ROW -> PIVOT_ROW
		pivot = *(tableau + pivotRowIndex*(column_a+row_a+2) + pivotColumIndex); // Our pivot value
		for(int i = 0; i < (column_a+row_a+2); i++){
			value1 = *(tableau + pivotRowIndex*(column_a+row_a+2) + i); // Our row value at pivot row
			*(tableau + pivotRowIndex*(column_a+row_a+2) + i) = value1 * 1/pivot; // When value1 = pivot, then pivot will be 1
		}

		// Turn all other values in pivot column into 0. Jump over pivot row
		// -value1* PIVOT_ROW + ROW -> ROW
		for(int i = 0; i < row_a + 1; i++){
			if(i != pivotRowIndex){
				value1 = *(tableau + i*(column_a+row_a+2) + pivotColumIndex); // This is at pivot column
				for(int j = 0; j < (column_a+row_a+2); j++){
					value2 = *(tableau + pivotRowIndex*(column_a+row_a+2) + j); // This is at pivot row
					value3 = *(tableau + i*(column_a+row_a+2) + j); // This is at the row we want to be 0 at pivot column
					*(tableau + i*(column_a+row_a+2) + j) = -value1*value2 + value3;
				}
			}
		}

		// Count for the iteration
		count++;

	}while(entry < 0); // Continue if we have still negative entries

	// Now when we have shaped our tableau. Let's find the optimal solution. Sum the columns
	for(int i = 0; i < column_a; i++){
		value1 = 0; // Reset
		for(int j = 0; j < row_a + 1; j++){
			value1 += *(tableau + j*(column_a+row_a+2) + i); // Summary
			value2 = *(tableau + j*(column_a+row_a+2) + i); // If this is 1 then we are on the selected

			// Check if we have a value that are very close to 1
			if(value1 < 1.00001 && value1 > 0.99999 && value2 > 0.99999){
				*(x + i) = *(tableau + j*(column_a+row_a+2) + (column_a+row_a+2-1));
			}
		}
	}


}
Rick81
Inlägg: 746
Blev medlem: 30 december 2005, 13:07:09

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av Rick81 »

Bra att det löste sig!

Hur lång tid tar det köra beräkningarna på STM32h7?
DanielM
Inlägg: 2192
Blev medlem: 5 september 2019, 14:19:58

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av DanielM »

Jag har inte köpt ett sådant kort. Tyvärr.
Jag vet dessutom inte hur man kollar cykeltiden i Atollic.

Tänker kanske köpa en STM32 Nucleo 32. Bara för att se om där fungerar att ha en adaptiv modellprediktiv regulator med integralfunktion :)

MPC är oftast implementerade i stora dyra tunga system.
Rick81
Inlägg: 746
Blev medlem: 30 december 2005, 13:07:09

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av Rick81 »

Så du har kört på STM32f4 nu?

Vet inte om det finns nåt inbyggt i Atollic men annars brukar man ju:
* Sätta en GPIO vid start och nollställa efter beräkning och sedan mäta med oscilloskop hur puslen blir
* Använda systicks (eller timer ticks) men då måste man ju veta man konfat rätt
* Köra operationen många gånger och mäta med tidtagarur, men då måste man ju köra så många gånger att man kan mäta så det tar några sekunder och sedan dividera med antal forloppar. Också se köra volatile på int i om man kör for(i = 0...) så inte kompilator optimerar bort det

Finns så klart fler alternativ...
DanielM
Inlägg: 2192
Blev medlem: 5 september 2019, 14:19:58

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av DanielM »

Jag har en LCD så jag kan testa skriva ut på den.

Men jag finner inget behov utav att titta tiderna på en mikrokontroller. Så länge den gör sin iteration så är det lungt.

Har du testat algoritmen? :)
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45291
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av TomasL »

Varför skall man testa en sak, som man inte har behov av, dessutom, använder den float, som är ett no-go i de allra flesta system.
bearing
Inlägg: 11253
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av bearing »

Fast det där förändras tack vare utvecklingen av beräkningsprestanda på små billiga mikrocontrollers. Och vissa operationer går ju faktiskt fortfare på flyttal än heltal.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45291
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av TomasL »

Men dt förutsätter att du har en flyttalsprocessor, annars går det garanterat långsammare, med flera magnituder.
Rick81
Inlägg: 746
Blev medlem: 30 december 2005, 13:07:09

Re: Hur kan jag få tag på prestandaversionen av Nucleo?

Inlägg av Rick81 »

Har inte testat algoritmen, men denna tråd ( och flera trådar) handlar ju om det går att köra dina beräkningar på en inbyggd processor jämfört med PC och Raspberyy pi så det vore ju intressant äntligen få svaret.
Så länge den gör sin iteration så är det lungt.
Förstår inte vad du menar? Det tar mindre än en sekund?
Skriv svar