简易示波器
前言
最近在使用Webots进行机器人仿真,但是软件似乎不支持单步调试,也没有能绘制波形的调试工具。不过好在可以添加display组件,也就像是一块小屏幕,所以可以自己实现一个比较好用的示波器。
我也将代码封装到了一个.h文件中,无论是Webots中的虚拟屏幕,还是平时装在小车上的OLED、LCD,只需要修改一下绘制像素点或者线条的接口函数,修改一下屏幕尺寸,就可以轻松移植使用了。
代码地址
代码中含有”wb”的为webots库函数,需修改。
效果演示
结构体介绍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
typedef struct __Piont_t { int x,y; }Point_t;
typedef struct __RingBuf_t { Point_t Points[RING_SIZE]; short head, tail; }RingBuf_t;
typedef struct __Channel_t { bool enable; uint32_t color; RingBuf_t R; double range; }Channel_t;
typedef struct __Display_t { int width, height; WbDeviceTag tag; Channel_t Channels[CHANNEL_NUM]; double data[CHANNEL_NUM]; }Display_t;
|
一个示波器可以绘制CHANNEL_NUM个波形。每个通道的最高处和最低处分别对应该数据的最大值和最小值
使用方法
修改参数
1 2 3 4
| #define MAX_WIDTH 512 #define MAX_HEIGHT 256 #define RING_SIZE MAX_WIDTH #define CHANNEL_NUM 4
|
通过宏定义修改屏幕长宽,以及想要显示的波形数量
初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
void displayInit(Display_t *D) { D->tag = wb_robot_get_device("display"); D->height = wb_display_get_height(D->tag); D->width = wb_display_get_width(D->tag); if (D->tag == 0) { printf("Error: Can't find the display"); return; } else { printf("Display found! %d x %d\n", D->width, D->height); }
for(int i=0; i<CHANNEL_NUM; i++) { D->Channels[i].enable = false; D->Channels[i].R.head = 0; D->Channels[i].R.tail = 0; }
channelEnable(D, 0, 0x0000ff, 1.5); channelEnable(D, 1, 0xff0000, 1); channelEnable(D, 2, 0x00ff00, 1); channelEnable(D, 3, 0xffff00, 1); return; }
|
其中wb开头的函数是webots的库函数,使用的时候修改掉即可。通过channelEnable
使能波形通道,定义序号、颜色、范围。
图形绘制
在updateDis
函数中修改绘制图形的函数为自己的函数即可。
1 2
| wb_display_draw_line(D->tag, point.x, point.y, next_point.x, next_point.y);
|
最后在自己任务的while
函数(或者再套一个函数)中添加想要示波的数据即可,比如之前的示例
1 2 3 4 5 6 7 8 9 10 11 12
| while(...) { ... display.data[0] = key; display.data[1] = sin(wb_robot_get_time()); display.data[2] = cos(wb_robot_get_time()); display.data[3] = fabs(fmod(wb_robot_get_time(), 2) - 1); addDisData(&Dormily.display); updateDis(&Dormily.display); }
|