• <bdo id='1gIzN'></bdo><ul id='1gIzN'></ul>
    1. <tfoot id='1gIzN'></tfoot>
      <legend id='1gIzN'><style id='1gIzN'><dir id='1gIzN'><q id='1gIzN'></q></dir></style></legend>

    2. <i id='1gIzN'><tr id='1gIzN'><dt id='1gIzN'><q id='1gIzN'><span id='1gIzN'><b id='1gIzN'><form id='1gIzN'><ins id='1gIzN'></ins><ul id='1gIzN'></ul><sub id='1gIzN'></sub></form><legend id='1gIzN'></legend><bdo id='1gIzN'><pre id='1gIzN'><center id='1gIzN'></center></pre></bdo></b><th id='1gIzN'></th></span></q></dt></tr></i><div id='1gIzN'><tfoot id='1gIzN'></tfoot><dl id='1gIzN'><fieldset id='1gIzN'></fieldset></dl></div>

        <small id='1gIzN'></small><noframes id='1gIzN'>

        提高超越方程解的精度

        时间:2023-08-03
        • <bdo id='dUJRh'></bdo><ul id='dUJRh'></ul>

          1. <legend id='dUJRh'><style id='dUJRh'><dir id='dUJRh'><q id='dUJRh'></q></dir></style></legend>
          2. <i id='dUJRh'><tr id='dUJRh'><dt id='dUJRh'><q id='dUJRh'><span id='dUJRh'><b id='dUJRh'><form id='dUJRh'><ins id='dUJRh'></ins><ul id='dUJRh'></ul><sub id='dUJRh'></sub></form><legend id='dUJRh'></legend><bdo id='dUJRh'><pre id='dUJRh'><center id='dUJRh'></center></pre></bdo></b><th id='dUJRh'></th></span></q></dt></tr></i><div id='dUJRh'><tfoot id='dUJRh'></tfoot><dl id='dUJRh'><fieldset id='dUJRh'></fieldset></dl></div>
              <tbody id='dUJRh'></tbody>
              <tfoot id='dUJRh'></tfoot>

              <small id='dUJRh'></small><noframes id='dUJRh'>

                  本文介绍了提高超越方程解的精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  我有一个特定的运动学作为更复杂机器的一部分,需要计算一些物理参数,这些参数非常难(更像是不可能)以适当的准确度测量> 使用我可以使用的仪器

                  I have a specific kinematics as a part of a more complex machine and need to compute some physical parameters that are very hard (more like impossible) to measure with proper accuracy with instruments I have at my disposal

                  [运动学]

                  乍一看是一个简单的1自由度臂(黑色),可以绕x轴旋转.它有一个重量迫使它总是向上移动,直到它碰到机械端点(角度 a0)或半径为 r0 的某个管子(蓝色).手臂旋转中心在y0.管子可以移动到任何y(t)高度.

                  At first look it is a simple 1 degree of freedom arm (black) which can rotate around x axis. It has a weight to force it to go always up until it hit the mechanic endpoint (angle a0) or some tube (blue) with radius r0. Arm rotation center is at y0. The tube can be moved to any y(t) height.

                  [使用]

                  这用于测量管的半径以进行进一步处理.半径可以计算(通过基本的测角法),这导致图像底部的方程.常数 a0,y0,z0 很难测量(它在复杂的机械内部)所以距离的测量精度为 min 0.1 mm 和角度 0.1 deg 甚至这是有问题的.

                  This is used to measure the radius of a tube for further processing. The radius can be computed (by basic goniometry) which leads to equation in the bottom of image. The constants a0,y0,z0 are very hard to measure (it is inside complex machinery) so the measurement accuracy for distances is min 0.1 mm and angle 0.1 deg and even that is questionable.

                  [校准]

                  所以我决定尝试从机器本身完成的一组测量中计算这些参数(自动校准).所以我有已知半径 r0 的校准管.所有绿色参数都可以作为常量处理.现在我沿着 y 轴定位管子,以覆盖尽可能多的手臂角度.遗憾的是,范围只有 20 度(对于当前机器设置)记住测量的 a(t) 预设 y(t) ...作为 n 点数据集.这给了我 n 个超越方程的系统.由此我尝试/猜测 a0,y0,z0 记住最佳解决方案的所有"可能性(最接近 r0)

                  So I decided to try compute these parameters from set of measurements done by the machine itself (auto-calibration). So I have calibration tube with known radius r0. All green parameters can be handled as constants. Now I position the tube along y axis to cover as much angles of arm as I could. Sadly the range is only about 20 degrees (for current machine setup) remembering measured a(t) for preset y(t) ... as n point dataset. This gives me system of n transcendent equations. From this I try/guess "all" possibilities of a0,y0,z0 remembering the best solution (closest to r0)

                  [a0,y0,z0 的近似值]

                  近似是基于我的这个类:

                  approximation is based on this class of mine:

                  //---------------------------------------------------------------------------
                  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
                              }
                          }
                      };
                  //---------------------------------------------------------------------------
                  

                  它通过一些初始步骤搜索单个变量的完整范围,然后找到最小偏差点.之后改变范围和步长以关闭该点的区域并递归提高精度.

                  It search the full range of single variable by some initial step then find the min deviation point. After that change the range and step to close area of this point and recursively increase accuracy.

                  解决方案本身如下所示:

                  The solution itself looks like this:

                  // (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 并忽略它的近似值,那么精度会显着提高,使 y0 没有错误(在模拟中)和 a0 的误差约为 0.3学位

                  This leads to solution close to the measured values but inside simulation the result is still not accurate enough. It is from 0.1 mm to 0.5 mm depending on number of points and angle range. If I measure properly z0 and ignore its approximation then the precision is boosted significantly leaving y0 without error (in simulation) and a0 with error around 0.3 degree

                  Q1 如何进一步提高解的准确度?

                  我无法增加角度范围.点数最好在 100 左右,精度越高越好,但超过 150 结果不稳定(对于某些半径,它完全关闭).完全不知道为什么.6 上面的递归数没有太大影响

                  I cannot increase the angular range. The number of points is best around 100 the more the better accuracy but above 150 the result is unstable (for some radiuses it is completely off). Have absolutely no clue why. The recursions number above 6 has not much effect

                  能否帮助根据与 0 度 的角距离对偏差进行加权?但遗憾的是 a(t) 范围不一定包括 0 度

                  Could help weighting the deviations according to angular distance from 0 degree ? But sadly a(t) range does not necessarily include 0 degrees

                  y0,z00.01 mma0

                  Q2 有什么我遗漏的地方吗?

                  比如错误嵌套的近似值或一些数学简化或不同的方法

                  Like wrongly nested approximations or some math simplification or different approach

                  [注释]

                  角度必须是a(t)+a0的形式,因为它是由IRC测量的,软件复位(16000 steps/round).它在 a0 位置时重置,我不计算振动和校准管偏心,它们已经得到处理,我的第一个目标是在没有它们的情况下在模拟中进行这项工作.管子y(t)可以随意定位,a(t)测量可以随意进行.

                  The angle must be in form of a(t)+a0 because it is measured by IRC with SW reset (16000 steps/round). It is reseted when in a0 position I do not count vibrations and calibration tube eccentricity they are taken care of already and my first goal is to make this work in simulation without them. Tube y(t) can be positioned at free will and the a(t) measurement can be done at will.

                  现在校准过程沿着 y 轴扫描点(从 a0 向下移动).使用 6 递归计算大约需要 35 秒(所以请耐心等待).5 递归大约需要 22

                  Right now the calibration process scan points along y axis (movement from a0 down). Computation with 6 recursions take around 35 seconds (so be patient). 5 recursions take around 22 seconds

                  [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 个递归来匹配输入的 IRC 精度,那么必须有 6 个递归.更改后(也在之前的编辑中)这里有一些结果

                  Just realized that I had only 4 recursions in simulation code to match the input IRC accuracy then there must be 6 recursions. After changing it (also in previous edit) here are some results

                                  | 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递归没有影响,也没有意义,因为真实的输入数据也不会更准确.

                  So the accuracy with z0 measured is almost in desired range but with z0 unknown the error is still ~10 times bigger then needed. Increasing simulation accuracy has no effect above 6 recursions and also no sense because real input data will not be more accurate either.

                  这里是使用上述模拟设置进行测试的模拟/测量点:

                  Here the simulated/measured points for testing with above simulated settings:

                   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] 进度更新

                  对@Ben 的一些说明

                  工作原理

                  第一张图片下的彩色方程给出了半径 r0 它由 2 个连接的 90 度 三角形(基本三角学)组成

                  the colored equation under the first image gives you the radius r0 it is made from 2 joined 90 degree triangles (basic trigonometry)

                  红色的东西:

                  • y(t) 是电机位置,它是已知的
                  • a(t) 也是已知的 IRC 状态
                  • y(t) is motor position and it is known
                  • a(t) is IRC state also known

                  绿色的东西:

                  • a0,y0,z0 是机械尺寸,已知但不精确,所以我测量了 y(t) 不同位置的许多 a(t) 使用已知的校准管 r0 并从中计算出更高精度的 a0,y0,z0
                  • a0,y0,z0 are mechanical dimensions and are known but not precise so I measure many a(t) for different positions of y(t) with known calibration tube r0 and compute the a0,y0,z0 with higher precision from it

                  进一步提高准确性

                  实际上,我通过从特殊校准运动中测量 y1=y0+z0*cos(a0) 使其更精确,精度约为 0.03 mm 甚至更好.a0 位置的手臂与管子y 运动轴的交点高度.它是从管从上到下时手臂第一次接触时的情况进行测量和插值的,但实际位置必须通过使用的半径和a0重新计算...因为接触点不在该轴上...(除非 r0=0.0).这也从校准中消除了一个近似循环,因为 y1,a0,z0 是相关的并且可以相互计算.由于不连续的测量方式和 a(t),y(t) 位置,从 IRC 的测量中消除双重混叠也有助于提高精度和计算稳定性(在真机上).我现在无法可靠地评估准确性,因为通过对许多测量周期的分析,我发现机器上存在一些机械问题,所以我一直等到它被修复.无论如何,在考虑两种方法和 _irc_calib_n=30 的情况下,r0=80.03 mm 的校准与仿真精度现在是:

                  I actually managed to get it more precise by measuring y1=y0+z0*cos(a0) from special calibration movement with precision around 0.03 mm and better. It is the height of intersection between arm in a0 position and tube y movement axis. It is measured and interpolated from situation when arm get first time contact when tube coming from up to down but the real position must be recomputed by used radius and a0... because contact point is not on this axis ... (unless r0=0.0). This also eliminates one approximation loop from calibration because y1,a0,z0 are dependent and can be computed from each other. Also removing double aliasing from measurement of IRC due to discontinuous manner of measurement and a(t),y(t) positions helped a lot to increase precision and computation stability (on real machine). I can not reliably asses accuracy right now because by analysis of many measured cycles I found some mechanical problems on the machine so I wait until it is repaired. Anyway the calibration vs. simulation accuracy for r0=80.03 mm with accounting both approaches and _irc_calib_n=30 is now:

                      ;      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 没有什么是直接测量或已知的.这已经是可以接受的,但正如我之前写的,当机器准备好时需要检查机器.只是为了完成这里是模拟测量现在的样子:

                  The bigger the calibration r0 the less accuracy (due to more limited a(t) range) this is by computing all a0,y0,(y1),z1 nothing is measured directly or known. This is already acceptable but as I wrote before need to check on machine when it is ready. Just to be complete here is how simulated measurements looks like now:

                  [edit4] 参见 近似搜索的工作原理

                  推荐答案

                  如果我理解正确,您正在尝试推断(但不是 测量)半径y 和 a 的测量值得到管的 r0.

                  If I understand this correctly, you're trying to infer (but not measure) the radius r0 of the tube from measurements for y and a.

                  将通常的误差传播应用到 r0 的公式中,可以获得(估计)结果 r0 的误差.在小角度的极限(这里适用,因为 a(t) 被限制为 20 度),这给出了粗略的(使用三角函数的小角度近似)

                  Applying the usual error propagation to your formula for r0, one obtains (an estimate for) the error of the resulting r0. In the limit of small angles (applicable here, since a(t) is limited to 20 degrees), this gives roughly (using the small-angle approximation for the trigonometic functions)

                  dr0^2 ~= dy^2 + z0^2 (pi*da/180)^2

                  dr0^2 ~= dy^2 + z0^2 (pi*da/180)^2

                  因此,在 r0 远小于 z0 的情况下,r0 上的相对误差总是远大于 y 和 z0*sin(a) 的相对误差.从您的图中可以清楚地看出这一点:测量的数量仅微弱地依赖于 r0.

                  Thus, in the case of r0 much smaller than z0, the relative error on r0 is always much larger than the relative errors of y and z0*sin(a). This is already clear from your graph: the measured quantities depend only weakly on r0.

                  换句话说,这不是确定半径 r0 的巧妙方法.对于这个基本限制,您无能为力(除非您可以增加角度 a 的范围).进行多次测量(消除噪音/错误的常用方法)可能无济于事,因为由于机器的内部工作原理,这些测量并不是相互独立的.因此,唯一的帮助是更准确的测量.

                  In other words, this is not a clever way to determine the radius r0. There is not much you can do about this fundamental limitation (except you can increase the range of angle a). Making many measurements (the usual method to beat down noise/errors) presumably won't help, because these measurements aren't independent of each other due to the internal workings of your machine. So, the only help would be more accurate measurements.

                  为了分析这种情况,我建议将推断的 r0 绘制为 y 的函数或作为固定 r0 的 a 函数的 y 的绘图/数字.

                  To analyse the situation, I recommend to make plots/figures of, say, the inferred r0 as function of y or of y as function of a for fixed r0.

                  这篇关于提高超越方程解的精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  • <tfoot id='lhNUs'></tfoot>
                      <tbody id='lhNUs'></tbody>

                      1. <i id='lhNUs'><tr id='lhNUs'><dt id='lhNUs'><q id='lhNUs'><span id='lhNUs'><b id='lhNUs'><form id='lhNUs'><ins id='lhNUs'></ins><ul id='lhNUs'></ul><sub id='lhNUs'></sub></form><legend id='lhNUs'></legend><bdo id='lhNUs'><pre id='lhNUs'><center id='lhNUs'></center></pre></bdo></b><th id='lhNUs'></th></span></q></dt></tr></i><div id='lhNUs'><tfoot id='lhNUs'></tfoot><dl id='lhNUs'><fieldset id='lhNUs'></fieldset></dl></div>
                        <legend id='lhNUs'><style id='lhNUs'><dir id='lhNUs'><q id='lhNUs'></q></dir></style></legend>

                        <small id='lhNUs'></small><noframes id='lhNUs'>

                          <bdo id='lhNUs'></bdo><ul id='lhNUs'></ul>