स्थिति माप, गति और त्वरण का अनुमान कैसे लगाएं


11

यह आसान है मैंने सोचा था, लेकिन मेरे भोले दृष्टिकोण ने बहुत शोर किया। मेरे पास यह नमूना समय है और t_angle.txt नामक फ़ाइल में स्थिति है:

0.768 -166.099892
0.837 -165.994148
0.898 -165.670052
0.958 -165.138245
1.025 -164.381218
1.084 -163.405838
1.144 -162.232704
1.213 -160.824051
1.268 -159.224854
1.337 -157.383270
1.398 -155.357666
1.458 -153.082809
1.524 -150.589943
1.584 -147.923012
1.644 -144.996872
1.713 -141.904221
1.768 -138.544807
1.837 -135.025749
1.896 -131.233063
1.957 -127.222366
2.024 -123.062325
2.084 -118.618355
2.144 -114.031906
2.212 -109.155006
2.271 -104.059753
2.332 -98.832321
2.399 -93.303795
2.459 -87.649956
2.520 -81.688499
2.588 -75.608597
2.643 -69.308281
2.706 -63.008308
2.774 -56.808586
2.833 -50.508270
2.894 -44.308548
2.962 -38.008575
3.021 -31.808510
3.082 -25.508537
3.151 -19.208565
3.210 -13.008499
3.269 -6.708527
3.337 -0.508461
3.397 5.791168
3.457 12.091141
3.525 18.291206
3.584 24.591179
3.645 30.791245
3.713 37.091217
3.768 43.291283
3.836 49.591255
3.896 55.891228
3.957 62.091293
4.026 68.391266
4.085 74.591331
4.146 80.891304
4.213 87.082100
4.268 92.961502
4.337 98.719368
4.397 104.172363
4.458 109.496956
4.518 114.523888
4.586 119.415550
4.647 124.088860
4.707 128.474464
4.775 132.714500
4.834 136.674385
4.894 140.481148
4.962 144.014626
5.017 147.388458
5.086 150.543938
5.146 153.436089
5.207 156.158638
5.276 158.624725
5.335 160.914001
5.394 162.984924
5.463 164.809685
5.519 166.447678

और वेग और त्वरण का अनुमान लगाना चाहते हैं। मुझे पता है कि त्वरण स्थिर है, इस मामले में 55 डिग्री / सेकंड ^ 2 के बारे में जब तक वेग लगभग 100 डिग्री / सेकंड नहीं है, तब तक आरोप शून्य और वेग स्थिर है। अंत में त्वरण -55 डिग्री / सेकंड ^ 2 है। यहाँ scilab कोड है जो विशेष रूप से त्वरण का बहुत शोर और बेकार अनुमान देता है।

clf()
clear
M=fscanfMat('t_angle.txt');
t=M(:,1);
len=length(t);
x=M(:,2);
dt=diff(t);
dx=diff(x);
v=dx./dt;
dv=diff(v);
a=dv./dt(1:len-2);
subplot(311), title("position"),
plot(t,x,'b');
subplot(312), title("velocity"),
plot(t(1:len-1),v,'g');
subplot(313), title("acceleration"),
plot(t(1:len-2),a,'r');

मैं बेहतर अनुमान पाने के लिए, इसके बजाय एक कलमन फ़िल्टर का उपयोग करने के बारे में सोच रहा था। क्या यह यहाँ उचित है? न जाने कैसे फिल्माकार समीकरण तैयार किए जाते हैं, कलमन फिल्टर के साथ बहुत अनुभवी नहीं हैं। मुझे लगता है कि राज्य वेक्टर वेग और त्वरण है और संकेत स्थिति है। या केएफ की तुलना में एक सरल विधि है, जो उपयोगी परिणाम देती है।

सभी सुझावों का स्वागत है! यहाँ छवि विवरण दर्ज करें


1
यह एक कलमन फ़िल्टर का एक उपयुक्त अनुप्रयोग है। Kalman फिल्टर पर विकिपीडिया लेख एक उदाहरण बहुत ज्यादा आपके जैसे नहीं है। यह केवल स्थिति और वेग का अनुमान लगाता है, लेकिन यदि आप उस उदाहरण को समझते हैं, तो इसे त्वरण तक विस्तारित करना सीधा है।
जेसन आर

1
Scipy में यह उपयोगी हो सकता है < docs.scipy.org/doc/scipy-0.16.1/reference/generated/… >
माइक

जवाबों:


12

एक तरीका यह होगा कि समस्या को कम से कम वर्ग के चौरसाई के रूप में रखा जाए। विचार एक चलती हुई खिड़की के साथ एक बहुपद को फिट करने के लिए है, फिर बहुपद के व्युत्पन्न का मूल्यांकन करें। सविट्ज़की-गोलय फ़िल्टरिंग के बारे में इस जवाब में कुछ सैद्धांतिक पृष्ठभूमि है कि यह गैर-वर्दी नमूनाकरण के लिए कैसे काम करता है।

इस मामले में, कोड संभवतः तकनीक के लाभों / सीमाओं के रूप में अधिक रोशन है। निम्नलिखित सुन्न स्क्रिप्ट दो मापदंडों के आधार पर किसी दिए गए स्थिति संकेत के वेग और त्वरण की गणना करेगा: 1) चौरसाई खिड़की का आकार, और 2) स्थानीय बहुपद सन्निकटन का क्रम।

# Example Usage:
# python sg.py position.dat 7 2

import math
import sys

import numpy as np
import numpy.linalg
import pylab as py

def sg_filter(x, m, k=0):
    """
    x = Vector of sample times
    m = Order of the smoothing polynomial
    k = Which derivative
    """
    mid = len(x) / 2        
    a = x - x[mid]
    expa = lambda x: map(lambda i: i**x, a)    
    A = np.r_[map(expa, range(0,m+1))].transpose()
    Ai = np.linalg.pinv(A)

    return Ai[k]

def smooth(x, y, size=5, order=2, deriv=0):

    if deriv > order:
        raise Exception, "deriv must be <= order"

    n = len(x)
    m = size

    result = np.zeros(n)

    for i in xrange(m, n-m):
        start, end = i - m, i + m + 1
        f = sg_filter(x[start:end], order, deriv)
        result[i] = np.dot(f, y[start:end])

    if deriv > 1:
        result *= math.factorial(deriv)

    return result

def plot(t, plots):
    n = len(plots)

    for i in range(0,n):
        label, data = plots[i]

        plt = py.subplot(n, 1, i+1)
        plt.tick_params(labelsize=8)
        py.grid()
        py.xlim([t[0], t[-1]])
        py.ylabel(label)

        py.plot(t, data, 'k-')

    py.xlabel("Time")

def create_figure(size, order):
    fig = py.figure(figsize=(8,6))
    nth = 'th'
    if order < 4:
        nth = ['st','nd','rd','th'][order-1]

    title = "%s point smoothing" % size
    title += ", %d%s degree polynomial" % (order, nth)

    fig.text(.5, .92, title,
             horizontalalignment='center')

def load(name):
    f = open(name)    
    dat = [map(float, x.split(' ')) for x in f]
    f.close()

    xs = [x[0] for x in dat]
    ys = [x[1] for x in dat]

    return np.array(xs), np.array(ys)

def plot_results(data, size, order):
    t, pos = load(data)
    params = (t, pos, size, order)

    plots = [
        ["Position",     pos],
        ["Velocity",     smooth(*params, deriv=1)],
        ["Acceleration", smooth(*params, deriv=2)]
    ]

    create_figure(size, order)
    plot(t, plots)

if __name__ == '__main__':
    data = sys.argv[1]
    size = int(sys.argv[2])
    order = int(sys.argv[3])

    plot_results(data, size, order)
    py.show()

विभिन्न मापदंडों के लिए यहां कुछ उदाहरण प्लॉट (आपके द्वारा प्रदान किए गए डेटा का उपयोग करके) हैं।

3 टी चौरसाई, 2 डिग्री बहुपद 7pt चौरसाई, 2 डिग्री बहुपद 11pt चौरसाई, 2 डिग्री बहुपद 11pt चौरसाई, 4 डिग्री बहुपद 11pt चौरसाई, 10 वीं डिग्री बहुपद

ध्यान दें कि खिड़की के आकार में वृद्धि के साथ त्वरण के टुकड़े की निरंतर प्रकृति कैसे कम स्पष्ट हो जाती है, लेकिन उच्च-क्रम बहुपद का उपयोग करके कुछ हद तक पुनर्प्राप्त किया जा सकता है। बेशक, अन्य विकल्पों में पहले व्युत्पन्न फ़िल्टर को दो बार लागू करना शामिल है (संभवतः अलग-अलग आदेश)। एक और बात जो स्पष्ट होनी चाहिए वह यह है कि इस प्रकार की सविट्ज़की-गॉले फ़िल्टरिंग, चूंकि यह खिड़की के मध्य बिंदु का उपयोग करती है, स्मूथ डेटा के सिरों को अधिक से अधिक काटती है क्योंकि खिड़की का आकार बढ़ता है। उस समस्या को हल करने के लिए विभिन्न तरीके हैं, लेकिन उनमें से एक को निम्नलिखित पेपर में वर्णित किया गया है:

पीए गोरी, कन्वेंशन (सविट्ज़की-गोले) विधि, गुदा द्वारा सामान्य कम-वर्ग चौरसाई और भेदभाव। रसायन। 62 (1990) 570-573। ( Google )

उसी लेखक का एक अन्य पेपर उदाहरण कोड में सीधी विधि की तुलना में गैर-समान डेटा को सुचारू करने के लिए अधिक कुशल तरीका बताता है:

पीए गोरी, कम से कम-वर्गों को चौरसाई और गैर-समान रूप से स्थानिक डेटा के विभेदीकरण द्वारा कनविक्शन विधि, गुदा। रसायन। 63 (1991) 534-536। ( Google )

अंत में, इस क्षेत्र में पढ़ने लायक एक और पेपर पर्सन और स्ट्रैंग द्वारा दिया गया है :

PO Persson, G. Strang, Smoothing by Savitzky-Golay and Legendre Filters, Comm। अनि। वित्त 13 (2003) 301316। ( pdf लिंक )

इसमें बहुत अधिक पृष्ठभूमि सिद्धांत शामिल हैं, और विंडो आकार चुनने के लिए त्रुटि विश्लेषण पर ध्यान केंद्रित करता है।


अच्छा विश्लेषण! +1
पीटर के.एच.

मैं पूरी तरह से इस जवाब की सराहना करता हूं!
lgwest

@ पश्चिम पश्चिम निश्चित रूप से, आशा है कि यह मदद करता है!
datageist

यदि डेटा समान रूप से दूरी पर है, उदाहरण के लिए dt = 0.1, तो संबंधित फ़िल्टर फ़ंक्शंस क्या है।
lgwest

फिर फ़िल्टर गुणांक स्थिर होगा, इसलिए आप बस एक बार sg_filter को कॉल कर सकते हैं (और तेजी के लिए व्युत्पन्न k - 2 के भाज्य द्वारा फ़िल्टर को गुणा करें)। इस उत्तर का पहला भाग देखें ।
datageist

2

आप शायद अभी, इस सवाल-जवाब में के रूप में ही करना चाहिए

संपादित करें: दो-आयामों के लिए हटाए गए संदर्भ; कोड वास्तव में केवल एक का उपयोग करता है (दूसरा समय चर है)।

हालांकि, आपके समय के नमूने समान रूप से स्थान नहीं देते हैं। यह एक मुद्दे की अधिक है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.