繁体   English   中英

间歇性错误-有时此代码有效,有时却无效!

[英]Intermittent bugs - sometimes this code works and sometimes it doesn't!

此代码间歇性地工作。 它在小型微控制器上运行。 即使重新启动处理器,它也能正常工作,但是如果我更改了部分代码,它就会中断。 这使我认为这是某种指针错误或内存损坏。 发生的是坐标,将p_res.pos.x传递给write_circle_outlined时有时会读取为0(错误值)和96(正确值)。 y在大多数情况下似乎是正确的。 如果有人发现明显错误的地方,请指出!

int demo_game()
{
    long int d;
    int x, y;
    struct WorldCamera p_viewer;
    struct Point3D_LLA p_subj;
    struct Point2D_CalcRes p_res;
    p_viewer.hfov = 27;
    p_viewer.vfov = 32;
    p_viewer.width = 192;
    p_viewer.height = 128;
    p_viewer.p.lat = 51.26f;
    p_viewer.p.lon = -1.0862f;
    p_viewer.p.alt = 100.0f;
    p_subj.lat = 51.20f;
    p_subj.lon = -1.0862f;
    p_subj.alt = 100.0f;
    while(1)
    {
        fill_buffer(draw_buffer_mask, 0x0000);
        fill_buffer(draw_buffer_level, 0xffff);
        compute_3d_transform(&p_viewer, &p_subj, &p_res, 10000.0f);
        x = p_res.pos.x;
        y = p_res.pos.y;
        write_circle_outlined(x, y, 1.0f / p_res.est_dist, 0, 0, 0, 1);
        p_viewer.p.lat -= 0.0001f; 
        //p_viewer.p.alt -= 0.00001f; 
        d = 20000;
        while(d--);
    }
    return 1;
}

compute_3d_transform的代码为:

void compute_3d_transform(struct WorldCamera *p_viewer, struct Point3D_LLA *p_subj, struct Point2D_CalcRes *res, float cliph)
{
    // Estimate the distance to the waypoint. This isn't intended to replace
    // proper lat/lon distance algorithms, but provides a general indication
    // of how far away our subject is from the camera. It works accurately for 
    // short distances of less than 1km, but doesn't give distances in any
    // meaningful unit (lat/lon distance?)
    res->est_dist = hypot2(p_viewer->p.lat - p_subj->lat, p_viewer->p.lon - p_subj->lon);
    // Save precious cycles if outside of visible world.
    if(res->est_dist > cliph)
        goto quick_exit;
    // Compute the horizontal angle to the point. 
    // atan2(y,x) so atan2(lon,lat) and not atan2(lat,lon)!
    res->h_angle = RAD2DEG(angle_dist(atan2(p_viewer->p.lon - p_subj->lon, p_viewer->p.lat - p_subj->lat), p_viewer->yaw));
    res->small_dist = res->est_dist * 0.0025f; // by trial and error this works well.
    // Using the estimated distance and altitude delta we can calculate
    // the vertical angle.
    res->v_angle = RAD2DEG(atan2(p_viewer->p.alt - p_subj->alt, res->est_dist));
    // Normalize the results to fit in the field of view of the camera if
    // the point is visible. If they are outside of (0,hfov] or (0,vfov]
    // then the point is not visible.
    res->h_angle += p_viewer->hfov / 2;
    res->v_angle += p_viewer->vfov / 2;
    // Set flags.
    if(res->h_angle < 0 || res->h_angle > p_viewer->hfov)
        res->flags |= X_OVER;
    if(res->v_angle < 0 || res->v_angle > p_viewer->vfov)
        res->flags |= Y_OVER;
    res->pos.x = (res->h_angle / p_viewer->hfov) * p_viewer->width;
    res->pos.y = (res->v_angle / p_viewer->vfov) * p_viewer->height;
    return;
quick_exit:
    res->flags |= X_OVER | Y_OVER;
    return;
}

结果的结构:

typedef struct Point2D_Pixel { unsigned int x, y; };

// Structure for storing calculated results (from camera transforms.)
typedef struct Point2D_CalcRes
{
    struct Point2D_Pixel pos;
    float h_angle, v_angle, est_dist, small_dist;
    int flags;
};

该代码是我的一个开源项目的一部分,因此可以在此处发布很多代码。

我看到您的某些计算取决于p_viewer->yaw ,但看不到p_viewer->yaw任何初始化。 这是你的问题吗?

几件事似乎很粗略:

  • 您可以在不设置p_res / res许多字段的情况下从compute_3d_transform返回,但是调用者从不检查这种情况。

  • 您始终从res->flags读取数据,而无需先对其进行初始化。

当我使用C语言进行编程时,我将使用分治法调试技术来解决此类问题,以尝试分离出有问题的操作(注意添加调试代码后症状是否会发生变化,这表明指针类型的bug悬而未决。 )。

从本质上讲,先从其中值是已知良好的第一行(并证明它一贯擅长这行)。 然后确定已知的不良之处。 然后大约。 在两点中间插入一个测试,看是否不好。 如果不是,则在中间点和已知的不良位置之间插入一个测试的中间位置;如果不好,则在中间点和已知的良好位置之间插入一个测试的中间位置,依此类推。

如果标识的行本身是函数调用,则可以在该调用的函数中重复此过程,依此类推。

当使用这种方法时,重要的是要最小化增加的代码量和可能造成时序变化的人为“噪声”。

如果您没有(或无法使用)交互式调试器,或者在使用交互式调试器时问题没有显现,请使用此选项。

只要输出不同,就可能意味着某些值未初始化,并且结果取决于变量中存在的垃圾值。 牢记这一点,我在寻找未初始化的变量。 p_res结构未初始化。

if(res->est_dist > cliph)
        goto quick_exit;

这意味着,根据res-> est_dist中存储的垃圾值,条件是否可能为true或false。 如果条件变为true,则直接进入quick_exit标签,并且不更新p_res.pos.x。 如果条件被证明是错误的,则对其进行更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM