1.合宙Air780E|内网穿透|LuatOS-SOC接口|MQTT|学习(22):4G远程遥控小车
2.Apollo EM中path_assesment_task相关细节的度源码讨论
3.PCA9685:I2C转16路PWM,助力你的度源码系统
4.CMake搭建OpenGL开发环境
5.求一份用C语言编写的俄罗斯方块的源代码!
合宙Air780E|内网穿透|LuatOS-SOC接口|MQTT|学习(22):4G远程遥控小车
基于AirE开发板的度源码4G远程遥控小车项目涉及硬件和软件两大部分。硬件方面,度源码所需设备包括一块AirE开发板和一张SIM卡。度源码使用了LuaTools2.1.作为调试工具,度源码合体鸭源码以及LuatOS@EC base . bsp V bit版本的度源码固件。内网穿透采用AirTun协议,度源码相关说明在gitee.com/openLuat/luat...。度源码硬件上,度源码选择USB-AM /度 DIY插头贴片USB A型接口公头作为连接器。度源码遥控小车车身组装包含购买相关组装教程或视频,度源码根据成品图样自行组装,度源码电路部分需将电机接线引出,度源码电池盒选用充电宝供电。度源码
在软件方面,将4G遥控车源码烧录至AirE模块,该源码位于gitee.com/openLuat/luat...。烧录完成后,控制台会显示控制端网址,记录下来并打开任意浏览器即可控制小车。此过程无需关注、转发、点赞、评论等操作,直接尝试遥控小车。
项目待完成的app租赁模板源码部分包括图传设置及解析。此文章内容对您有所帮助时,请考虑关注、点赞支持作者的持续创作。
Apollo EM中path_assesment_task相关细节的讨论
网上已有关于本task流程的详细注释,本文主要探讨Apollo EM中path_assesment task的内部算法细节。
首先,我们来看SetPathPointType函数。函数中,ego_center_shift_distance代表车体几何中心距离后轴中心的距离。初始化过程中,以车体后轴中心点为基准获取整个车体Box。ego_box所调用的Shift函数将后轴中心点前移至车体几何中心点并计算box四个角的位置。这样做的原因是,Control使用后轴中心点跟踪每一个pathpoint,而本车SLboundary依据其几何中心点在参考线上进行投影,因此这一步转化是必不可少的。
Shift函数内所调用的InitCorners()如上图所示,其中cos_heading,sin_heading_,half_length_,half_width_,center_,是在Box2d初始化时进行赋值。简单用图示介绍一下含义:X-Y用于表示地图坐标系,x-y用于表示将地图坐标系平移至车体几何中心点之后的坐标系,[公式] 用于表示heading。特别解释一下:此处的使用 [公式] 来表示长度half_width x[公式]。
获取到本车box的四个角的坐标之后,再将依靠参考线将box转化到SL坐标系下的boundary。之后遍历SL坐标系下每个pathpoint,计算自车位于每个pathpoint的html图片特效源码时候所对应的车体的边界。将边界与车道线比较,判断每个pathpoint的类型(在lane_borrow/lane_change决策下是在旁车道还是本车道)。此处不粘贴源码,直接用图示进行说明各种情况。
需要注意:由于要在统一的坐标系下进行比较,所以,采用-right_width。所以对应上图的情况,即处于车道边界之外还没换道的情况:start_l>lane_left_width || end_1<-lane_right_width此时type为IN_LANE。对应上图情况,即严格处于本车边界之内的车辆,需要考虑将车道边界添加buffer:所以本车实际处于虚线之内,此时的type为IN_LANE,表示已经换道完成。其它状态下为lane_change的过渡状态,type为OUT_ON_FORWARD_LANE。
需要注意的是:由于借道其实是拐入别的车道一点点之后再拐回来,所以需要添加动态的迟滞边界in_and_out_lane_hysteresis_buffer,来对pathpoint进行严格地区分。类似的做法在量产ADAS功能中也用到,主要用于对前方动态Target的识别,目的是为了防止障碍车辆沿车道线来回画龙或压线行驶的情况。扯远了~
如上述,因为借道只是占据旁车道一点点,所以判断条件与lane_change略有不同,此处的e语言getsubmenu源码判断条件使用end_l与lane_left_width相比较,start_l与-lane_right_width相比较。
如上图所示,当前一个路径点在车道内(is_prev_point_out_lane = false),即绿点所在位置,则判断lane_borrow的条件:此时,in_and_out_lane_hysteresis_buffer = 0.2;当前一个路径点在车道内(is_prev_point_out_lane = true),即红点所在位置,此时,in_and_out_lane_hysteresis_buffer = 0;
接下来讨论path与静态障碍物collision的问题:具体流程图参见下图:IsCollidingWithStaticObstacles中流程概述:过滤掉虚拟障碍物,高速运动障碍物等,按照固定距离的pathpoint建立VehBox,所有点转化为Frenet坐标系,调用函数IsPointIn检验所有点是否处于障碍物的内部。
下面开始详细讲解IsPointIn函数:首先判断本车的Corner点是否在障碍物边界上,如果不在,则进行下一步取Corner点在与轴方向异侧的两个点,分别于Corner点构成向量,之后做叉乘,叉乘结果若大于0,则比较两个点的y值,若y值结果小于0,则看向量正旋转到目标向量的实际角度是否小于度,若小于,则c由零变为1;若y值结果为大于,则看向量正旋转到目标的实际角度是否大于度,若大于,类头脑王者源码则c由零变为1。同理再构建另外两个向量,若与上述情况相同,则c由1变为2。最后判断C为奇数还是偶数,如果为奇数,则返回true,表示Corner点处于Obstacle内部。如果为偶数,则表示Corner点在Obstacle外部。
下面举个栗子:对于左图A点的这种情况,0点与3点在Y轴方向上位于A点异侧,0.y<3.y,side>0(即比较向量A-0正旋转到目标向量A-3是否小于度),实际大于度(蓝色箭头),结果为否,则c值仍为0;2点与1点在Y轴方向上位于A点异侧,side<0(即比较向量A-2正旋转到目标向量A-1是否大于度),实际大于度(红色箭头),结果为是,则c值变为1。最终c&1为奇数,表示A点在obstacle之内。
对于右图A点情况,0点与3点在Y轴方向上位于A点异侧,0.y<3.y,side>0(即比较向量A-0正旋转到目标向量A-3是否小于度),实际小于度(红色箭头),结果为是,c值由0变为1;2点与1点在Y轴方向上位于A点异侧,side<0(即比较向量A-2正旋转到目标向量A-1是否大于度),实际大于度(蓝色箭头),结果为是,则c值变为2。最终c&1为偶数,表示A点在obstacle之外。
正旋转相关的知识:叉乘几何含义:须注意:本算法所有的坐标系为上图所示,所以正旋转方向为X轴沿绿三色箭头转到Y轴。
最后依旧借用M星云男神女神镇楼。。
PCA:I2C转路PWM,助力你的系统
PCA是一种主要用作I2C转路PWM的集成电路,适用于舵机控制、LED颜色控制等。其控制精度在Hz的控制频率下,脉宽为0.5ms~2.5ms,具备位分辨率(级),具体精度计算需参考相关资料。
PCA有两种封装形式:TSSOP与HVQFN,各有相应的引脚排列。每个引脚的功能描述如下图所示。引脚A0-A5共同决定器件地址,由于有6个引脚参与,因此可有个不同的器件地址。除了LED All Call address (E0h)和Software Reset address (h)外,实际可用地址为个,理论上,1个I2C接口可控制多达路PWM。器件地址的设置示意图如下图所示。默认情况下,若A0-A5全部接地,则器件地址为0x。
默认状态下,上电复位后,寄存器地址默认值为0,具体寄存器地址及其用途见下图。重点关注以下寄存器:模式设置寄存器、PWM通道寄存器与占空比设置、PWM周期(频率)寄存器与周期(频率)设置。
在使用模式设置寄存器时,需注意以下事项:首先介绍MODE1寄存器,其功能如下图所示。在配置模式时,特别关注MODE2寄存器的各位功能,如图所示。
PWM通道寄存器的设置如下图所示,每个通道有4个寄存器,每个寄存器图解如图所示。在设置PWM占空比时,首先配置舵机,例如ON < OFF情况。特殊情况下,PWM周期大于定时器一次计数时,配置ON>OFF情况。
配置PWM频率时,一般采用内置晶振,频率为MHz。通过配置PRE_SCALE寄存器来调整频率,其与PWM频率的关系见下图。若使用内置晶振,取osc_clock=,update_rate=(舵机控制频率Hz)。
推荐硬件设计时,确保OE引脚接低电平以确保IC使能。若连接LED灯,则推荐连接方式如下图所示。
软件设计部分,Micro:bit平台采用TypeScript(JavaScript的超类)进行底层开发,提供基本操作方法及其思路。日后再更新C、C++及其它平台(STM、Linux树莓派、Arduino等)的操作方法。Micro:bit驱动PCA的源代码提供,注意源代码中的时间为us,与教程中的ms不同。
树莓派平台采用Python驱动PCA,首先安装Python和smbus库。Python代码如下所示,保存文件名为pca.py,命令行进入该文件所在的路径,运行该Python脚本。执行命令后,即可控制舵机从0度转到度,再从度转到0度。
CMake搭建OpenGL开发环境
在Ubuntu.环境中搭建OpenGL开发环境,主要采用GLFW和GLAD。
首先,编译GLFW,遵循GLFW官网提供的编译指南,利用CMake进行编译。
Ubuntu用户可以直接安装libglfw3-dev依赖。
确认所使用的环境为X系统,并安装相应依赖。
访问GLAD官网,下载zip压缩包,解压后将include文件夹移动到/usr/local/include目录,并将glad.c文件放置在工程目录中。
创建测试工程,包含CMakeLists.txt文件和main.cpp。
欲深入了解OpenGL,可参考LearnOpenGL CN主页。
加入glm库,获取链接:github.com/g-truc/glm。
步骤如下:直接将glm源码下载到thirdparty目录;
修改CMakeLists.txt文件,加入相关配置。
调整顶点着色器,添加模型常量句柄,以便与shader program链接。
使用glm库旋转度,实现特定效果。
最终结果如下所示。
求一份用C语言编写的俄罗斯方块的源代码!
俄罗斯方块C源代码#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
#define ZL 4 //坐标增量, 不使游戏窗口靠边
#define WID //游戏窗口的宽度
#define HEI //游戏窗口的高度
int i,j,Ta,Tb,Tc; // Ta,Tb,Tc用于记住和转换方块变量的值
int a[][]={ 0}; //标记游戏屏幕各坐标点:0,1,2分别为空、方块、边框
int b[4]; //标记4个"口"方块:1有,0无,类似开关
int x,y, level,score,speed; //方块中心位置的x,y坐标,游戏等级、得分和游戏速度
int flag,next; //当前要操作的方块类型序号,下一个方块类型序号
void gtxy(int m, int n); //以下声明要用到的自编函数
void gflag( ); //获得下一方块序号
void csh( ); //初始化界面
void start( ); //开始部分
void prfk ( ); //打印方块
void clfk( ); //清除方块
void mkfk( ); //制作方块
void keyD( ); //按键操作
int ifmov( ); //判断方块能否移动或变体
void clHA( ); //清除满行的方块
void clNEXT( ); //清除边框外的NEXT方块
int main( )
{ csh( );
while(1)
{ start( ); //开始部分
while(1)
{ prfk( );
Sleep(speed); //延时
clfk( );
Tb=x;Tc=flag; //临存当前x坐标和序号,以备撤销操作
keyD( );
y++; //方块向下移动
if (ifmov( )==0) { y--; prfk( ); dlHA( ); break;} //不可动放下,删行,跨出循环
}
for(i=y-2;i<y+2;i++){ if (i==ZL) { j=0; } } //方块触到框顶
if (j==0) { system("cls");gtxy(,);printf("游戏结束!"); getch(); break; }
clNEXT( ); //清除框外的NEXT方块
}
return 0;
}
void gtxy(int m, int n) //控制光标移动
{ COORD pos; //定义变量
pos.X = m; //横坐标
pos.Y = n; //纵坐标
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
void csh( ) //初始化界面
{ gtxy(ZL+WID/2-5,ZL-2); printf("俄罗斯方块"); //打印游戏名称
gtxy(ZL+WID+3,ZL+7); printf("