c++ - ट्रान्सेंडैंटल समीकरण के समाधान की बढ़ती सटीकता



math geometry (1)

मेरे पास एक अधिक जटिल मशीन के एक भाग के रूप में एक विशिष्ट कीनेमेटीक्स है और कुछ भौतिक मापदंडों की गणना करने की आवश्यकता है जो कि मेरे निपटान में मौजूद उपकरणों के साथ उचित सटीकता के साथ मापने के लिए बहुत कठिन (असंभव की तरह) हैं।

[गतिकी]

पहली नज़र में यह एक साधारण 1 डिग्री की आज़ादी बांह (काली) है जो x अक्ष के चारों ओर घूम सकती है। यह एक भार है जब तक वह मैकेनिक समापन बिंदु (कोण a0 ) या त्रिज्या r0 साथ कुछ ट्यूब (नीला) को हिट करने के लिए मजबूर करने के लिए। आर्म रोटेशन सेंटर y0 । ट्यूब को किसी भी y(t) ऊंचाई पर ले जाया जा सकता है।

[उपयोग]

इसका उपयोग आगे की प्रक्रिया के लिए एक ट्यूब की त्रिज्या को मापने के लिए किया जाता है। त्रिज्या की गणना की जा सकती है (बुनियादी गोनोमेट्री द्वारा) जो छवि के तल में समीकरण की ओर जाता है। स्थिरांक a a0,y0,z0 को मापना बहुत मुश्किल है (यह जटिल मशीनरी के अंदर है) इसलिए दूरी के लिए माप सटीकता न्यूनतम 0.1 mm और कोण 0.1 deg और यहां तक ​​कि यह संदिग्ध है।

[अंशांकन]

इसलिए मैंने मशीन द्वारा किए गए माप के सेट से इन मापदंडों की गणना करने का प्रयास करने का फैसला किया (ऑटो-कैलिब्रेशन)। इसलिए मुझे ज्ञात त्रिज्या r0 साथ अंशांकन ट्यूब है। सभी हरे मापदंडों को स्थिरांक के रूप में संभाला जा सकता है। अब मैं y अक्ष के साथ ट्यूब को हाथ के जितना कोण को कवर करने के लिए रख सकता हूं। अफसोस की बात है कि सीमा केवल 20 degrees (करंट मशीन सेटअप के लिए) है जिसे पूर्व निर्धारित y(t) ... n बिंदु डेटासेट के रूप में मापा जाता a(t) । यह मुझे n ट्रान्सेंडेंट समीकरणों की प्रणाली देता है। इससे मैं a0,y0,z0 के सर्वोत्तम समाधान को याद करने की "सभी" संभावनाओं का अनुमान / अनुमान a0,y0,z0 ( r0 निकटतम)

[a, y0, z0 का सन्निकटन]

सन्निकटन मेरे इस वर्ग पर आधारित है:

//---------------------------------------------------------------------------
class approx
    {
public:
    double a,aa,a0,a1,da,*e,e0;
    int i,n;
    bool done,stop;

    approx()            { a=0.0; aa=0.0; a0=0.0; a1=1.0; da=0.1; e=NULL; e0=NULL; i=0; n=5; done=true; }
    approx(approx& a)   { *this=a; }
    ~approx()           {}
    approx* operator = (const approx *a) { *this=*a; return this; }
    //approx* operator = (const approx &a) { ...copy... return this; }

    void init(double _a0,double _a1,double _da,int _n,double *_e)
        {
        if (_a0<=_a1) { a0=_a0; a1=_a1; }
        else          { a0=_a1; a1=_a0; }
        da=fabs(_da);
        n =_n ;
        e =_e ;
        e0=-1.0;
        i=0; a=a0; aa=a0;
        done=false; stop=false;
        }
    void step()
        {
        if ((e0<0.0)||(e0>*e)) { e0=*e; aa=a; }         // better solution
        if (stop)                                       // increase accuracy
            {
            i++; if (i>=n) { done=true; a=aa; return; } // final solution
            a0=aa-fabs(da);
            a1=aa+fabs(da);
            a=a0; da*=0.1;
            a0+=da; a1-=da;
            stop=false;
            }
        else{
            a+=da; if (a>a1) { a=a1; stop=true; }       // next point
            }
        }
    };
//---------------------------------------------------------------------------

यह एकल चर की पूरी श्रृंखला को कुछ प्रारंभिक चरण से खोजता है, फिर न्यूनतम विचलन बिंदु को खोजता है। उसके बाद इस बिंदु के बंद क्षेत्र और सीमा को बदलें और सटीकता बढ़ाएं।

समाधान स्वयं इस तरह दिखता है:

// (global) input data
#define _irc_calib_n 100
#define _irc_approx_n 5
int    irc_calib_ix; // number of measured points
double irc_calib_y[_irc_calib_n]; // y(t)
double irc_calib_a[_irc_calib_n]; // a(t)
double irc_calib_r; // calibration tube radius + arm radius

// approximation
int ix=0;
double e,a,deg=M_PI/180.0;
approx aa,ay,az;
//           min       max       step     recursions    ErrorOfSolutionVariable
for (aa.init(-90.0*deg,+90.0*deg,10.0*deg,_irc_approx_n,&e);!aa.done;aa.step())
for (ay.init(  0.0    ,200.0    ,10.0    ,_irc_approx_n,&e);!ay.done;ay.step())
for (az.init( 50.0    ,400.0    ,10.0    ,_irc_approx_n,&e);!az.done;az.step())
    {
    for (e=0.0,ix=0;ix<_irc_calib_n;ix++) // test all measured points (e is cumulative error)
        {
        a=irc_calib_a[ix]+aa.a;
        if (a> pi) a-=pi2;
        if (a<-pi) a+=pi2;
        if (fabs(a)>0.5*pi) { e=100.0; break; } // ignore too far angles
        e+=fabs(+(cos(a)*(irc_calib_y[ix]-ay.a))
                -(sin(a)*(az.a))
                -(irc_calib_r));
        }
    }
// here aa.a,ay.a,az.a holds the result

यह मापा मूल्यों के करीब समाधान की ओर जाता है लेकिन सिमुलेशन के अंदर परिणाम अभी भी सटीक नहीं है। अंक और कोण सीमा के आधार पर यह 0.1 मिमी से 0.5 मिमी तक है। अगर मैं z0 ठीक से z0 और इसके अनुमान को नजरअंदाज करता z0 तो सटीक को त्रुटि के बिना y0 (सिमुलेशन में) और a0 को त्रुटि के साथ 0.3 डिग्री के आसपास छोड़ने पर काफी बढ़ावा मिलता है

Q1 मैं समाधान की सटीकता में और सुधार कैसे कर सकता हूं?

मैं कोणीय सीमा नहीं बढ़ा सकता। अंकों की संख्या 100 के आसपास सबसे बेहतर सटीकता है लेकिन 150 से ऊपर परिणाम अस्थिर है (कुछ त्रिज्या के लिए यह पूरी तरह से है)। कोई सुराग नहीं है क्यों। 6 ऊपर की पुनरावृत्ति संख्या का अधिक प्रभाव नहीं है

0 degree से कोणीय दूरी के अनुसार विचलन को भारित करने में मदद कर सकता है? लेकिन दुख की बात है कि a(t) रेंज में 0 degrees शामिल नहीं है

वांछित सटीकता y0,z0 लिए 0.01 mm और a0 लिए 0.01 degree है

Q2 क्या कुछ ऐसा है जिसे मैंने याद किया है?

गलत तरीके से नेस्टेड सन्निकटन या कुछ गणित सरलीकरण या अलग दृष्टिकोण

[टिप्पणियाँ]

कोण a(t)+a0 रूप में होना चाहिए क्योंकि यह आईआरसी द्वारा SW रीसेट ( 16000 steps/round ) के साथ मापा जाता है। इसे तब रीसेट किया जाता है जब a0 स्थिति में मैं कंपन और अंशांकन ट्यूब सनकीपन की गणना नहीं करता हूं, उन्हें पहले से ही ध्यान रखा जाता है और मेरा पहला लक्ष्य उनके बिना सिमुलेशन में यह काम करना है। ट्यूब y(t) को स्वतंत्र इच्छा पर तैनात किया जा सकता है और a(t) माप इच्छा पर किया जा सकता है।

अभी y अक्ष के साथ अंशांकन प्रक्रिया स्कैन अंक ( a0 डाउन से आंदोलन)। 6 पुनरावृत्तियों के साथ गणना में लगभग 35 सेकंड लगते हैं (इसलिए धैर्य रखें)। 5 पुनरावृत्ति में लगभग 22 सेकंड लगते हैं

[edit1] यहाँ सिमुलेशन कैसे किया जाता है

approx aa; double e;
for (aa.init(-90.0*deg,+90.0*deg,10.0*deg,6,&e);!aa.done;aa.step())
 e=fabs(+(cos(aa.a)*(y(t)-y0))
        -(sin(aa.a)*(z0))
        -(irc_calib_r));
if (aa.a<a0) aa.a=a0;

[edit2] कुछ मूल्य

बस एहसास हुआ कि इनपुट आईआरसी सटीकता से मेल खाने के लिए सिमुलेशन कोड में मेरे पास केवल 4 पुनरावृत्तियां थीं, फिर 6 पुनरावृत्तियां होनी चाहिए। इसे बदलने के बाद (पिछले संपादन में भी) यहाँ कुछ परिणाम हैं

                | a0[deg]| y0[mm] | z0[mm] | 
    simulated   | -7.4510|191.2590|225.9000|
    z0 known    | -7.4441|191.1433|225.9000|
    z0 unknown  | -7.6340|191.8074|225.4971|

तो z0 मापा के साथ सटीकता लगभग वांछित सीमा में है, लेकिन z0 अज्ञात के साथ त्रुटि अभी भी ~10 गुना बड़ी है फिर जरूरत है। बढ़ती सिमुलेशन सटीकता का 6 पुनरावर्ती से ऊपर कोई प्रभाव नहीं है और यह भी कोई मतलब नहीं है क्योंकि वास्तविक इनपुट डेटा या तो अधिक सटीक नहीं होगा।

यहाँ उपर्युक्त सिम्युलेटेड सेटिंग्स के साथ परीक्षण के लिए नकली / मापा बिंदु:

 ix   a [deg]    y [mm]
  0   -0.2475 +105.7231 
  1   -0.4500 +104.9231 
  2   -0.6525 +104.1231 
  3   -0.8550 +103.3231 
  4   -1.0575 +102.5231 
  5   -1.2600 +101.7231 
  6   -1.4625 +100.9231 
  7   -1.6650 +100.1231 
  8   -1.8675  +99.3231 
  9   -2.0700  +98.5231 
 10   -2.2725  +97.7231 
 11   -2.4750  +96.9231 
 12   -2.6775  +96.1231 
 13   -2.8575  +95.3077 
 14   -3.0600  +94.5154 
 15   -3.2625  +93.7231 
 16   -3.4650  +92.9308 
 17   -3.6675  +92.1385 
 18   -3.8700  +91.3462 
 19   -4.0725  +90.5538 
 20   -4.2750  +89.7615 
 21   -4.4877  +88.9692 
 22   -4.6575  +88.1769 
 23   -4.8825  +87.3615 
 24   -5.0850  +86.5154 
 25   -5.2650  +85.7000 
 26   -5.4675  +84.9077 
 27   -5.6700  +84.1154 
 28   -5.8725  +83.3231 
 29   -6.0750  +82.5308 
 30   -6.2775  +81.7000 
 31   -6.5025  +80.8462 
 32   -6.6825  +80.0462 
 33   -6.8850  +79.2538 
 34   -7.0875  +78.4615 
 35   -7.2900  +77.6538 
 36   -7.5159  +76.7692 
 37   -7.6725  +75.9769 
 38   -7.8750  +75.1846 
 39   -8.1049  +74.3692 
 40   -8.2800  +73.5000 
 41   -8.4825  +72.7077 
 42   -8.6850  +71.9154 
 43   -8.9100  +71.0308 
 44   -9.0900  +70.2231 
 45   -9.2925  +69.4308 
 46   -9.5175  +68.5462 
 47   -9.6975  +67.7462 
 48   -9.9000  +66.9462 
 49  -10.1025  +66.0615 
 50  -10.3148  +65.2692 
 51  -10.4850  +64.3769 
 52  -10.6875  +63.5846 
 53  -10.9125  +62.7462 
 54  -11.0925  +61.9077 
 55  -11.2950  +61.0846 
 56  -11.4975  +60.2231 
 57  -11.7000  +59.3923 
 58  -11.9025  +58.5308 
 59  -12.1288  +57.6692 
 60  -12.3075  +56.8385 
 61  -12.5100  +55.9462 
 62  -12.7125  +55.1538 
 63  -12.9150  +54.2615 
 64  -13.1175  +53.4000 
 65  -13.2975  +52.5769 
 66  -13.5000  +51.6846 
 67  -13.7025  +50.7923 
 68  -13.9050  +50.0000 
 69  -14.1075  +49.1077 
 70  -14.3100  +48.2154 
 71  -14.5350  +47.3615 
 72  -14.7150  +46.5308 
 73  -14.9175  +45.6385 
 74  -15.1200  +44.7462 
 75  -15.3225  +43.8538 
 76  -15.5250  +42.9615 
 77  -15.7490  +42.0692 
 78  -15.9075  +41.2769 
 79  -16.1100  +40.3846 
 80  -16.3125  +39.4923 
 81  -16.5150  +38.6000 
 82  -16.7175  +37.7077 
 83  -16.9200  +36.8154 
 84  -17.1225  +35.9231 
 85  -17.3250  +34.9308 
 86  -17.5275  +34.0385 
 87  -17.7300  +33.1462 
 88  -17.9325  +32.2538 
 89  -18.1350  +31.3615 
 90  -18.3405  +30.4692 
 91  -18.5175  +29.4769 
 92  -18.7200  +28.5846 
 93  -18.9225  +27.6923 
 94  -19.1250  +26.8000 
 95  -19.3275  +25.8077 
 96  -19.5300  +24.9154 
 97  -19.7325  +23.9231 
 98  -19.9350  +23.0308 
 99  -20.1375  +22.1385 

[edit3] प्रगति अद्यतन

@ के लिए कुछ स्पष्टीकरण

यह काम किस प्रकार करता है

पहली छवि के तहत रंगीन समीकरण आपको त्रिज्या r0 देता है यह 2 से बना है 90 degree त्रिकोण (मूल त्रिकोणमिति)

लाल सामान:

  • y(t) मोटर की स्थिति है और यह ज्ञात है
  • a(t) IRC राज्य भी है

हरा सामान:

  • a0,y0,z0 यांत्रिक आयाम हैं और ज्ञात नहीं हैं, लेकिन सटीक नहीं हैं इसलिए मैं ज्ञात अंशांकन ट्यूब r0 साथ y(t) विभिन्न पदों के लिए कई a(t) को a0,y0,z0 और इससे उच्च परिशुद्धता के साथ a0,y0,z0 गणना करता a0,y0,z0

आगे सटीकता में सुधार

मैं वास्तव में 0.03 mm और बेहतर के साथ परिशुद्धता के साथ विशेष अंशांकन आंदोलन से y1=y0+z0*cos(a0) को मापकर इसे और अधिक सटीक प्राप्त करने में कामयाब रहा। यह a0 स्थिति और ट्यूब y आंदोलन अक्ष में हाथ के बीच चौराहे की ऊंचाई है। इसे मापा जाता है और उस स्थिति से प्रक्षेपित किया जाता है जब हाथ पहली बार संपर्क में आते हैं जब ट्यूब ऊपर से नीचे की ओर आती है लेकिन वास्तविक स्थिति का उपयोग त्रिज्या और a0 द्वारा फिर से किया जाना चाहिए ... क्योंकि संपर्क बिंदु इस अक्ष पर नहीं है ... (जब तक r0=0.0 )। यह अंशांकन से एक सन्निकटन लूप को भी समाप्त करता है क्योंकि y1,a0,z0 निर्भर हैं और एक दूसरे से गणना की जा सकती है। आईआरसी की माप से दोहरे उर्फिंग को हटाने के कारण माप और a(t),y(t) तरीके से a(t),y(t) पदों ने सटीक और कम्प्यूटेशन स्थिरता (वास्तविक मशीन पर) बढ़ाने के लिए बहुत मदद की। मैं अभी विश्वसनीय रूप से सटीकता का आश्वासन नहीं दे सकता क्योंकि कई मापा चक्रों के विश्लेषण से मुझे मशीन पर कुछ यांत्रिक समस्याएं मिलीं, इसलिए मैं इसकी मरम्मत होने तक प्रतीक्षा करता हूं। वैसे भी r0=80.03 mm लिए अंशांकन बनाम सिमुलेशन सटीकता दोनों दृष्टिकोणों के साथ है और _irc_calib_n=30 अब है:

    ;      computed     simulated  |delta|
    a0=  -6.915840 ;  -6.916710   +0.000870 deg
    y0=+186.009765 ;+186.012822   +0.003057 mm
    y1=+158.342452 ;+158.342187   +0.000264 mm
    z0=+228.102470 ;+228.100000   +0.002470 mm

बड़े अंशांकन r0 कम सटीकता (अधिक सीमित a(t) रेंज के कारण) यह सभी a0,y0,(y1),z1 गणना करके है a0,y0,(y1),z1 कुछ भी सीधे या ज्ञात नहीं मापा जाता है। यह पहले से ही स्वीकार्य है लेकिन जैसा कि मैंने तैयार होने पर मशीन पर जांच करने की आवश्यकता से पहले लिखा था। बस यहाँ पूरा होना है कि नकली माप अब कैसा दिखता है:

[edit4] देखें कि सन्निकटन खोज कैसे काम करती है


अगर मैं इसे सही ढंग से समझता हूं, तो आप y और a के लिए माप से ट्यूब की त्रिज्या r0 का अनुमान लगाना (लेकिन मापना नहीं ) कर रहे हैं।

R0 के लिए अपने सूत्र में सामान्य त्रुटि प्रसार को लागू करना, एक परिणामी r0 की त्रुटि प्राप्त करता है (के लिए एक अनुमान)। छोटे कोणों की सीमा में (यहां लागू, चूंकि (टी) 20 डिग्री तक सीमित है), यह मोटे तौर पर (त्रिकोणमितीय कार्यों के लिए छोटे कोण का उपयोग करके) देता है

dr0 ^ 2 ~ = डाई ^ 2 + z0 ^ 2 (पीआई * दा / 180) ^ 2

इस प्रकार, r0 की तुलना में z0 से बहुत छोटा होने की स्थिति में, r0 पर सापेक्ष त्रुटि हमेशा y और z0 * पाप (a) की सापेक्ष त्रुटियों से बहुत बड़ी होती है। यह आपके ग्राफ़ से पहले से ही स्पष्ट है: मापा मात्रा केवल r0 पर कमजोर रूप से निर्भर करती है।

दूसरे शब्दों में, त्रिज्या r0 निर्धारित करने का यह एक चतुर तरीका नहीं है। इस मूलभूत सीमा के बारे में आप बहुत कुछ नहीं कर सकते हैं (सिवाय कोण की सीमा को बढ़ाए आप)। कई माप (शोर / त्रुटियों को हरा करने की सामान्य विधि) निश्चित रूप से मदद नहीं करेगी, क्योंकि ये माप आपकी मशीन के आंतरिक कामकाज के कारण एक दूसरे से स्वतंत्र नहीं हैं। तो, एकमात्र मदद अधिक सटीक माप होगी।

स्थिति का विश्लेषण करने के लिए, मैं प्लॉट / के आंकड़े बनाने की सलाह देता हूं, कहते हैं, अनुमानित r0 y या y के कार्य के रूप में एक निश्चित r0 के लिए कार्य करता है।





transcendental-equation