einfache Frässimulation in Simulink erstellen
realtm
Forum-Newbie
Beiträge: 3
Anmeldedatum: 14.06.14
Wohnort: ---
Version: ---
Verfasst am : 14.06.2014, 16:59
Titel : einfache Frässimulation in Simulink erstellen
Hallo,
ich habe die Aufgabe eine (einfache) Frässimulation in Matlab/Simulink zu erstellen.
Dabei würde ich ein Höhenfeld aus einer Datei einlesen, und dann einen Fräser darüberfahren lassen und dann die jeweilige Spandicke zu berechnen.
Ist das prinzipiell möglich in Simulink?
Könnte man die Schnittberechnung auch in eine C++ Funktion in Simulink einbinden?
Vielen Dank!
Schönen Gruß!!
dmjr
Forum-Century
Beiträge: 199
Anmeldedatum: 02.10.12
Wohnort: ---
Version: ---
Verfasst am : 15.06.2014, 16:16
Titel :
Die Frage ist sehr allgemein gestellt und deswegen schwer zu beantworten. Ich sehe grundsätzlich keine Hindernisse. Der C++-Code kann als "S-Funktion" eingebunden werden.
P.S: Die Liste der unterstützten Compiler genau lesen, nach meiner Erfahrung nimmt da jeder Zweite das was falsches und ärgert sich dann warum Matlab keinen Compiler findet.
realtm
Themenstarter
Forum-Newbie
Beiträge: 3
Anmeldedatum: 14.06.14
Wohnort: ---
Version: ---
Verfasst am : 07.08.2014, 10:52
Titel :
Ich habe jetzt mal eine einfache Simulation in C++ geschrieben, aber irgendwie kriege ich es nicht vernünftig in eine S-Function gepackt....
Hier der Code:
Code:
#include "stdafx.h "
#include <iostream>
#include <fstream>
#include <sstream>
#include "vector.h "
#include <vector>
#ifndef M_PI
#define M_PI 3 .14159265358979323846f
#endif
class Dexel {
Vector start;
Vector end ;
Vector direction;
double length ;
public:
Dexel( Vector s, Vector e, Vector d, double l) {
start = s;
end = e;
direction = d;
length = l;
}
void SetEnd( Vector e) { end = e; length = ( end - start) .length ( ) ; }
void SetStart( Vector s) { start = s; length = ( end - start) .length ( ) ; }
Vector GetEnd( ) { return end ; }
Vector GetStart( ) { return start; }
std ::vector <Vector> circleLineCollision( const Vector pos, double radius)
{
std ::vector <Vector> cutP;
Vector2d toolPos( pos[ 0 ] , pos[ 1 ] ) ;
Vector2d d = ( Vector( end [ 0 ] , end [ 1 ] ) - Vector( start[ 0 ] , start[ 1 ] ) ) ;
Vector2d s( start[ 0 ] , start[ 1 ] ) ;
const double invDSq = 1 .0f / ( d.length ( ) *d.length ( ) ) ;
const double p = ( d*toolPos - s*d) * invDSq;
const double discriminant = p * p - ( ( ( s - toolPos) .length ( ) *( s - toolPos) .length ( ) ) - radius * radius) * invDSq;
if ( discriminant < 0 .0f) {
// Keine Kollision!
return cutP;
}
else {
const double squareRoot = sqrt ( discriminant) ;
Vector2d S1 = s + ( p - squareRoot) *d;
Vector S13D( S1[ 0 ] , S1[ 1 ] , start[ 2 ] ) ;
Vector2d S2 = s + ( p + squareRoot) *d;
Vector S23D( S2[ 0 ] , S2[ 1 ] , start[ 2 ] ) ;
cutP.push_back ( S13D) ;
cutP.push_back ( S23D) ;
double d1 = ( s - toolPos) .length ( ) ;
double d2 = ( Vector2d( end [ 0 ] , end [ 1 ] ) - toolPos) .length ( ) ;
if ( d1 <= radius && d2 <= radius)
cutP.push_back ( Vector( 0 ,0 ,0 ) ) ;
return cutP;
}
}
} ;
class DexelBoard{
std ::vector <Dexel> xBoard;
std ::vector <Dexel> yBoard;
std ::vector <Dexel> zBoard;
int substeps;
Vector position;
Vector dimension;
double precision;
Vector lastToolPos;
std ::vector <double> chip;
public:
DexelBoard( Vector pos, Vector dim, double pr, int sub) {
position = pos;
dimension = dim;
precision = pr;
substeps = sub;
lastToolPos =Vector( -100 , -100 , -100 ) ;
for ( size_t i = 0 ; i <= ( dim[ 2 ] / precision) ; i++) {
for ( size_t j = 0 ; j <= ( dim[ 1 ] / precision) ; j++) {
xBoard.push_back ( Dexel( Vector( position[ 0 ] - dimension[ 0 ] / 2 , position[ 1 ] - dimension[ 1 ] / 2 + j*precision, position[ 2 ] + dimension[ 2 ] / 2 -i*precision) ,
Vector( position[ 0 ] + dimension[ 0 ] / 2 , position[ 1 ] - dimension[ 1 ] / 2 + j*precision, position[ 2 ] + dimension[ 2 ] / 2 - i*precision) , Vector( 1 , 0 , 0 ) , dimension[ 0 ] ) ) ;
}
}
for ( size_t i = 0 ; i <= ( dim[ 2 ] / precision) ; i++) {
for ( size_t j = 0 ; j <= ( dim[ 0 ] / precision) ; j++) {
yBoard.push_back ( Dexel( Vector( position[ 0 ] - dimension[ 0 ] / 2 + j*precision, position[ 1 ] - dimension[ 1 ] / 2 , position[ 2 ] + dimension[ 2 ] / 2 -i*precision) ,
Vector( position[ 0 ] - dimension[ 0 ] / 2 + j*precision, position[ 1 ] + dimension[ 1 ] / 2 , position[ 2 ] + dimension[ 2 ] / 2 - i*precision) , Vector( 0 , 1 , 0 ) , dimension[ 0 ] ) ) ;
}
}
for ( size_t i = 0 ; i <= ( dim[ 1 ] / precision) ; i++) {
for ( size_t j = 0 ; j <= ( dim[ 0 ] / precision) ; j++) {
zBoard.push_back ( Dexel( Vector( position[ 0 ] - dimension[ 0 ] / 2 + j*precision, position[ 1 ] - dimension[ 1 ] / 2 + i*precision, position[ 2 ] + dimension[ 2 ] / 2 ) ,
Vector( position[ 0 ] - dimension[ 0 ] / 2 + j*precision, position[ 1 ] - dimension[ 1 ] / 2 + i*precision, position[ 2 ] - dimension[ 2 ] /2 ) , Vector( 0 , 0 , 1 ) , dimension[ 0 ] ) ) ;
}
}
}
bool doIntersect( Vector toolPos, double radius) {
Vector2d min = position.xy ( ) - dimension.xy ( ) / 2 ;
Vector2d max = position.xy ( ) + dimension.xy ( ) / 2 ;
Vector2d toolMin( toolPos[ 0 ] - radius, toolPos[ 1 ] - radius) ;
Vector2d toolMax( toolPos[ 0 ] + radius, toolPos[ 1 ] + radius) ;
if ( ( toolMin > min || toolMin <= max ) && ( toolMax>min || toolMax <= max ) ) {
if ( toolPos[ 2 ] <( position[ 2 ] + dimension[ 2 ] / 2 ) && toolPos[ 2 ] >( position[ 2 ] - dimension[ 2 ] / 2 ) )
return true ;
}
else return false ;
}
void output( int n) {
std ::ostringstream filename;
filename << n << ".txt ";
std ::ofstream out( filename.str ( ) .c_str ( ) ) ;
out << std ::endl ;
for ( size_t i = 0 ; i < xBoard.size ( ) ; i++) {
out << xBoard[ i] .GetStart ( ) [ 0 ] << " " << xBoard[ i] .GetStart ( ) [ 1 ] << " " << xBoard[ i] .GetStart ( ) [ 2 ] << std ::endl ;
out << xBoard[ i] .GetEnd ( ) [ 0 ] << " " << xBoard[ i] .GetEnd ( ) [ 1 ] << " " << xBoard[ i] .GetEnd ( ) [ 2 ] << std ::endl ;
}
for ( size_t i = 0 ; i < yBoard.size ( ) ; i++) {
out << yBoard[ i] .GetStart ( ) [ 0 ] << " " << yBoard[ i] .GetStart ( ) [ 1 ] << " " << yBoard[ i] .GetStart ( ) [ 2 ] << std ::endl ;
out << yBoard[ i] .GetEnd ( ) [ 0 ] << " " << yBoard[ i] .GetEnd ( ) [ 1 ] << " " << yBoard[ i] .GetEnd ( ) [ 2 ] << std ::endl ;
}
for ( size_t i = 0 ; i < zBoard.size ( ) ; i++) {
out << zBoard[ i] .GetStart ( ) [ 0 ] << " " << zBoard[ i] .GetStart ( ) [ 1 ] << " " << zBoard[ i] .GetStart ( ) [ 2 ] << std ::endl ;
out << zBoard[ i] .GetEnd ( ) [ 0 ] << " " << zBoard[ i] .GetEnd ( ) [ 1 ] << " " << zBoard[ i] .GetEnd ( ) [ 2 ] << std ::endl ;
}
}
void cut( Vector toolPos, double radius) {
if ( doIntersect( toolPos, radius) ) {
chip.clear ( ) ;
std ::vector <Vector> cutPoints;
std ::vector <int> dexelToDelete;
double dS, dE;
//xBoard
for ( size_t i = 0 ; i < xBoard.size ( ) ; i++) {
if ( xBoard[ i] .GetStart ( ) [ 2 ] < toolPos[ 2 ] ) //dexel under cutter
continue ;
std ::vector <Vector> value = xBoard[ i] .circleLineCollision ( toolPos, radius) ;
if ( value.size ( ) == 3 ) {
dexelToDelete.push_back ( i) ;
}
if ( value.size ( ) == 2 ) {
if ( value[ 0 ] [ 0 ] >=( xBoard[ i] .GetStart ( ) [ 0 ] ) && value[ 0 ] [ 0 ] <= ( xBoard[ i] .GetEnd ( ) [ 0 ] ) &&
value[ 1 ] [ 0 ] >=( xBoard[ i] .GetStart ( ) [ 0 ] ) && value[ 1 ] [ 0 ] <= ( xBoard[ i] .GetEnd ( ) [ 0 ] ) && value[ 0 ] !=value[ 1 ] ) {
cutPoints.push_back ( value[ 0 ] ) ;
cutPoints.push_back ( value[ 1 ] ) ;
dS = ( xBoard[ i] .GetStart ( ) - value[ 0 ] ) .length ( ) ;
dE = ( xBoard[ i] .GetEnd ( ) - value[ 0 ] ) .length ( ) ;
if ( dS < dE) { //value[ 0 ] näher an start...value [ 1 ] näher an End
xBoard.push_back ( Dexel( value[ 1 ] ,xBoard[ i] .GetEnd ( ) , Vector( 1 ,0 ,0 ) , ( value[ 1 ] -xBoard[ i] .GetEnd ( ) ) .length ( ) ) ) ;
xBoard[ i] .SetEnd ( value[ 0 ] ) ;
}
else {
xBoard.push_back ( Dexel( value[ 0 ] , xBoard[ i] .GetEnd ( ) , Vector( 1 , 0 , 0 ) , ( value[ 0 ] - xBoard[ i] .GetEnd ( ) ) .length ( ) ) ) ;
xBoard[ i] .SetEnd ( value[ 1 ] ) ;
}
}
else if ( value[ 0 ] [ 0 ] >= ( xBoard[ i] .GetStart ( ) [ 0 ] ) && value[ 0 ] [ 0 ] <= ( xBoard[ i] .GetEnd ( ) [ 0 ] ) ) {
cutPoints.push_back ( value[ 0 ] ) ;
dS = ( xBoard[ i] .GetStart ( ) - toolPos) .length ( ) ;
dE = ( xBoard[ i] .GetEnd ( ) - toolPos) .length ( ) ;
if ( dS < dE)
xBoard[ i] .SetStart ( value[ 0 ] ) ;
else
xBoard[ i] .SetEnd ( value[ 0 ] ) ;
}
else if ( value[ 1 ] [ 0 ] >= ( xBoard[ i] .GetStart ( ) [ 0 ] ) && value[ 1 ] [ 0 ] <= ( xBoard[ i] .GetEnd ( ) [ 0 ] ) ) {
cutPoints.push_back ( value[ 1 ] ) ;
dS = ( xBoard[ i] .GetStart ( ) - toolPos) .length ( ) ;
dE = ( xBoard[ i] .GetEnd ( ) - toolPos) .length ( ) ;
if ( dS < dE)
xBoard[ i] .SetStart ( value[ 1 ] ) ;
else
xBoard[ i] .SetEnd ( value[ 1 ] ) ;
}
}
}
for ( size_t i = 0 ; i < dexelToDelete.size ( ) ; i++) {
std ::vector <Dexel>::iterator it = xBoard.begin ( ) + dexelToDelete[ i] -i;
xBoard.erase ( it) ;
}
//yBoard
dexelToDelete.clear ( ) ;
for ( size_t i = 0 ; i < yBoard.size ( ) ; i++) {
if ( yBoard[ i] .GetStart ( ) [ 2 ] < toolPos[ 2 ] ) //dexel under cutter
continue ;
std ::vector <Vector> value = yBoard[ i] .circleLineCollision ( toolPos, radius) ;
if ( value.size ( ) == 3 ) {
dexelToDelete.push_back ( i) ;
}
if ( value.size ( ) == 2 ) {
if ( value[ 0 ] [ 1 ] >= ( yBoard[ i] .GetStart ( ) [ 1 ] ) && value[ 0 ] [ 1 ] <= ( yBoard[ i] .GetEnd ( ) [ 1 ] ) &&
value[ 1 ] [ 1 ] >= ( yBoard[ i] .GetStart ( ) [ 1 ] ) && value[ 1 ] [ 1 ] <= ( yBoard[ i] .GetEnd ( ) [ 1 ] ) && value[ 0 ] != value[ 1 ] ) {
cutPoints.push_back ( value[ 0 ] ) ;
cutPoints.push_back ( value[ 1 ] ) ;
dS = ( yBoard[ i] .GetStart ( ) - value[ 0 ] ) .length ( ) ;
dE = ( yBoard[ i] .GetEnd ( ) - value[ 0 ] ) .length ( ) ;
if ( dS < dE) { //value[ 0 ] näher an start...value [ 1 ] näher an End
yBoard.push_back ( Dexel( value[ 1 ] , yBoard[ i] .GetEnd ( ) , Vector( 0 , 1 , 0 ) , ( value[ 1 ] - yBoard[ i] .GetEnd ( ) ) .length ( ) ) ) ;
yBoard[ i] .SetEnd ( value[ 0 ] ) ;
}
else {
yBoard.push_back ( Dexel( value[ 0 ] , yBoard[ i] .GetEnd ( ) , Vector( 0 , 1 , 0 ) , ( value[ 0 ] - yBoard[ i] .GetEnd ( ) ) .length ( ) ) ) ;
yBoard[ i] .SetEnd ( value[ 1 ] ) ;
}
}
else if ( value[ 0 ] [ 1 ] >= ( yBoard[ i] .GetStart ( ) [ 1 ] ) && value[ 0 ] [ 1 ] <= ( yBoard[ i] .GetEnd ( ) [ 1 ] ) ) {
cutPoints.push_back ( value[ 0 ] ) ;
dS = ( yBoard[ i] .GetStart ( ) - toolPos) .length ( ) ;
dE = ( yBoard[ i] .GetEnd ( ) - toolPos) .length ( ) ;
if ( dS < dE)
yBoard[ i] .SetStart ( value[ 0 ] ) ;
else
yBoard[ i] .SetEnd ( value[ 0 ] ) ;
}
else if ( value[ 1 ] [ 1 ] >= ( yBoard[ i] .GetStart ( ) [ 1 ] ) && value[ 1 ] [ 1 ] <= ( yBoard[ i] .GetEnd ( ) [ 1 ] ) ) {
cutPoints.push_back ( value[ 1 ] ) ;
dS = ( yBoard[ i] .GetStart ( ) - toolPos) .length ( ) ;
dE = ( yBoard[ i] .GetEnd ( ) - toolPos) .length ( ) ;
if ( dS < dE)
yBoard[ i] .SetStart ( value[ 1 ] ) ;
else
yBoard[ i] .SetEnd ( value[ 1 ] ) ;
}
}
}
for ( size_t i = 0 ; i < dexelToDelete.size ( ) ; i++) {
std ::vector <Dexel>::iterator it = yBoard.begin ( ) + dexelToDelete[ i] - i;
yBoard.erase ( it) ;
}
//zBoard
dexelToDelete.clear ( ) ;
for ( size_t i = 0 ; i < zBoard.size ( ) ; i++) {
if ( zBoard[ i] .GetEnd ( ) [ 2 ] >= toolPos[ 2 ] )
dexelToDelete.push_back ( i) ;
else {
Vector2d d( toolPos[ 0 ] - zBoard[ i] .GetStart ( ) [ 0 ] , toolPos[ 1 ] - zBoard[ i] .GetStart ( ) [ 1 ] ) ;
if ( d.length ( ) <= radius) {
zBoard[ i] .SetStart ( Vector( zBoard[ i] .GetStart ( ) [ 0 ] , zBoard[ i] .GetStart ( ) [ 1 ] , toolPos[ 2 ] ) ) ;
}
}
}
for ( size_t i = 0 ; i < dexelToDelete.size ( ) ; i++) {
std ::vector <Dexel>::iterator it = zBoard.begin ( ) + dexelToDelete[ i] - i;
zBoard.erase ( it) ;
}
//winkelbereich
std ::ostringstream filename;
filename << toolPos[ 0 ] << " cut.txt ";
std ::ofstream out( filename.str ( ) .c_str ( ) ) ;
out << std ::endl ;
out << toolPos[ 0 ] << " " << toolPos[ 1 ] << " " << toolPos[ 2 ] << std ::endl ;
out << lastToolPos[ 0 ] << " " << lastToolPos[ 1 ] << " " << lastToolPos[ 2 ] << std ::endl ;
double wMin = 360 ;
double wMax = 0 ;
std ::ostringstream filename2;
filename2 << toolPos[ 0 ] << " allCutPoints.txt ";
std ::ofstream out2( filename2.str ( ) .c_str ( ) ) ;
out2 << std ::endl ;
for ( size_t i = 0 ; i < cutPoints.size ( ) ; i++) {
out2 << cutPoints[ i] [ 0 ] << " " << cutPoints[ i] [ 1 ] << std ::endl ;
double w = atan2 ( cutPoints[ i] [ 1 ] - toolPos[ 1 ] , cutPoints[ i] [ 0 ] - toolPos[ 0 ] ) ;
if ( w < wMin)
wMin = w;
else if ( w>wMax)
wMax = w;
}
double step = ( abs ( wMin) + abs ( wMax) ) / ( substeps-1 ) ;
for ( size_t i = 0 ; i < substeps; i++) {
Vector2d cutP( toolPos[ 0 ] + radius*cos ( wMax - ( i*step ) ) , toolPos[ 1 ] + radius *sin ( wMax - ( i*step ) ) ) ;
out << cutP[ 0 ] << " " << cutP[ 1 ] << std ::endl ;
double invDSq = 1 .0f / ( cutP.xy ( ) - toolPos.xy ( ) ) .length ( ) ;
double p = ( ( ( cutP.xy ( ) - toolPos.xy ( ) ) * lastToolPos.xy ( ) ) - ( toolPos.xy ( ) *( cutP.xy ( ) - toolPos.xy ( ) ) ) ) * invDSq;
double discriminant = p * p - ( ( toolPos.xy ( ) - lastToolPos.xy ( ) ) .length ( ) - radius * radius) * invDSq;
if ( discriminant >= 0 .0f)
{
// Die beiden Lösungen für t ausrechnen und ausgeben.
double squareRoot = sqrt ( discriminant) ;
double t0 = p - squareRoot;
double t1 = p + squareRoot;
Vector2d p0 = toolPos.xy ( ) + t0*( cutP.xy ( ) - toolPos.xy ( ) ) ;
Vector2d p1 = toolPos.xy ( ) + t1*( cutP.xy ( ) - toolPos.xy ( ) ) ;
double d0 = ( p0 - cutP) .length ( ) ;
double d1 = ( p1 - cutP) .length ( ) ;
if ( d0 < d1) {
chip.push_back ( d0) ;
out << p0[ 0 ] << " " << p0[ 1 ] << std ::endl ;
}
else {
chip.push_back ( d1) ;
out << p1[ 0 ] << " " << p1[ 1 ] << std ::endl ;
}
}
}
}
lastToolPos = toolPos;
}
} ;
Ist es möglich die externe vector.h in die S_function mit einzubinden?
Ich bräuchte für die S-Function folgende Eingaben:
double precision
vector size
vector position
vector toolposition
double toolradius
Als Ausgabe würde dann jeweils die Schnitttiefe rauskommen.
Jemand vlt einen Tip für ein gutes "komplexeres" Beispiel? Die Standart Beispile aus der Doku habe ich mir angesehen, aber die helfen mir nicht weiter.
Danke!
Gruß Torben
realtm
Themenstarter
Forum-Newbie
Beiträge: 3
Anmeldedatum: 14.06.14
Wohnort: ---
Version: ---
Verfasst am : 07.08.2014, 13:19
Titel :
Das einbinden der vector.h klappt.
Der S-Function builder funktioniert nur mit c-Code?
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
Impressum
| Nutzungsbedingungen
| Datenschutz
| FAQ
| RSS
Hosted by:
Copyright © 2007 - 2024
goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.