一、单片机编程人工智能?
摘要:不知道大家有没有这样一种感觉,就是感觉自己玩单片机还可以,各个功能模块也都会驱动,但是如果让你完整的写一套代码,却无逻辑与框架可言,上来就是开始写!东抄抄写抄抄。说明编程还处于比较低的水平,那么如何才能提高自己的编程水平呢?学会一种好的编程框架或者一种编程思想,可能会受用终生!比如模块化编程,框架式编程,状态机编程等等,都是一种好的框架。
今天说的就是状态机编程,由于篇幅较长,大家慢慢欣赏。那么状态机是一个这样的东东?状态机(state machine)有5个要素,分别是状态(state)、迁移(transition)、事件(event)、动作(action)、条件(guard)。
什么是状态机?
状态机是一个这样的东东:状态机(state machine)有 5 个要素,分别是状态(state)、迁移(transition)、事件(event)、动作(action)、条件(guard)。
状态:一个系统在某一时刻所存在的稳定的工作情况,系统在整个工作周期中可能有多个状态。例如一部电动机共有正转、反转、停转这 3 种状态。
一个状态机需要在状态集合中选取一个状态作为初始状态。
迁移:系统从一个状态转移到另一个状态的过程称作迁移,迁移不是自动发生的,需要外界对系统施加影响。停转的电动机自己不会转起来,让它转起来必须上电。
事件:某一时刻发生的对系统有意义的事情,状态机之所以发生状态迁移,就是因为出现了事件。对电动机来讲,加正电压、加负电压、断电就是事件。
动作:在状态机的迁移过程中,状态机会做出一些其它的行为,这些行为就是动作,动作是状态机对事件的响应。给停转的电动机加正电压,电动机由停转状态迁移到正转状态,同时会启动电机,这个启动过程可以看做是动作,也就是对上电事件的响应。
条件:状态机对事件并不是有求必应的,有了事件,状态机还要满足一定的条件才能发生状态迁移。还是以停转状态的电动机为例,虽然合闸上电了,但是如果供电线路有问题的话,电动机还是不能转起来。
只谈概念太空洞了,上一个小例子:一单片机、一按键、俩 LED 灯(记为L1和L2)、一人, 足矣!
【学习交流群】不知道怎么学?遇到问题没人问?到处找资料?邀请你加入我的嵌入式物联网单片机学习交流群,群内气氛活跃,大咖小白、在职、学生都有,还有群友整理收集的100G教程资料,点击下方进群占位。(点击跳转到群二维码,请放心点击!)
知乎-嵌入式物联网单片机学习交流群规则描述:
1、L1L2
状态转换顺序OFF/OFF--->ON/OFF--->ON/ON--->OFF/ON--->OFF/OFF
2、通过按键控制L1L2
的状态,每次状态转换需连续按键5
次
3、L1L2
的初始状态OFF/OFF
下面这段程序是根据功能要求写成的代码。
程序清单List1:
void main(void)
{
sys_init();
led_off(LED1);
led_off(LED2);
g_stFSM.u8LedStat = LS_OFFOFF;
g_stFSM.u8KeyCnt = 0;
while(1)
{
if(test_key()==TRUE)
{
fsm_active();
}
else
{
; /*idle code*/
}
}
}
void fsm_active(void)
{
if(g_stFSM.u8KeyCnt > 3) /*击键是否满 5 次*/
{
switch(g_stFSM.u8LedStat)
{
case LS_OFFOFF:
led_on(LED1); /*输出动作*/
g_stFSM.u8KeyCnt = 0;
g_stFSM.u8LedStat = LS_ONOFF; /*状态迁移*/
break;
case LS_ONOFF:
led_on(LED2); /*输出动作*/
g_stFSM.u8KeyCnt = 0;
g_stFSM.u8LedStat = LS_ONON; /*状态迁移*/
break;
case LS_ONON:
led_off(LED1); /*输出动作*/
g_stFSM.u8KeyCnt = 0;
g_stFSM.u8LedStat = LS_OFFON; /*状态迁移*/
break;
case LS_OFFON:
led_off(LED2); /*输出动作*/
g_stFSM.u8KeyCnt = 0;
g_stFSM.u8LedStat = LS_OFFOFF; /*状态迁移*/
break;
default: /*非法状态*/
led_off(LED1);
led_off(LED2);
g_stFSM.u8KeyCnt = 0;
g_stFSM.u8LedStat = LS_OFFOFF; /*恢复初始状态*/
break;
}
}
else
{
g_stFSM.u8KeyCnt++; /*状态不迁移,仅记录击键次数*/
}
}
实际上在状态机编程中,正确的顺序应该是先有状态转换图,后有程序,程序应该是根据设计好的状态图写出来的。不过考虑到有些童鞋会觉得代码要比转换图来得亲切,我就先把程序放在前头了。
这张状态转换图是用UML(统一建模语言)的语法元素
画出来的,语法不是很标准,但拿来解释问题足够了。
圆角矩形代表状态机的各个状态,里面标注着状态的名称。
带箭头的直线或弧线代表状态迁移,起于初态,止于次态。
图中的文字内容是对迁移的说明,格式是:事件[条件]/动作列表(后两项可选)。
“事件[条件]/动作列表”要说明的意思是:如果在某个状态下发生了“事件”,并且状态机
满足“[条件]”,那么就要执行此次状态转移,同时要产生一系列“动作”,以响应事件。在这个例子里,我用“KEY”表示击键事件。
图中有一个黑色实心圆点,表示状态机在工作之前所处的一种不可知的状态,在运行之前状态机必须强制地由这个状态迁移到初始状态,这个迁移可以有动作列表(如图1所示),但不需要事件触发。
图中还有一个包含黑色实心圆点的圆圈,表示状态机生命周期的结束,这个例子中的状态机生生不息,所以没有状态指向该圆圈。
关于这个状态转换图就不多说了,相信大家结合着上面的代码能很容易看明白。现在我们再聊一聊程序清单List1。
先看一下fsm_active()
这个函数,g_stFSM.u8KeyCnt = 0;
这个语句在switch—case
里共出现了 5 次,前 4 次是作为各个状态迁移的动作出现的。从代码简化提高效率的角度来看,我们完全可以把这 5 次合并为 1 次放在 switch—case 语句之前,两者的效果是完全一样的,代码里之所以这样啰嗦,是为了清晰地表明每次状态迁移中所有的动作细节,这种方式和图2的状态转换图所要表达的意图是完全一致的。
再看一下g_stFSM
这个状态机结构体变量,它有两个成员:u8LedStat
和 u8KeyCnt
。用这个结构体来做状态机好像有点儿啰嗦,我们能不能只用一个像 u8LedStat 这样的整型变量来做状态机呢?
当然可以!我们把图 2中的这 4 个状态各自拆分成 5 个小状态,这样用 20 个状态同样能实现这个状态机,而且只需要一个 unsigned char 型的变量就足够了,每次击键都会引发状态迁移, 每迁移 5 次就能改变一次 LED 灯的状态,从外面看两种方法的效果完全一样。
假设我把功能要求改一下,把连续击键5次改变L1L2
的状态改为连续击键100次才能改变L1L2
的状态。这样的话第二种方法需要4X100=400
个状态!而且函数fsm_active()
中的switch—case语句里要有400个case
,这样的程序还有法儿写么?!
同样的功能改动,如果用g_stFSM
这个结构体来实现状态机的话,函数fsm_active()
只需要将if(g_stFSM.u8KeyCnt>3)
改为if(g_stFSM.u8KeyCnt > 98)
就可以了!
g_stFSM
结构体的两个成员中,u8LedStat
可以看作是质变因子,相当于主变量;u8KeyCnt
可以看作是量变因子,相当于辅助变量。量变因子的逐步积累会引发质变因子的变化。
像g_stFSM
这样的状态机被称作Extended State Machine
,我不知道业内正规的中文术语怎么讲,只好把英文词组搬过来了。
2、状态机编程的优点
说了这么多,大家大概明白状态机到底是个什么东西了,也知道状态机化的程序大体怎么写了,那么单片机的程序用状态机的方法来写有什么好处呢?
(1)提高CPU使用效率
话说我只要见到满篇都是delay_ms()
的程序就会蛋疼,动辄十几个ms
几十个ms
的软件延时是对CPU资源的巨大浪费,宝贵的CPU
机时都浪费在了NOP
指令上。那种为了等待一个管脚电平跳变或者一个串口数据而岿然不动的程序也让我非常纠结,如果事件一直不发生,你要等到世界末日么?
把程序状态机化,这种情况就会明显改观,程序只需要用全局变量记录下工作状态,就可以转头去干别的工作了,当然忙完那些活儿之后要再看看工作状态有没有变化。只要目标事件(定时未到、电平没跳变、串口数据没收完)还没发生,工作状态就不会改变,程序就一直重复着“查询—干别的—查询—干别的”这样的循环,这样CPU
就闲不下来了。在程序清单 List3 中,if{}else{}
语句里else
下的内容(代码中没有添加,只是加了一条/*idle code*/
的注释示意)就是上文所说的“别的工作
” 。
这种处理方法的实质就是在程序等待事件的过程中间隔性地插入一些有意义的工作,好让CPU
不是一直无谓地等待。
(2) 逻辑完备性
我觉得逻辑完备性是状态机编程最大的优点。
不知道大家有没有用C语言写过计算器的小程序,我很早以前写过,写出来一测试,那个惨不忍睹啊!当我规规矩矩的输入算式的时候,程序可以得到正确的计算结果,但要是故意输入数字和运算符号的随意组合,程序总是得出莫名其妙的结果。
后来我试着思维模拟一下程序的工作过程,正确的算式思路清晰,流程顺畅,可要碰上了不规矩的式子,走着走着我就晕菜了,那么多的标志位,那么多的变量,变来变去,最后直接分析不下去了。
很久之后我认识了状态机,才恍然明白,当时的程序是有逻辑漏洞的。如果把这个计算器程序当做是一个反应式系统,那么一个数字或者运算符就可以看做一个事件,一个算式就是一组事件组合。对于一个逻辑完备的反应式系统,不管什么样的事件组合,系统都能正确处理事件,而且系统自身的工作状态也一直处在可知可控的状态中。反过来,如果一个系统的逻辑功能不完备,在某些特定事件组合的驱动下,系统就会进入一个不可知不可控的状态,与设计者的意图相悖。
状态机就能解决逻辑完备性的问题。
状态机是一种以系统状态为中心,以事件为变量的设计方法,它专注于各个状态的特点以及状态之间相互转换的关系。状态的转换恰恰是事件引起的,那么在研究某个具体状态的时候,我们自然而然地会考虑任何一个事件对这个状态有什么样的影响。这样,每一个状态中发生的每一个事件都会在我们的考虑之中,也就不会留下逻辑漏洞。
这样说也许大家会觉得太空洞,实践出真知,某天如果你真的要设计一个逻辑复杂的程序,
我保证你会说:哇!状态机真的很好用哎!
(3)程序结构清晰
用状态机写出来的程序的结构是非常清晰的。
程序员最痛苦的事儿莫过于读别人写的代码。如果代码不是很规范,而且手里还没有流程图,读代码会让人晕了又晕,只有顺着程序一遍又一遍的看,很多遍之后才能隐约地明白程序大体的工作过程。有流程图会好一点,但是如果程序比较大,流程图也不会画得多详细,很多细节上的过程还是要从代码中理解。
相比之下,用状态机写的程序要好很多,拿一张标准的UML
状态转换图,再配上一些简明的文字说明,程序中的各个要素一览无余。程序中有哪些状态,会发生哪些事件,状态机如何响应,响应之后跳转到哪个状态,这些都十分明朗,甚至许多动作细节都能从状态转换图中找到。可以毫不夸张的说,有了UML
状态转换图,程序流程图写都不用写。
二、编程人工智能小程序
随着科技的不断进步和发展,编程与人工智能已经成为当今数字时代的热门话题。在移动互联网的时代,小程序的兴起更是为编程和人工智能带来了全新的发展机遇。
编程的重要性
编程作为一种技能,不仅可以让人们更好地理解计算机的工作原理,更重要的是可以让人们通过代码创造出令人惊艳的应用程序和软件,为社会发展带来新的可能性。随着信息技术的普及和深入,学习编程已经成为当今社会中一个非常重要的技能。
人工智能的发展趋势
当我们谈到人工智能时,不得不提的是其快速发展的势头。从机器学习到深度学习,人工智能技术正日益成熟和普及。人工智能的应用已经渗透到各行各业,为生产生活带来了诸多便利。
小程序在编程和人工智能中的应用
小程序作为一种轻量级应用程序,集成了编程与人工智能技术,为用户提供简洁、便捷的服务体验。通过小程序,用户可以享受到个性化智能推荐、语音识别、人脸识别等功能,为用户提供更高效的服务。
未来展望
在不久的将来,编程、人工智能和小程序将更加紧密地结合在一起,成为数字时代的主要趋势。随着技术的日益发展,我们可以期待看到更多智能化、个性化的小程序问世,为用户带来更便捷、智能的生活体验。
三、儿童编程人工智能机器人比赛有必要参加吗?
是有必要的。
孩子学习机器人编程不仅可以获取知识、提升能力,同时还能通过专业的比赛,站在更高的舞台和高手切磋,提升自信心。
四、如何快速入门人工智能编程?人工智能编程基础详解
人工智能编程基础详解
人工智能(AI)作为当今世界最热门的科技领域之一,引发了无数人的兴趣。如果你也想学习人工智能编程,那么本文将为你详细介绍人工智能编程的基础知识,帮助你快速入门。
什么是人工智能编程?
人工智能编程指的是利用计算机编程语言和技术,设计和开发能够模拟人类智能行为的程序和系统的过程。这些程序和系统可以自主地学习、推理、规划、理解语言等,是实现人工智能的基础。
入门人工智能编程的基础知识
要学习人工智能编程,你需要具备以下基础知识:
- 1. 编程语言:掌握至少一门编程语言,如Python、Java、C++等。Python在人工智能领域应用广泛,是入门人工智能编程的绝佳选择。
- 2. 数据结构与算法:熟悉常用的数据结构和算法,包括数组、链表、栈、队列、排序算法、搜索算法等。
- 3. 数据分析和处理:掌握数据分析和处理的基本方法,对数据进行清洗、转换和可视化。
- 4. 机器学习基础:了解机器学习的基本概念,包括监督学习、无监督学习、强化学习等。
学习方法和路径
在掌握了上述基础知识之后,你可以按照以下路径系统地学习人工智能编程:
- 1. 学习Python语言基础,包括语法、数据类型、函数等。
- 2. 进行数据结构与算法的学习和实践,掌握常用的数据结构和算法。
- 3. 学习机器学习的基本理论和算法,包括线性回归、逻辑回归、决策树、支持向量机等。
- 4. 深入学习神经网络和深度学习,掌握梯度下降、反向传播等核心概念。
- 5. 实践项目:通过完成一些小型的人工智能项目,如情感分析、图像识别等,巩固所学知识。
学习资源推荐
在学习人工智能编程的过程中,以下学习资源可能对你有所帮助:
- 1. 网上教程:有众多优质的网上教程,例如Coursera、Udacity、网易云课堂等,提供Python、机器学习等课程。
- 2. 书籍推荐:《Python编程从入门到实践》、《统计学习方法》、《深度学习》等。
- 3. 开源项目:GitHub上有许多开源的人工智能项目,可以参与其中学习、贡献代码。
通过本文的介绍,相信你对人工智能编程有了更清晰的认识。希望你能通过系统的学习和实践,快速掌握人工智能编程的基础知识,开启人工智能编程之旅。
感谢你看完本文,希望这些信息对你有所帮助!
五、人工智能编程软件?
yanshee安卓最新版是非常好用的机器人编程软件
支持在手机上控制机器人,可以进行简单的编程,让机器人来执行你的指令和动作,享受编程开发的乐趣,还可以锻炼逻辑思维能力。
yanshee是优必选教育课程体系中面向高等教育课程的开源人形机器人平台。您可以通过使用yanshee app与yanshee机器人进行连接,对yanshee机器人进行机器人遥控,动作回读编程,以及blockly图形化编程,不但可以简单快速地体验与yanshee互动的乐趣,还可以在图形化编程娱乐中了解到python代码的原理,激发您深入学习yanshee机器人的高级编程和人工智能开发的激情和动力。
六、人工智能编程?
你的这个想法,我们正做:计算机自解释自编程技术。这是我们人工智能项目的一部分。学习人工智能,大数据的基础必须有,另外多看一些人工智能理论的书,还有相关的论文。多去理解别人是怎么思考怎么实践的。
七、ar编程和人工智能编程的区别?
AR编程(增强现实编程)和人工智能(AI)编程是两种不同的编程领域,以下是它们之间的一些区别:
1. 定义和应用:
- AR编程:AR编程是指开发应用程序和技术,通过计算机视觉和传感器技术将虚拟元素与现实世界进行融合,实现对真实世界的增强。AR编程主要用于在手机、平板电脑和其他AR设备上创建具有增强现实体验的应用程序和游戏。
- 人工智能编程:人工智能编程是指开发和训练计算机程序,使其能够模拟人类智能和具备学习、推理和决策能力。人工智能编程涉及机器学习、深度学习、自然语言处理、图像识别等领域的算法和技术,用于创建智能系统和应用程序。
2. 技术和方法:
- AR编程:AR编程通常使用计算机视觉、图像识别、动作追踪、传感器等技术,通过跟踪和分析现实世界的图像和动作,将虚拟元素与现实环境进行融合。AR编程需要掌握如OpenGL、Unity等工具和技术。
- 人工智能编程:人工智能编程涉及广泛的技术和方法,包括机器学习、深度学习、神经网络、自然语言处理、专家系统等。人工智能编程需要掌握编程语言(如Python、Java)和相应的AI框架(如TensorFlow、PyTorch)。
3. 应用领域:
- AR编程:AR编程的应用领域包括互动娱乐、虚拟试衣、教育、建筑设计、医疗等领域。AR技术可以为用户创造沉浸式和交互性的增强现实体验。
- 人工智能编程:人工智能编程的应用领域非常广泛,包括自动驾驶、语音识别、智能助理、金融预测、医疗诊断等。人工智能技术可以帮助人们处理和分析复杂的数据,并做出智能的推理和决策。
需要注意的是,AR编程和人工智能编程并不是相互排斥的,它们可以结合使用。例如,可以使用人工智能算法来实现AR应用中的对象识别和交互。同时,也有可能在人工智能应用中使用AR界面提供更直观和交互性的体验。
八、人工智能属于编程么?
人工智能不属于编程的但需要由编程来实现。
人工智能编程语言是一类适应于人工智能和知识工程领域的、具有符号处理和逻辑推理能力的计算机程序设计语言。能够用它来编写程序求解非数值计算、知识处理、推理、规划、决策等具有智能的各种复杂问题。
九、人工智能怎么设计编程?
使用矩阵的方式编写人工智能框架、使用四种性能优化矩阵编写人工智能框架、人工智能及感知元解密、神经网络结构及Sigmoid函数、用神经网络识别手写数字、人工智能框架编写中关于损失度及梯度下降的设计与实现、 MNIST数字识别、从矩阵视角剖析神经网络的运行过程
十、什么是人工智能编程?
就是人工智能语言编程,人工智能编程语言是一类适应于人工智能和知识工程领域的、具有符号处理和逻辑推理能力的计算机程序设计语言。能够用它来编写程序求解非数值计算、知识处理、推理、规划、决策等具有智能的各种复杂问题。