在webots中绘制数据曲线

文档创建日期:2023年4月14日

文档内容:如何在webots中绘制数据值随时间变化的曲线

文档作者:RobotFreak

在webots中进行机器人仿真时,不可避免地也会用到pid,在对pid进行调参的过程中,曲线图十分重要。单纯只通过终端看数据的数值变化很难调出比较理想的效果,还是需要曲线图看波形才可以。于是有一个能画图的节点就十分重要。

通过查阅webots的Webots documentation: Display (cyberbotics.com),发现Display节点可以实现画图、可视化的功能。

webots中的Display节点可以模拟一个嵌入式屏幕,或者显示任何图形信息例如图表,文本,机器人轨迹,滤波后的摄像头图像等等。

显示Display的overlay

想要显示display的overlay小窗口需要取消勾选Overlays中的Hide All Display Overlays:

在这里插入图片描述

Display初始化

主要是根据display的名称获取DeviceTag,对参数初始化。

void initDisplay(Display* displayPtr)
{
    
    
	displayPtr->id = wb_robot_get_device(displayPtr->name);
	displayPtr->width = wb_display_get_width(displayPtr->id);
	displayPtr->height = wb_display_get_height(displayPtr->id);
	displayPtr->maxValue = DISPLAY_FOOTY_MAX_VALUE;
	displayPtr->pointToDraw.x = 0;
	displayPtr->pointToDraw.y = 0;
}

Display是一个结构体,保存了显示设备的相关参数和信息。

typedef struct
{
    
    
	WbDeviceTag id;
	const char* name;
	int height;        //display的高度(像素数)
	int width;         //display的宽度(像素数)
	double maxValue;   //display的显示数据的最大值,y轴最大值(绝对值)
	Point2DimInt pointToDraw; //要画的点

}Display;

在Display中画出数据曲线

画曲线有两个思路:

  1. 每次画一个点,逐个像素的画pixel
  2. 画直线,两次数据的横坐标(t)可以有一定间隔但不能太大

第一种思路

第一种思路的实现方法如下:

void displayDrawPoint(Display* displayPtr, double value)
{
    
    
	if (displayPtr->pointToDraw.x >= displayPtr->width) //限制在宽的范围内
		displayPtr->pointToDraw.x = 0;
	displayPtr->pointToDraw.x += 1; //逐渐往后画
	int midHeight = displayPtr->height / 2; //中间高度,向上为正(y变小),向下为负(y变大)
	displayPtr->pointToDraw.y = midHeight - value / displayPtr->maxValue * midHeight; //根据要画的值与最大值的比值决定点的y坐标
	wb_display_draw_pixel(displayPtr->id, displayPtr->pointToDraw.x, displayPtr->pointToDraw.y); //画一个像素
	//如何从左到右画完一次之后再次从左边开始时不受之前画的影响?

}

因为我想在display中画出分正负的曲线,所以我以高的中间(y轴)为基准,向上为正,向下为负,越偏离基准线,绝对值就越大。

按照第一种思路画出来实现的效果如下:

在webots中绘制数据曲线_画点

猜你喜欢

转载自blog.csdn.net/svfsvadfv/article/details/130192676
今日推荐