首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >轨迹优化

轨迹优化
EN

Code Review用户
提问于 2014-10-23 10:43:03
回答 1查看 108关注 0票数 3

下面是一个函数,它以下列方式进行一些轨迹优化:

代码语言:javascript
运行
复制
for position in sref_
    ... // get position data
    // start parallel region
    for time in vtwin->trefloc_                    // time will be offsetted
        for start_velocity in vtwin->vrefloc_      // start_velocity will be offsetted
        ... // check constraint
            for stop_velocity in vtwin->vrefloc_   // stop_velocity will be offsetted
            ... // check many constraints
            ... // temporarily save 6 values if better than of other stop_velocity
        ... // save the 6 values which proofed to be best to output
    // end parallel region

该函数根据过渡性质和最内部循环中的代价函数(通过从数组中读取)来寻找最优的转换。代码中的百分比数字提供了关于执行一行的次数(与时间无关)的信息,与最内部循环的执行总数有关。

自从我要求对它进行检查后,这个函数已经发生了变化,这里。我试图给它更多的结构(通过使用结构),但已经是这样了。不知怎么的,我没看到可以分开的部分。如果我..。

  • ...put两个速度循环在一个单独的函数中,我需要把这么多的变量传递给新函数。
  • ...put仅是独立函数中最内部的循环,我必须传递一大串变量,并创建一个数组来返回6个返回值,这些值由外部速度循环存储(参见伪代码)。
  • ...put内部最内部循环的一些微小部分在子函数中,它没有多大帮助。许多值被多次使用。约束检查无法来源,是吗?甚至我也不确定,如果所有东西都会被内联,导致已经尝试过了,并且我看到了对执行时间的轻微影响,即使不是很多。

也许现在复习起来会容易一些,即使它的结构不是很好。

代码语言:javascript
运行
复制
// RECURSION ROUTINE
static void rmss(const FunMapsVel *fmapsvel, const FunMapsPos *fmapspos, 
                 const Window *vtwin, double const * const sref_, const size_t nv, 
                 const size_t nt, const size_t ns, const double max_decel, 
                 const double total_dynmass, ArgOut *matout)
{
    const double Inf = (const double)mxGetInf();
    double prodiv = 0.;
    size_t k = ns - 1;
    // POSITIONAL LOOP
    while(k--){         // indices from ns - 2 to zero
        clock_t tloop = clock();
        int h;
        // get position dependent values
        const double sk         = sref_[k];                     // position s
        const double sstep      = sref_[k+1] - sk;              // current step width
        const double toff_sk    = vtwin->toffset_[k];           // time offset at current position
        const double toff_skp1  = vtwin->toffset_[k+1];         // time offset at next position
        const double voff_sk    = vtwin->voffset_[k];           // velocity offset at current position
        const double voff_skp1  = vtwin->voffset_[k+1];         // velocity offset at next position
        const double vmax_sk    = fmapspos->velolim_at_s_[k];   // velocity limit at current position
        const double vmax_skp1  = fmapspos->velolim_at_s_[k+1]; // velocity limit at next position
        // window time bound at next position
        const double tmax_skp1  = (vtwin->twidth-1/vtwin->tstep_r) + toff_skp1;
        // drag at current position
        const double route_drag_sk = fmapspos->route_drag_at_s_[k];   /
        // check for validity of matrix slice k+1 of costToEnd
        check_previous_mat(matout->costToEnd, k, nv, nt);
        // Check for user interruption
        if (utIsInterruptPending()) {        
            mexErrMsgIdAndTxt("MATLAB:dprm:userinterrupt",
                              "User interrupt detected.");
        }
#if PARALLEL
    #pragma omp parallel for private(h) num_threads(8) schedule(dynamic)
#endif
        for(h = 0; h < (int)nt; h++){
            size_t mk; 
            double tk;
            // current time
            tk = vtwin->trefloc_[h] + toff_sk;
            // INITIAL VELOCITY LOOP
            for(mk = 0; mk < nv-1; mk++){
                size_t mkp1 = nv-1;
                size_t tmp_iv, tmp_it;
                double tmp_f, tmp_e, tmp_t, tmp_c = Inf;
                // current velocity
                const double vk = vtwin->vrefloc_[mk] + voff_sk;
                // check for velocity limit exceedance
                if(vk > vmax_sk)
                    break;
                // TARGET VELOCITY LOOP
                while(mkp1--){ // 100 % executions
                    size_t t_skp1_idx, vmap_vq_idx, vmap_vk_idx, fmap_freq_idx;
                    double dv, vq, dt, aq, tkp1, F_DRAG, F_REQ, 
                            F_TRACTION_TRAIN, dE, cost, new_cost;
                    // next velocity
                    const double vkp1 = vtwin->vrefloc_[mkp1] + voff_skp1;
                    // check for velocity limit exceedance
                    if(vkp1 > vmax_skp1)
                        continue;
                    // --- DISCRETE SOLUTION OF EQUATION OF MOTION ---
                    // >>> mp * a = - Drag(sk, vk) + F_trac
                    // Difference equations
                    dv = vkp1 - vk;          // velocity stepwidth of current step
                    vq = (vkp1 + vk) * 0.5;  // average velocity on transition
                    dt = sstep / vq;         // time of transition
                    aq = dv / dt;            // average acceleration on transition
                    // Check celeration constraints
                    if(aq < -max_decel){
                        break; // 2.4 % of inner loop executions
                    }
                    tkp1 = dt + tk;
                    // Check for being within time window
                    if(tkp1 < toff_skp1){
                        continue;
                    }
                    if(tkp1 > tmax_skp1){
                        break;
                    }
                    // Compute time index
                    t_skp1_idx = (size_t)(((tkp1-toff_skp1) * vtwin->tstep_r) + 0.5);
                    // CHECK BOUNDS - t_skp1_idx
                    // (to prevent segfaults)
                    if(t_skp1_idx >= nt){
                        break;
                    }
                    // Check for valid follow up state
                    if(matout->costToEnd[IND3(mkp1, t_skp1_idx, k+1, nv, nt)] == Inf){
                        continue; // 24.4 % of inner loop executions
                    }
            // TRACTION FORCE COMPUTATION
                    // Get index for average velocity
                    vmap_vq_idx = (size_t)(vq*fmapsvel->vmapstep_r + 0.5);
                    // Compute total drag force: F(s, v)
                    F_DRAG = fmapsvel->train_drag_at_vq_[vmap_vq_idx] + route_drag_sk;
                    // ----- Equation of motion -----
                    // Compute required transition traction force
                    // F = m*p*a + Drag(s, v)
                    F_REQ = total_dynmass * aq + F_DRAG; 
                    // Differentiate + / - traction force
                    if(F_REQ > 0){
                        // stop iteration if maximum transmittable force is exceeded
                        if(F_REQ > fmapsvel->ftransmax){
                            continue; // 8.3 % of inner loop executions
                        }
                        // Get index for step divisible velocity
                        vmap_vk_idx = (size_t)(MAX(vkp1, vk) * fmapsvel->vmapstep_r + 0.5);
                        // Get max available traction force for max transition velocity
                        F_TRACTION_TRAIN = fmapsvel->trac_force_at_vq_[vmap_vk_idx];

                        if(F_REQ > F_TRACTION_TRAIN){
                            continue; // 10 % of inner loop executions
                        }
                    }
                    // Check for maximum negativ transmittable force, so that
                    // fmap_freq_idx will be within bounds
                    if(F_REQ < -fmapsvel->ftransmax){
                        break;
                    }
                    // --- all fine, acquire transition cost and save ---
                    // Get index for discretized traction force
                    fmap_freq_idx = (size_t)((F_REQ + fmapsvel->ftransmax) * fmapsvel->fmapstep_r + 0.5);
                    // CHECK BOUNDS for fmap_freq_idx
                    if(fmap_freq_idx >= fmapsvel->len_costfunc){
                        continue;
                    }
                    // 54.5 % of inner loop executions
                    cost = fmapsvel->costFunction[fmap_freq_idx + (vmap_vq_idx * fmapsvel->len_costfunc)];
                    dE = cost * dt; // our transition cost value (dE)
                    // Compute cost for current state
                    new_cost = dE + matout->costToEnd[IND3(mkp1, t_skp1_idx, k + 1, nv, nt)];
                    // Replace temporary transition is current transition is better
                    if(new_cost < tmp_c){
                        tmp_c = new_cost;
                        tmp_it = t_skp1_idx;
                        tmp_iv = mkp1;
                        tmp_f = F_REQ;
                        tmp_e = dE;
                        tmp_t = dt;
                    }
                } // END TARGET VELOCITY LOOP

                // Store transition to output
                if(tmp_c < Inf){
                    size_t idx = IND3(mk, h, k, nv, nt);
                    matout->costToEnd[idx]  = tmp_c;
                    matout->optV_ind[idx]  = (uint8_T )tmp_iv + 1; // MATLAB index conversion
                    matout->optT_ind[idx]  = (uint16_T)tmp_it + 1; // by increment
                    matout->transTimes[idx] = tmp_t;

                    if(matout->save_all){
                        matout->transForces[idx]   = tmp_f;
                        matout->transEnergies[idx] = tmp_e;
                    }
                    tmp_c = Inf;
                }
            } // END INIT VELOCITY LOOP
        } // END TIME LOOP
        // print loop state
        print_state(tloop, k+1, ns, &prodiv);
    } // END POSITIONAL LOOP
    // END OF RECURSION
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2014-10-23 10:59:38

您可以做的第一件事是更多描述性变量名称。我知道命名东西很难,但请不要这么神秘。

其次,将您的tmp_*放在结构中的“初始速度循环”中将更加清晰,并允许您将“目标速度循环”放在一个只返回该结构的单独函数中(不需要记住返回值的顺序)。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/67671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档