1 func absInt(x int) int {
2 if x < 0 {
3 return -x
4 }
5 return x
6 }
下面会用到此方法, int类型值取绝对值
1 type sp_item struct {
2 x int
3 y int
4 g int
5 h int
6 f int
7 p *sp_item
8 }
9
10 type sp_open []*sp_item
11
12 func (sp sp_open) Len() int {
13 return len(sp)
14 }
15
16 func (sp sp_open) Less(i, j int) bool {
17 return sp[i].f < sp[j].f
18 }
19
20 func (sp sp_open) Swap(i, j int) {
21 sp[i], sp[j] = sp[j], sp[i]
22 }
23
24 func (sp sp_open) exceptFirst() sp_open {
25 var newSps []*sp_item
26 for i := 1; i < len(sp); i++ {
27 newSps = append(newSps, sp[i])
28 }
29 return newSps
30 }
31
32 func (sp sp_open) getIndex(x, y int) int {
33 for i, v := range sp {
34 if v.x == x && v.y == y {
35 return i
36 }
37 }
38 return -1
39 }
这是open列表(带检索的列表)
Len()
Less(i, j int)
Swap(i, j int)
上面三个方法是自定义排序(sp_item.f从小到大排序)
exceptFirst()
复制 sp_open 数组并返回, 不包含第一个 sp_item
getIndex(x, y int)
获取与参数x,y匹配的 sp_item,返回其当前索引或-1
1 type sp_close []int
2
3 func (sp sp_close) contains(x, y int) bool {
4 for k := 0; k < len(sp); k += 2 {
5 if sp[k] == x && sp[k+1] == y {
6 return true
7 }
8 }
9 return false
10 }
这是close列表(不在检索的列表)
contains(x, y int)
sp_close 是否包含参数x,y
1 type sp_dots [8]int
2
3 func (sp sp_dots) getIndex(x, y int) int {
4 for i := 0; i < 8; i += 2 {
5 if sp[i] == x && sp[i+1] == y {
6 return i
7 }
8 }
9 return -1
10 }
11
12 func (sp *sp_dots) put(x, y int) {
13 _x := x - 1
14 x_ := x + 1
15 _y := y - 1
16 y_ := y + 1
17 sp[0], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6], sp[7] = x, _y, _x, y, x_, y, x, y_
18 }
19
20 func (sp *sp_dots) putA(x, y int) {
21 _x := x - 1
22 x_ := x + 1
23 _y := y - 1
24 y_ := y + 1
25 sp[0], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6], sp[7] = _x, _y, x_, _y, _x, y_, x_, y_
26 }
此类型用于获取参数x,y周围的4个点
put(x, y int)
填充 sp_dots, 周围正对面的四个索引点
putA(x, y int)
填充 sp_dots, 周围四个角的索引点
1 type SeekPath struct {
2 BevelAngle bool //是否可以走斜角
3 Timeout time.Duration //超时
4 Junction func(x, y int) bool //过滤
5 }
6
7 // x,y: 开始索引点; x1,y1: 结束索引点
8 func (sp SeekPath) GetPath(x, y, x1, y1 int) []int {
9 sTime := time.Now()
10 eTime := time.Now().Add(sp.Timeout)
11
12 var close sp_close //不在检测的列表
13 var dots, dotsA, dotsB sp_dots //周围的点
14 var isSort bool //如果为 true 则表示 open 列表已改变
15
16 node := &sp_item{
17 x: x, y: y,
18 h: absInt(x1-x)*10 + absInt(y1-y)*10,
19 }
20 open := sp_open{node}
21 node.f = node.h
22 nd := node
23
24 for {
25 if len(open) == 0 || sTime.After(eTime) {
26 break
27 }
28
29 //sp_item.f 从小到大排序
30 if isSort {
31 isSort = false
32 sort.Sort(open)
33 }
34
35 //node 如果是目标就结束
36 node = open[0]
37 if node.x == x1 && node.y == y1 {
38 nd = node
39 break
40 }
41
42 if nd.h > node.h {
43 nd = node
44 }
45
46 open = open.exceptFirst() //从 open 列表删除第一个
47 close = append(close, node.x, node.y) //把 node 加入 close 列表
48
49 var state [4]bool //记录四个面是否合法
50 var dx, dy int
51
52 //四个面
53 dots.put(node.x, node.y)
54 for i := 0; i < 8; i += 2 {
55 dx, dy = dots[i], dots[i+1]
56
57 //在close列表
58 if close.contains(dx, dy) {
59 continue
60 }
61
62 //已在open列表
63 g := open.getIndex(dx, dy)
64 if g != -1 {
65 dot := open[g]
66 g = node.g + 10
67 if g < dot.g {
68 dot.g = g
69 dot.f = g + dot.h
70 dot.p = node
71 isSort = true
72 }
73 state[i/2] = true
74 continue
75 }
76
77 //索引点是否合法
78 if dx < 0 || dy < 0 || !sp.Junction(dx, dy) {
79 close = append(close, node.x, node.y)
80 continue
81 }
82
83 g = node.g + 10
84 h := absInt(x1-dx)*10 + absInt(y1-dy)*10
85 open = append(open, &sp_item{x: dx, y: dy, g: g, h: h, f: g + h, p: node})
86 isSort = true
87 state[i/2] = true
88 }
89
90 //四个角
91 dotsA.putA(node.x, node.y)
92 for i := 0; i < 8; i += 2 {
93 dx, dy = dotsA[i], dotsA[i+1]
94
95 //在close列表
96 if close.contains(dx, dy) {
97 continue
98 }
99
100 //已在open列表
101 g := open.getIndex(dx, dy)
102 if g != -1 {
103 dot := open[g]
104 g = node.g + 14
105 if g < dot.g {
106 dot.g = g
107 dot.f = g + dot.h
108 dot.p = node
109 isSort = true
110 }
111 continue
112 }
113
114 //索引点是否合法
115 if dx < 0 || dy < 0 || !sp.Junction(dx, dy) {
116 close = append(close, node.x, node.y)
117 continue
118 }
119
120 is := true
121 dotsB.put(dx, dy)
122 for i := 0; i < 8; i += 2 {
123 g = dots.getIndex(dotsB[i], dotsB[i+1])
124 if g == -1 {
125 continue
126 }
127 if !state[g/2] {
128 is = false
129 break
130 }
131 }
132 if is {
133 g = node.g + 14
134 h := absInt(x1-dx)*10 + absInt(y1-dy)*10
135 open = append(open, &sp_item{x: dx, y: dy, g: g, h: h, f: g + h, p: node})
136 isSort = true
137 }
138 }
139 }
140
141 var path []int
142 for nd != nil {
143 path = append(path, nd.x, nd.y)
144 nd = nd.p
145 }
146
147 return path
148 }
外部可实例 SeekPath 来获取寻路后的路径
使用示例:
1 // 此结构是用于创建 SeekPath 的参数, 由客户端定义
2 type hh_SeekPath struct {
3 BevelAngle bool `json:"bevelAngle"`
4 Disables []bool `json:"disables"`
5 LenX int `json:"lenX"`
6 LenY int `json:"lenY"`
7 X int `json:"x"`
8 Y int `json:"y"`
9 X1 int `json:"x1"`
10 Y1 int `json:"y1"`
11 }
12
13 func main() {
14 //设置可同时执行的最大CPU数
15 runtime.GOMAXPROCS(runtime.NumCPU())
16 http.Handle("/", http.FileServer(http.Dir("./")))
17
18 http.HandleFunc("/hh", func(w http.ResponseWriter, r *http.Request) {
19 w.Header().Set("Access-Control-Allow-Origin", "*") //*允许所有的域头
20
21 value := r.FormValue("value")
22 param := hh_SeekPath{}
23 err := json.Unmarshal([]byte(value), ¶m)
24 if err != nil {
25 fmt.Println("hh error: ", err)
26 return
27 }
28
29 length := len(param.Disables)
30 lenMax := param.LenX * param.LenY
31 sp := SeekPath{
32 BevelAngle: param.BevelAngle,
33 Timeout: time.Second * 10,
34
35 //此回调如果返回false就把x,y添加到不在检索列表(close)
36 Junction: func(x, y int) bool {
37 //如果x,y超出最大边界就返回false
38 if x >= param.LenX || y >= param.LenY {
39 return false
40 }
41 //Disables[bool] 由客户端随机生成的障碍
42 if length == lenMax {
43 return param.Disables[x*param.LenY+y]
44 }
45 return true
46 },
47 }
48
49 result, _ := json.Marshal(sp.GetPath(param.X, param.Y, param.X1, param.Y1))
50 fmt.Fprint(w, *(*string)(unsafe.Pointer(&result)))
51 })
52
53 fmt.Println("浏览器地址: http://localhost:8080")
54 log.Fatal(http.ListenAndServe(":8080", nil))
55 }
下面是客户端代码(HTML)
1 <!DOCTYPE html>
2 <html lang = "zh-CN">
3
4 <head>
5 <meta charset = "utf-8" />
6 <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no, minimal-ui"> <!-- 不允许用户缩放 -->
7 <style>
8 *{margin:0;padding:0}
9 body{overflow: hidden;}
10 .title{position: absolute;font-size: 12px; color: #000000; background-color: #ffffff;}
11 </style>
12 </head>
13
14 <body>
15
16 <p class="title">go A*寻路测试: 点击第一次为起点, 第二次点击为终点</p>
17
18 <script src = "./js/main.js" type = "module"></script>
19
20 </body>
21
22 </html>
index.html 1 import { CanvasEvent, CanvasImageCustom, CanvasImageDraw, CanvasImageScroll, CanvasImage } from "./lib/ElementUtils.js"
2 import { Ajax, UTILS } from "./lib/Utils.js";
3
4 function main(){
5 const size = 50;
6 const imgA = new CanvasImageCustom().size(size, size).rect(2, 1).fill("#eeeeee").stroke("#cccccc");
7 const imgB = new CanvasImageCustom().size(size, size).rect(2, 1).fill("#333333").stroke("#000000");
8 const imgS = new CanvasImageCustom().size(size, size).rect(2, 1).fill("#00ff00");
9 const imgE = new CanvasImageCustom().size(size, size).rect(2, 1).fill("#ff0000");
10 const imgP = new CanvasImageCustom().size(size, size).rect(size/2, 1).fill("#0000ff");
11 const cid = new CanvasImageDraw({width: innerWidth, height: innerHeight});
12 const cis = new CanvasImageScroll(cid, {scrollVisible: "auto"});
13 const cie = new CanvasEvent(cid);
14
15 //发送给服务器的寻路参数
16 const param = {
17 bevelAngle: true, //是否可走斜角
18 disables: [], //禁用点
19 lenX: Math.floor(innerWidth/size), //索引x轴长度
20 lenY: 100, //索引y轴长度
21 x:0, y:0, //起点
22 x1: 0, y1: 0, //终点
23 }
24 var isEnd = true;
25 const pathsCI = []
26 const ajax = new Ajax({
27 url: "http://localhost:8080/hh",
28 success: v => {
29 v = JSON.parse(v);
30 for(let i = 0; i < v.length; i+=2){
31 const ci = new CanvasImage(imgP).pos(v[i]*size, v[i+1]*size);
32 pathsCI.push(ci);
33 cid.list.push(ci);
34 }
35 cid.redraw();
36 isEnd = true;
37 },
38 });
39
40 //点击的回调方法
41 var isSend = false;
42 function onclick(event){
43 if(isEnd === false) return alert("等待上一次的结果");
44 const ci = event.target;
45 if(isSend === false){
46 isSend = true;
47 param.x = Math.floor(ci.x / size);
48 param.y = Math.floor(ci.y / size);
49 imgS.pos(ci);
50 const c = pathsCI.length;
51 if(c !== 0){
52 cid.list.splice(cid.list.indexOf(pathsCI[0]), c);
53 pathsCI.length = 0;
54 }
55 } else {
56 isEnd = isSend = false;
57 param.x1 = Math.floor(ci.x / size);
58 param.y1 = Math.floor(ci.y / size);
59 ajax.send(`name=hh_SeekPath&value=${JSON.stringify(param)}`);
60 imgE.pos(ci);
61 }
62 cid.redraw();
63 }
64
65 //创建视图和障碍点
66 for(let x = 0, i = 0; x < param.lenX; x++){
67 for(let y = 0, ci; y < param.lenY; y++, i++){
68 if(UTILS.random(0, 1) < 0.3){
69 param.disables[i] = false;
70 ci = cid.list[i] = new CanvasImage(imgB).pos(x * size, y * size);
71 } else {
72 param.disables[i] = true;
73 ci = cid.list[i] = new CanvasImage(imgA).pos(x * size, y * size);
74 ci.addEventListener("click", onclick);
75 }
76 }
77 }
78
79 //end
80 cis.bindScrolls();
81 cid.list.push(imgS, imgE);
82 cid.render();
83 }
84
85 main();
结果图:

源码下载地址: https://www.123pan.com/s/ylTuVv-nwhpH.html
下面的go码是改过的
换了一个名字(SeekPath 换成了 Astar)
去掉了一个属性 .BevelAngle:bool 是否可以走斜角
1 import (
2 "sort"
3 "time"
4 )
5
6 // go A*寻路算法
7
8 func absInt(x int) int {
9 if x < 0 {
10 return -x
11 }
12 return x
13 }
14
15 type sp_item struct {
16 x int
17 y int
18 g int
19 h int
20 f int
21 p *sp_item
22 }
23
24 type sp_open []*sp_item
25
26 func (sp sp_open) Len() int {
27 return len(sp)
28 }
29
30 func (sp sp_open) Less(i, j int) bool {
31 return sp[i].f < sp[j].f
32 }
33
34 func (sp sp_open) Swap(i, j int) {
35 sp[i], sp[j] = sp[j], sp[i]
36 }
37
38 func (sp sp_open) exceptFirst() sp_open {
39 var newSps []*sp_item
40 for i := 1; i < len(sp); i++ {
41 newSps = append(newSps, sp[i])
42 }
43 return newSps
44 }
45
46 func (sp sp_open) get(x, y int) int {
47 for i, v := range sp {
48 if v.x == x && v.y == y {
49 return i
50 }
51 }
52 return -1
53 }
54
55 type sp_close []int
56
57 func (sp sp_close) contains(x, y int) bool {
58 for k := 0; k < len(sp); k += 2 {
59 if sp[k] == x && sp[k+1] == y {
60 return true
61 }
62 }
63 return false
64 }
65
66 type sp_dots [8]int
67
68 func (sp sp_dots) get(x, y int) int {
69 for i := 0; i < 8; i += 2 {
70 if sp[i] == x && sp[i+1] == y {
71 return i
72 }
73 }
74 return -1
75 }
76
77 func (sp *sp_dots) put(x, y int) {
78 _x := x - 1
79 x_ := x + 1
80 _y := y - 1
81 y_ := y + 1
82 sp[0], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6], sp[7] = x, _y, _x, y, x_, y, x, y_
83 }
84
85 func (sp *sp_dots) putA(x, y int) {
86 _x := x - 1
87 x_ := x + 1
88 _y := y - 1
89 y_ := y + 1
90 sp[0], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6], sp[7] = _x, _y, x_, _y, _x, y_, x_, y_
91 }
92
93 // A*寻路
94 type Astar struct {
95 Timeout time.Duration //超时
96 Junction func(x, y int) bool //过滤
97 }
98
99 func (sp Astar) GetPathF(x, y, x1, y1 int) []int {
100 sTime := time.Now()
101 eTime := time.Now().Add(sp.Timeout)
102
103 var close sp_close //不在检测的列表
104 var dots sp_dots //周围的点
105 var isSort bool //如果为 true 则表示 open 列表已改变
106 var dx, dy int
107
108 node := &sp_item{
109 x: x, y: y,
110 h: absInt(x1-x)*10 + absInt(y1-y)*10,
111 }
112
113 node.f = node.h
114 nd := node
115 open := sp_open{node}
116
117 for len(open) != 0 && sTime.Before(eTime) {
118 //sp_item.f 从小到大排序
119 if isSort {
120 isSort = false
121 sort.Sort(open)
122 }
123
124 //node 如果是目标就结束
125 node = open[0]
126 if node.x == x1 && node.y == y1 {
127 nd = node
128 break
129 }
130
131 if nd.h > node.h {
132 nd = node
133 }
134
135 open = open.exceptFirst() //从 open 列表删除第一个
136 close = append(close, node.x, node.y) //把 node 加入 close 列表
137
138 //四个面
139 dots.put(node.x, node.y)
140 for i := 0; i < 8; i += 2 {
141 dx, dy = dots[i], dots[i+1]
142
143 //在close列表
144 if close.contains(dx, dy) {
145 continue
146 }
147
148 //索引点是否合法
149 if dx < 0 || dy < 0 || !sp.Junction(dx, dy) {
150 close = append(close, dx, dy)
151 continue
152 }
153
154 //已在open列表
155 g := open.get(dx, dy)
156 if g != -1 {
157 d := open[g]
158 g = node.g + 10
159 if g < d.g {
160 d.g = g
161 d.f = g + d.h
162 d.p = node
163 isSort = true
164 }
165 } else {
166 g = node.g + 10
167 h := absInt(x1-dx)*10 + absInt(y1-dy)*10
168 open = append(open, &sp_item{x: dx, y: dy, g: g, h: h, f: g + h, p: node})
169 isSort = true
170 }
171 }
172 }
173
174 var path []int
175 for nd != nil {
176 path = append(path, nd.x, nd.y)
177 nd = nd.p
178 }
179
180 return path
181 }
182
183 func (sp Astar) GetPath(x, y, x1, y1 int) []int {
184 sTime := time.Now()
185 eTime := time.Now().Add(sp.Timeout)
186
187 var close sp_close
188 var dots, dotsA, dotsB sp_dots
189 var state [4]bool
190 var isSort bool
191 var dx, dy, i int
192
193 g := absInt(x1-x)*10 + absInt(y1-y)*10
194 node := &sp_item{x: x, y: y, h: g, f: g}
195 nd := node
196 open := sp_open{node}
197
198 for len(open) != 0 && sTime.Before(eTime) {
199 if isSort {
200 isSort = false
201 sort.Sort(open)
202 }
203
204 node = open[0]
205 if node.x == x1 && node.y == y1 {
206 nd = node
207 break
208 }
209
210 if nd.h > node.h {
211 nd = node
212 }
213
214 open = open.exceptFirst()
215 close = append(close, node.x, node.y)
216 dots.put(node.x, node.y)
217 dotsA.putA(node.x, node.y)
218 state[0], state[1], state[2], state[3] = false, false, false, false
219
220 for i = 0; i < 8; i += 2 {
221 dx, dy = dots[i], dots[i+1]
222
223 if close.contains(dx, dy) {
224 continue
225 }
226
227 if dx < 0 || dy < 0 || !sp.Junction(dx, dy) {
228 close = append(close, dx, dy)
229 continue
230 }
231
232 state[i/2] = true
233 g = open.get(dx, dy)
234 if g != -1 {
235 dot := open[g]
236 g = node.g + 10
237 if g < dot.g {
238 dot.g = g
239 dot.f = g + dot.h
240 dot.p = node
241 isSort = true
242 }
243 } else {
244 g = node.g + 10
245 h := absInt(x1-dx)*10 + absInt(y1-dy)*10
246 open = append(open, &sp_item{x: dx, y: dy, g: g, h: h, f: g + h, p: node})
247 isSort = true
248 }
249 }
250
251 B:
252 for i = 0; i < 8; i += 2 {
253 dx, dy = dotsA[i], dotsA[i+1]
254
255 if close.contains(dx, dy) {
256 continue
257 }
258
259 if dx < 0 || dy < 0 || !sp.Junction(dx, dy) {
260 close = append(close, dx, dy)
261 continue
262 }
263
264 dotsB.put(dx, dy)
265 for k := 0; k < 8; k += 2 {
266 g = dots.get(dotsB[k], dotsB[k+1])
267 if g != -1 && !state[g/2] {
268 continue B
269 }
270 }
271
272 g = open.get(dx, dy)
273 if g != -1 {
274 dot := open[g]
275 g = node.g + 14
276 if g < dot.g {
277 dot.g = g
278 dot.f = g + dot.h
279 dot.p = node
280 isSort = true
281 }
282 } else {
283 g = node.g + 14
284 h := absInt(x1-dx)*10 + absInt(y1-dy)*10
285 open = append(open, &sp_item{x: dx, y: dy, g: g, h: h, f: g + h, p: node})
286 isSort = true
287 }
288 }
289 }
290
291 var path []int
292 for nd != nil {
293 path = append(path, nd.x, nd.y)
294 nd = nd.p
295 }
296
297 return path
298 }
完整的go码
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c
TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是
TCP是面向连接的协议,连接的建立和释放是每一次面向连接的通信中必不可少的过程。TCP连接的管理就是使连接的建立和释放都能正常地进行。三次握手TCP连接的建立—三次握手建立TCP连接①若主机A中运行了一个客户进程,当它需要主机B的服务时,就发起TCP连接请求,并在所发送的分段中用SYN=1表示连接请求,并产生一个随机发送序号x,如果连接成功,A将以x作为其发送序号的初始值:seq=x。主机B收到A的连接请求报文,就完成了第一次握手。客户端发送SYN=1表示连接请求客户端发送一个随机发送序号x,如果连接成功,A将以x作为其发送序号的初始值:seq=x②主机B如果同意建立连接,则向主机A发送确认报
VXLAN简介定义RFC定义了VLAN扩展方案VXLAN(VirtualeXtensibleLocalAreaNetwork,虚拟扩展局域网)。VXLAN采用MACinUDP(UserDatagramProtocol)封装方式,是NVO3(NetworkVirtualizationoverLayer3)中的一种网络虚拟化技术。目的随着网络技术的发展,云计算凭借其在系统利用率高、人力/管理成本低、灵活性/可扩展性强等方面表现出的优势,已经成为目前企业IT建设的新趋势。而服务器虚拟化作为云计算的核心技术之一,得到了越来越多的应用。服务器虚拟化技术的广泛部署,极大地增加了数据中心的计算密度;同时,为
目录一、原理部分1、什么是串行通信(1)并行通信与串行通信(2)串行通信的制式(3)串行通信的主要方式 2、配置串口(1)SCON和PCON:串行口1的控制寄存器(2)SBUF:串行口数据缓冲寄存器 (3)AUXR:辅助寄存器编辑(4)ES、PS:与串行口1中断相关的寄存器(5)波特率设置 3、串口框架编写二、程序案例一、原理部分1、什么是串行通信(1)并行通信与串行通信微控制器与外部设备的数据通信,根据连线结构和传送方式的不同,可以分为两种:并行通信和串行通信。并行通信:数据的各位同时发送与接收,每个数据位使用一条导线,这种方式传输快,但是需要多条导线进行信号传输。串行通信:数据一位一
这篇文章,主要介绍如何使用SpringCloud微服务组件从0到1搭建一个微服务工程。目录一、从0到1搭建微服务工程1.1、基础环境说明(1)使用组件(2)微服务依赖1.2、搭建注册中心(1)引入依赖(2)配置文件(3)启动类1.3、搭建配置中心(1)引入依赖(2)配置文件(3)启动类1.4、搭建API网关(1)引入依赖(2)配置文件(3)启动类1.5、搭建服务提供者(1)引入依赖(2)配置文件(3)启动类1.6、搭建服务消费者(1)引入依赖(2)配置文件(3)启动类1.7、运行测试一、从0到1搭建微服务工程1.1、基础环境说明(1)使用组件这里主要是使用的SpringCloudNetflix
目录文章信息写在前面Background&MotivationMethodDCNV2DCNV3模型架构Experiment分类检测文章信息Title:InternImage:ExploringLarge-ScaleVisionFoundationModelswithDeformableConvolutionsPaperLink:https://arxiv.org/abs/2211.05778CodeLink:https://github.com/OpenGVLab/InternImage写在前面拿到文章之后先看了一眼在ImageNet1k上的结果,确实很高,超越了同等大小下的VAN、RepLK
文章目录前言一、注册小程序二、项目创建三、运行项目四、其他配置最后前言此次项目开发使用uniapp和uview进行开发,需要用到的开发工具为HBuilderX和微信开发者工具,具体的安装方式见官网,小程序注册见微信公众平台。一、注册小程序注册在微信公众平台注册小程序,按照提示注册完后会发配一个appid和密钥,需要复制保存好。完善信息设置=>基本设置,填写小程序基本信息,包括名称、头像、介绍及服务范围等。第三方设置根据开发需求添加插件授权。成员管理管理=>成员管理,点击编辑或下拉选择添加成员,输入微信号添加新的项目成员,只有成员可以进行真机测试。体验成员可以使用发布的体验版。开发设置开发=>开
ESP32学习笔记(七)复位和时钟目录:ESP32学习笔记(一)芯片型号介绍ESP32学习笔记(二)开发环境搭建VSCode+platformioESP32学习笔记(三)硬件资源介绍ESP32学习笔记(四)串口通信ESP32学习笔记(五)外部中断ESP32学习笔记(六)定时器ESP32学习笔记(七)复位和时钟1.复位2.系统时钟2.1时钟树2.2时钟源从时钟树可以看出时钟源共七种ESP32的时钟源分别来自外部晶振、内部PLL或振荡电路具体地说,这些时钟源为:2.2.1快速时钟PLL_CLK320MHz或480MHz内部PLL时钟XTL_CLK2~40MHz外部晶振时钟,模组板载的是40MHz晶