我希望仿真的传感器切换功能是这样的:保留manual_control.py的切换传感器功能,但是切换后不销毁上一个传感器,切换仅是把当前传感器的数据以图像的方式展示在屏幕上,其他的传感器依旧接受数据。
所以,传感器在创建后就不会被销毁(除了退出时),始终调用listen函数监听从服务端发送的数据。因此我写了一个函数,用于创建传感器并监听数据:
def set_all_sensor(self):
for i in range(len(self.sensors)):
self.sensors_stream.append(self._parent.get_world().spawn_actor(
self.sensors[i][-1],
self._camera_transforms[i][0],
attach_to=self._parent,
attachment_type=self._camera_transforms[i][1]))
self.sensors_stream[i].listen(lambda image: self._parse_image(image, i))
初看时,觉得逻辑完美:sensors_stream为创建的传感器Actor列表,在创建后就始终监听。但是遇到了仅最后一个传感器接受到数据且收到的数据是其他传感器才应接受的数据。
尝试了很多方法,比如多进程。这样每个进程的数据是独立的,就不会相互影响了。但是不管我怎么尝试的测试写法能顺利运行,而真的写在脚本中缺始终报错,原因不明。
最后反应过来,问题就出在这个循环上,因为在每一个循环中,监听的函数是始终保持运行的。而每个监听函数中有一个i变量,而每个循环后i都会发生改变,这就导致了最终每个传感器接受到的i最终都是传感器的总数——也就是尽管所有传感器都接受到了自己应有的数据,但是_parse_image函数的i变量是相同的,最终都会发给最后一个接口,这就导致接受信息的混乱。修改后代码如下:
def set_all_sensor(self):
for i in range(len(self.sensors)):
self.sensors_stream.append(self._parent.get_world().spawn_actor(
self.sensors[i][-1],
self._camera_transforms[i][0],
attach_to=self._parent,
attachment_type=self._camera_transforms[i][1]))
self.sensors_stream[0].listen(lambda image: self._parse_image(image, 0))
self.sensors_stream[1].listen(lambda image: self._parse_image(image, 1))
self.sensors_stream[2].listen(lambda image: self._parse_image(image, 2))
self.sensors_stream[3].listen(lambda image: self._parse_image(image, 3))
self.sensors_stream[4].listen(lambda image: self._parse_image(image, 4))
self.sensors_stream[5].listen(lambda image: self._parse_image(image, 5))
self.sensors_stream[6].listen(lambda image: self._parse_image(image, 6))
self.sensors_stream[7].listen(lambda image: self._parse_image(image, 7))
也想不到更好的做法,只好写死。
总的来说,还是对回调函数的理解有误,for循环中的listen函数始终保持运行但是i会改变。
但现在也有新的问题没有解决:传感器和车辆无法销毁,还有就是如果在cmd的界面点击一下鼠标,就导致客户端卡死,只能强行关掉。