Monthly Archives: September 2009

放慢模拟节奏

昨天的模拟开始很好,后来改了一些参数之后速度巨大,发指啊……

后来调试了半天,发现一个问题:

if (destTime > now )
{
speed = sqrt((node->X_ – x)*(node->X_ – x) + (node->Y_ – y)*(node->Y_ – y)) / (destTime – now);
其中destTime和now都是double类型,当两者相等(但存储上可能不同),例如destTime = 5.0001,now= 5.000001,这个时候if条件满足,然后进去执行,speed变成一个天文数字……,看来浮点数的运算始终要加以个值啊。
将 if (destTime > now)改为 if (destTime > now + DELTA),再加上#define DELTA 0.001。这样就可以了。

还有一个问题是,我每隔0.1秒执行查询节点状态,居然发现0.x秒时候节点位置不变,这样0.1-0.9秒速度均为0,而到1.0的时候才变化。后来想了半天,估计是sumo单步模拟只能逐秒进行。我后来问了邮件列表,果然如此。启用0.1秒模拟需要重新编译,加上参数–enable-subsecond,但是作者原话是“Please note that this is not yet completed – it works, but the vehicle behaviour at intersections is very bad.”

算了,还是我自己弄一个近似模拟吧,想想看比赛的慢动作,距离不变,时间变长的话,那么速度就变慢了。这样想就清除了:

1 地图的大小不变
2 时间模拟理论上会增加10倍,那么这样1秒就相当于0.1秒了,速度直接除以10即可,而加速度需要除以100.
3 需要设置的地方是,tcl中的模拟时间大约要增加到10倍,edge.xml中的道路速度除以10,route.xml文件中的vtype中的车辆accel和decel除以100,maxspeed除以10。

基本上这样就可以了。可以看出最后的模拟时间变长为10倍,而速度变成原来的十分之一。两者略有差异,原因就是,模拟的颗粒越细,结果自然越精确了。

ns2 segment fault

完成了一个发送beacon的程序,但是出现segment fault了,调试到最后发现是channel.cc中在更新节点的时候链表出问题了。再仔细一看,发现是原来的逻辑是需要链表是有序的,结果几次调用之后居然无序了,有一些节点的值进行变化,但是节点链表中的顺序始终不变,导致问题出现了。
再深入看一下,原来是TransV1.2中竟然手动设置节点的位置,而不是调用set_destination函数:
// set node exactly to old destination
node->X_ = node->destX_;
node->Y_ = node->destY_;
// move node to position
// velocity = space / time
if (destTime > now)
{
speed = sqrt((node->X_ – x)*(node->X_ – x) + (node->Y_ – y)*(node->Y_ – y)) / (destTime – now);
// set_destination returns 0 on success
if ( node->set_destination(x, y, speed) )

奇怪的是作者一边手动赋值,一边又调用函数,真得不知道怎么想的,sigh

给我的感觉是ns2跟其他的扩展结合的太紧密了,很容易就出错啊……