PX4分析系列之添加北醒TOF传感器(使用UART)

2023-05-16

PX4分析系列之添加北醒TOF传感器(使用UART)

提示:一个飞行器爱好者,才疏学浅。通过自己学习PX4源码的过程,进行分析和记录。欢迎各路大神讨论,并指正文中错误,请轻拍。


文章目录

    • PX4分析系列之添加北醒TOF传感器(使用UART)
  • 前言
  • 一、如何自定义uORB消息,创建TOF数据结构
  • 二、连接北醒TOF传感器并通过串口获取数据
  • 总结


前言

提示:大致内容分为2个部分,其中第一部分是介绍如果添加自己的消息oURB。第二部分是如何实现连接北醒TOF传感器。

提示:以下是本篇文章正文内容,下面案例可供参考

一、如何自定义uORB消息,创建TOF数据结构

这部分网上的例子非常多。我就正常操作一下。并实现一个简单的订阅发布实例。
1.在消息目录下创建自己的tof信息。

/px4_v1.6.0/Firmware/msg/test_tof.msg

uint32 tof_distance
uint32 tof_phase
uint32 tof_amp
uint16 tof_mode

2.在对应的msg文件目录下将创建的消息加入到CMakeLists.txt。

/px4_v1.6.0/Firmware/msg/CMakeLists.txt

subsystem_info.msg
system_power.msg
task_stack_info.msg
tecs_status.msg
telemetry_status.msg
test_motor.msg
test_tof.msg /* 添加到了这里 */
time_offset.msg
transponder_report.msg
uavcan_parameter_request.msg
uavcan_parameter_value.msg

3.进行编译生成TOPICS头文件

make px4fmu-v2-default
px4_v1.6.0/Firmware/build_px4fmu-v2_default/src/modules/uORB/topics/test_tof.h

#pragma once
#include <stdint.h>
#ifdef __cplusplus
#include <cstring>
#else
#include <string.h>
#endif

#include <uORB/uORB.h>
#ifndef __cplusplus
#endif
#ifdef __cplusplus
struct __EXPORT test_tof_s {
#else
struct test_tof_s {
#endif
	uint64_t timestamp; // required for logger
	uint32_t tof_distance;
	uint32_t tof_phase;
	uint32_t tof_amp;
	uint16_t tof_mode;
	uint8_t _padding0[2]; // required for logger
#ifdef __cplusplus
#endif
};
/* register this as object request broker structure */
ORB_DECLARE(test_tof);

生成了test_tof_s 数据结构和TOPICS ID,test_tof。

4.修改一个简单的发布订阅实例来测试一下。当前使用的是虚假数据,之后在本文第二部分真实的连接TOF传感器数据。

px4_v1.6.0/Firmware/src/modules/tof/px4_distance_tof.c

/****************************************************************************
/**
 * @file px4_simple_app.c
 * Minimal application example for PX4 autopilot
 *
 * @author Example User <mail@example.com>
 */

#include <px4_config.h>
#include <px4_tasks.h>
#include <px4_posix.h>
#include <unistd.h>
#include <stdio.h>
#include <poll.h>
#include <string.h>

/* 添加要是用的topics , test_tof*/
#include <uORB/uORB.h>
#include <uORB/topics/test_tof.h>

__EXPORT int px4_tof_app_main(int argc, char *argv[]);

int px4_tof_app_main(int argc, char *argv[])
{
	PX4_INFO("Init Tof !!!");

	/* 定义两个test_tof_s 数据结构体,tof用于发布数据,tof_copy用于订阅后复制数据 */
	struct test_tof_s tof;
    struct test_tof_s tof_copy;
	memset(&tof, 0, sizeof(tof));
   / * 公告一个消息,目的是发布这个消息 */
	orb_advert_t tof_pub = orb_advertise(ORB_ID(test_tof), &tof);
    /* 对数据进行虚假赋值*/
    tof.tof_amp = 100;
    tof.tof_distance = 200; 
    tof.tof_phase = 300;
   
   /*发送数据*/
    orb_publish(ORB_ID(test_tof),tof_pub,&tof);

   	/* subscribe to sensor_combined topic(订阅一个消息ID) */
	int sensor_tof_fd = orb_subscribe(ORB_ID(test_tof));
	/* limit the update rate to 5 Hz */
   //设置sensor_combined消息的订阅时间间隔200毫秒一次
	orb_set_interval(sensor_tof_fd, 200);
   /* 将数据copy到新的结构体中进行验证*/
    orb_copy(ORB_ID(test_tof),sensor_tof_fd,&tof_copy); 
  /* 打印数据进行验证*/
    PX4_INFO("[px4_tof] amp %d, distance %d ,phase %d\r\n", tof_copy.tof_amp,tof_copy.tof_distance,tof_copy.tof_phase);
    
	PX4_INFO("exiting");

	return 0;
}

5.将编写的文件加入总的CMakeList。让它可以被编译。

px4_v1.6.0/Firmware/cmake/configs/nuttx_px4fmu-v2_default.cmake

modules/sensors
modules/tof

之后编译并下载

make px4fmu-v2_default
make px4fmu-v2_default upload

6.打开QGC的NSH控制台输入px4_tof_app
在这里插入图片描述
看到输出了对应的虚假数据,简单的测试完毕。

二、连接北醒TOF传感器并通过串口获取数据

1.查看原理图确定使用的串口。
在这里插入图片描述

  • TELEM1 : /dev/ttyS1
  • TELEM2 : /dev/ttyS2
  • GPS : /dev/ttyS3
  • NSH : /dev/ttyS5
  • SERIAL4: /dev/ttyS6
  • N/A : /dev/ttyS4
  • IO DEBUG (RX only):/dev/ttyS0
  • 根据rcS端口定义所以使用 px4_tof_uart start /dev/ttyS6 ---- USART8 115200 */
    因为北醒TOF使用的波特率为115200,所以需要对串口8,连接外设的SERIAL4波特率进行修改。
    在这里插入图片描述

px4_v1.6.0/Firmware/nuttx-configs/px4fmu-v2/nsh/defconfig

# UART8 Configuration
#
CONFIG_UART8_RXBUFSIZE=300
CONFIG_UART8_TXBUFSIZE=300
CONFIG_UART8_BAUD=115200 /* 修改波特率为115200 */
CONFIG_UART8_BITS=8
CONFIG_UART8_PARITY=0
CONFIG_UART8_2STOP=0
# CONFIG_UART8_IFLOWCONTROL is not set
# CONFIG_UART8_OFLOWCONTROL is not set
# CONFIG_UART8_DMA is not set
# CONFIG_PSEUDOTERM is not set
CONFIG_USBDEV=y

2.编写对应的实现文件

Firmware/src/modules/opt3101/opt3101.c

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <stdbool.h>
#include <errno.h>
#include <drivers/drv_hrt.h>
#include <string.h>
#include <systemlib/err.h>
#include <systemlib/systemlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <uORB/topics/test_tof.h>
#include <px4_tasks.h>
#include <poll.h>
#include <px4_posix.h>

static bool thread_should_exit = false; /*Ddemon exit flag*///定义查看进程存在标志变量
static bool thread_running = false;  /*Daemon status flag*///定义查看进程运行标志变量
static int  px4_tof_task;//定义进程变量

__EXPORT int px4_tof_uart_main(int argc, char *argv[]);
 int px4_tof_uart_thread_main(int argc, char *argv[]);

static int tof_uart_init(const char * uart_name);//串口初始化函数,形参为串口路径
static int set_uart_baudrate(const int fd, unsigned int baud);//设置串口波特率函数
static void usage(const char *reason);//进程提示函数

int set_uart_baudrate(const int fd, unsigned int baud)
{
    int baudrate;

    switch (baud) {
        case 9600:   baudrate = B9600;   break;
        case 19200:  baudrate = B19200;  break;
        case 38400:  baudrate = B38400;  break;
        case 57600:  baudrate = B57600;  break;
        case 115200: baudrate = B115200; break;
        default:
            warnx("ERR: baudrate: %d\n", baudrate);
            return -EINVAL;
    }
    //实例化termios结构体,命名为uart_config
    struct termios uart_config;
 
    int termios_state;
    /* fill the struct for the new configuration */
    tcgetattr(fd, &uart_config);
    /* clear ONLCR flag (which appends a CR for every LF) */
    uart_config.c_oflag &= ~ONLCR;
    /* no parity, one stop bit */
    uart_config.c_cflag &= ~(CSTOPB | PARENB);
    /* set baud rate */
    if ((termios_state = cfsetispeed(&uart_config, baudrate)) < 0) {
        warnx("ERR: %d (cfsetispeed)\n", termios_state);
        return false;
    }
 
    if ((termios_state = cfsetospeed(&uart_config, baudrate)) < 0) {
        warnx("ERR: %d (cfsetospeed)\n", termios_state);
        return false;
    }
    if ((termios_state = tcsetattr(fd, TCSANOW, &uart_config)) < 0) {
        warnx("ERR: %d (tcsetattr)\n", termios_state);
        return false;
    }
 
    return true;
}
 
static int tof_uart_init(const char * uart_name)
{
    int serial_fd = open(uart_name, O_RDWR | O_NOCTTY| O_NONBLOCK);

    if (serial_fd < 0) {
        err(1, "failed to open port: %s", uart_name);
        return false;
    }
    return serial_fd;
}

static void usage(const char *reason)
{
    if (reason) {
        fprintf(stderr, "%s\n", reason);
    }
 
    fprintf(stderr, "usage: px4_tof_uart {start|stop|status} [param]\n\n");
    exit(1);
}

int px4_tof_uart_main(int argc, char *argv[])
{
    if (argc < 2) {
        usage("missing command plase enter help");
    }
  
    if (!strcmp(argv[1], "start")) {
        if (thread_running) {
            warnx("px4 tof uart already running\n");
            return 0;
        }

        thread_should_exit = false;

        px4_tof_task = px4_task_spawn_cmd("px4_tof_uart",
                         SCHED_DEFAULT,
                         SCHED_PRIORITY_DEFAULT,
                         1000,
                         px4_tof_uart_thread_main,
                         (argv) ? (char * const *)&argv[2] : (char * const *)NULL);
        return 0;
    }

    if (!strcmp(argv[1], "stop")) {
        thread_should_exit = true;
        return 0;
    }

    if (!strcmp(argv[1], "status")) {
        if (thread_running) {
            warnx("running");
            return 0;
 
        } else {
            warnx("stopped");
            return 1;
        }
 
        return 0;
    }

    usage("unrecognized command");
    return 1;
}
/*
*  TELEM1 : /dev/ttyS1
*  TELEM2 : /dev/ttyS2
*  GPS    : /dev/ttyS3
*  NSH    : /dev/ttyS5
*  SERIAL4: /dev/ttyS6
*  N/A    : /dev/ttyS4
*  IO DEBUG (RX only):/dev/ttyS0
*  rcS px4_tof_uart start /dev/ttyS6  ---- USART8 115200 */
int px4_tof_uart_thread_main(int argc, char *argv[])
{
    if (argc < 2) {
        errx(1, "need a serial port name as argument");
        usage("eg:");
    }

    const char *uart_name = argv[1];
    warnx("opening port %s", uart_name);
    
    /*Uart Init*/
    int tof_uart = tof_uart_init(uart_name);
    if(false == tof_uart)
    {
        PX4_INFO("open_uart_port falied\n");
        return -1;
    }
    if(false == set_uart_baudrate(tof_uart,115200)){//设置串口波特率为57600
        PX4_INFO("set_uart_baudrate is failed\n");
        return -1;
    }
    PX4_INFO("tof uart init is successed\n");
 
    /*进程标志变量*/
    thread_running = true;
 
    /*初始化数据结构体 */
    struct test_tof_s g_tof;
    struct test_tof_s s_tof;

    memset(&g_tof, 0, sizeof(g_tof));
    memset(&s_tof, 0, sizeof(s_tof)); 
    /* 公告主题 */
    orb_advert_t tof_uart_pub = orb_advertise(ORB_ID(test_tof), &g_tof);
 
    /*定义接收话题变量*/
    bool updated = false;
    int tof_uart_fd = orb_subscribe(ORB_ID(test_tof));//订阅input_rc消息
   
    /*定义串口事件阻塞结构体及变量*/
    px4_pollfd_struct_t fds[] = {
    	{ .fd = tof_uart,   .events = POLLIN },
    };
    int error_counter = 0;
 
    while(!thread_should_exit){
        
        /*检查更新*/
    	orb_check(tof_uart_fd, &updated);
 
    	
    	if (updated) {
    		orb_copy(ORB_ID(test_tof), tof_uart_fd, &s_tof);
    		
    		PX4_INFO("orb_copy tof_distance =%d ,tof_amp =%d , tof_mode =%d\n", s_tof.tof_distance, s_tof.tof_amp,s_tof.tof_mode);
    	
    	}
 
    	int poll_ret = poll(fds,1,5);//阻塞等待5ms
    	if (poll_ret == 0)
    	{
    		/* this means none of our providers is giving us data */
    	    PX4_INFO("No receive data for 5ms\n");
    	} else if (poll_ret < 0)
    	{
    	   /* this is seriously bad - should be an emergency */
    	   if (error_counter < 10 || error_counter % 50 == 0)
    	   {
    		   /* use a counter to prevent flooding (and slowing us down) */
    		   PX4_INFO("ERROR return value from poll(): %d\n", poll_ret);
    	   }
    	       error_counter++;
    	}
    	else
    	{
    	   if (fds[0].revents & POLLIN)
    	   {
                uint8_t data;
                uint8_t buffer[10] = {0};
               /*接收服务系统发过来的消息*/
    		   read(tof_uart,&data,1);//读取串口数据
    		   if(data == 0x59)
    		   {//找到帧头0x59
    			   buffer[0] = 0x59;
                   read(tof_uart,&data,1);//读取串口数据
                    if(data == 0x59)
    		        {//找到帧头0x59
                       buffer[1] = 0x59;
                       for(int i = 2;i <8;i++)
    			        {
    				      read(tof_uart,&data,1);//读取后面的数据
    				      buffer[i] = data;
    				      //PX4_INFO("buffer=%d ",buffer[i]);//将消息打印出来

                         
    		            }
                         g_tof.tof_distance = buffer[3]<<8 | buffer[2];
                          g_tof.tof_amp =  buffer[5]<<8 | buffer[4];
                          g_tof.tof_mode = buffer[6];

                          PX4_INFO("orb_publish tof_distance =%d ,tof_amp =%d , tof_mode =%d\n", g_tof.tof_distance,g_tof.tof_amp,g_tof.tof_mode);//将消息打印出来
        	              orb_publish(ORB_ID(test_tof), tof_uart_pub, &g_tof);//发布话题
                    } 
    			   
    		   }

               

        	   
    	   }
    	}
    	
    }
    //如果标志位置flase应该退出进程
    warnx("exiting");
    thread_running = false;
    close(tof_uart);
 
    fflush(stdout);
    return 0;
}

其中北醒的数据协议是
在这里插入图片描述
3.查看实验结果之前,同样需要添加到
px4_v1.6.0/Firmware/cmake/configs/nuttx_px4fmu-v2_default.cmake
在控制台输入 px4_tof_uart start /dev/ttyS6
在这里插入图片描述
可以看到订阅和发送的数据是相同的。 并且解析出了北醒TOF的传感器数据。

总结

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PX4分析系列之添加北醒TOF传感器(使用UART) 的相关文章

  • 无人机PX4学习(2)

    内容源自 xff1a PX4飞控用户手册 链接 xff1a https docs px4 io master en getting started flight controller selection html Flight Contro
  • 无人机PX4学习(3)

    内容源自 xff1a PX4飞控用户手册 链接 xff1a PX4 Flight Modes Overview PX4 User Guide Flight Mode Section RC或GCS上可以切换飞行模式 xff0c 但有些模式有限
  • 两篇论文入坑AIOps异常检测

    AIOps简介 以下部分内容来源于清华大学裴丹教授发表在 中国计算机学会通讯 第13卷第12期的专栏 基于机器学习的智能运维 我们都知道 xff0c 当代社会生活中的大型软硬件系统为了确保能够安全 可靠地运行 xff0c 需要有专业的运维人
  • python代码,两个4*4旋转矩阵之间的位姿变化,相对旋转矩阵

    python代码 xff0c 两个4 4旋转矩阵之间的位姿变化 xff0c 也就是求两个旋转矩阵之间的相对旋转矩阵 import numpy as np def get transform matrix rot mat1 rot mat2
  • crazyS中给firefly飞机添加两个相机

    firefly飞机中原本只有一个相机 xff0c 由于项目需要一个飞机去识别前方两架飞机 xff0c 因此需要增加一个相机 在rotors descriptioin gt urdf gt mav with vi sensor中可以看到此处
  • gitee(码云)和gitHub的区别

    1 gitee与gitHub概念 xff1f Gitee xff08 码云 xff09 是开源中国社区推出的代码托管协作开发平台 xff0c 支持Git和SVN xff0c 提供免费的私有仓库托管 Gitee专为开发者提供稳定 高效 安全的
  • 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    郭孟琦 43 原创作品转载请注明出处 43 Linux内核分析 MOOC课程http mooc study 163 com course USTC 1000029000 首先我选择的系统调用是122号系统调用 uname 简单的介绍一下un
  • 局域网共享文件夹加密(100%成功版本)

    文章目录 一 创建新用户1 右键此电脑选择管理2 点击本地用户和组3 点击用户A 右键空白区域选择创建新用户B 设置用户名和密码C 取消勾选用户下次登录时须更改密码D 勾选用户不能更改密码和密码永不过期 二 创建共享文件夹1 创建一个新文件
  • STM32PWM--基于HAL库(第十三届蓝桥杯嵌入式模拟题)

    文章目录 前言一 CubeMX配置 第十三届模拟题完整版 二 代码相关定义 声明1 函数声明2 宏定义3 变量定义 三 主要函数1 按键扫描2 配置模式3 LCD显示4 频率检测 TIM2输入捕获中断函数 5 PWM输出 TIM3 6 Ma
  • STM32综合-基于HAL库(第十二届蓝桥杯嵌入式省赛)

    文章目录 前言一 CubeMX配置 第十二届省赛完整版 二 代码相关定义 声明1 函数声明2 宏定义3 变量定义 三 主要函数1 按键扫描2 串口接收中断 定时器中断 接收 3 数据解析4 判定数据正误5 数据更新6 结算7 Main函数
  • STM32RTC秒中断--基于HAL库(一文看懂如何配置并使用)

    文章目录 前言一 CubeMX配置 RTC相关 1 使能RTC xff1a 2 进制配置 xff1a 3 初始时间配置 xff1a 4 日期配置 5 闹钟配置 二 代码1 获取时间2 设置闹钟3 闹钟中断函数 三 实验结果总结 前言 相关说
  • STM32LCD--基于HAL库(选中高亮?一文看懂如何玩转高亮显示)

    文章目录 前言一 LCD上的坐标这个坐标是怎么确定的 xff1f X轴Y轴 二 高亮显示类型三 部分真题要求解析四 如何高亮显示选中数据五 代码分析总结 前言 相关说明 xff1a 开发板 xff1a CT117E M4 STM32G431
  • STM32MP157实现串口接收数据上云-MP157串口测试

    文章目录 前言一 需要软件二 minicom配置三 功能选择四 发送数据结语 前言 本篇分享 xff1a 这次将会用几篇博客分享STM32MP157实现串口接收数据上云的一个基础功能 xff0c 实现STM32MP157的串口在接收到数据时
  • STM32MP157实现串口接收数据上云-云数据库存储多设备数据&界面显示实现

    文章目录 前言一 软件安装二 代码改进1 串口接收2 JSON数据解析 三 云产品流转1 作用2 自定义产品功能 amp 添加设备3 创建数据传输规则 四 MYSQL操作五 NODE RED操作1 总体思路2 安装节点3 节点配置4 页面布
  • TX2

    目录 1 Jetson TX2简介2 使用前准备2 1显示2 2控制2 3电源2 4开机2 5系统2 6使用图形界面2 7系统更新 xff0c 安装模块3 对外接口 xff1a 4 软件包配置JetPack4 1使用JetPack 5 TX
  • Linux应用编程-音频应用编程-语音转文字项目

    文章目录 前言Linux语音识别alsa lib简介 xff1a 安装alsa lib库 xff1a libcurl库简介 xff1a 安装libcurl库 xff1a API调用录音相关概念样本长度 xff08 Sample xff09
  • STM32MP157-QT-串口调试助手设计

    文章目录 前言STM32MP157串口调试助手widget uipro文件widget h头文件槽函数成员声明 widget cpp头文件扫描串口并添加到下拉列表串口配置参数获取配置参数 打开 关闭串口读取数据信号读数据函数代码 发送数据清
  • Linux-VIM使用

    文章目录 前言VIM使用1 切换模式2 跳转 1 跳转到指定行 2 跳转到首行 3 跳转到末行 3 自动格式化程序4 大括号对应5 删除 xff08 1 xff09 删除一个单词 xff08 2 xff09 删除光标位置至行尾 xff08
  • JAVA学习记录

    文章目录 前言Pta做题样例做题样例 命名规范 amp 代码风格基本数据类型基本语法类变量类函数关系运算 浮点数 xff08 实型 xff09 数组Java定义数组Java程序遍历整个数组使用FOR EACH循环输出整个数组 循环使用对象字
  • STM32G431-基于HAL库(第十四届蓝桥杯嵌入式模拟题2)

    文章目录 前言一 CubeMX配置 第十四届模拟题2完整版 二 代码相关定义 声明1 函数声明2 宏定义3 变量定义 三 主要函数1 按键扫描2 各参数控制3 LCD显示4 输出信号改变5 串口接收6 Main函数 四 实验结果1 数据页1

随机推荐

  • 线性控制理论纵横

    线性控制理论是系统与控制理论中最为成熟和最为基础的一个组成分支 xff0c 是 现代控制理论的基石 系统与控制理论的其他分支 xff0c 都不同程度地受到线性控制 理论的概念 方法和结果的影响和推动 线性系统理论的研究对象为线性系统 xff
  • 非线性控制理论的发展

    人类认识客观世界和改造世界的历史进程 xff0c 总是由低级到高级 xff0c 由简单到复 杂 xff0c 由表及里的纵深发展过程 在控制领域方面也是一样 xff0c 最先研究的控制系统 都是线性的 例如 xff0c 瓦特蒸汽机调节器 液面
  • 如何正确使用电烙铁

    焊接技术是一项无线电爱好者必须掌握的基本技术 xff0c 需要多多练习才能熟练掌握 1 选用合适的焊锡 xff0c 应选用焊接电子元件用的低熔点焊锡丝 2 助焊剂 xff0c 用25 的松香溶解在75 的酒精 xff08 重量比 xff09
  • 2.13 STM32 串口传输最佳处理方式 FreeRTOS+队列+DMA+IDLE (一)

    当多个串口数据都有大量数据来时 我们如何最佳处理STM32串口通信数据 可以通过FreeRTOS 队列的发送方式 下面将串口DMA发送处理过程 中心思想 1 建立一个大的环形数组 2 发送的数据时 将数据存入到大的数组 3 需要发送数据的长
  • 最流行的开源飞控项目ArduPilot Mega(APM)介绍及发展历史

    ArduPilotMega APM 是市面上最强大的基于惯性导航的开源自驾仪 特性包括 免费开源固件 xff0c 支持飞机 xff08 34 ArduPlane 34 xff09 xff0c 多旋翼 四旋翼 六旋翼 八旋翼等 直升机 xff
  • 解密Apache HAWQ ——功能强大的SQL-on-Hadoop引擎 [作者:常雷]

    作者 xff1a 常雷 博士 xff0c Pivotal中国研发中心研发总监 xff0c HAWQ并行Hadoop SQL引擎创始人 xff0c Pivotal HAWQ团队负责人 xff0c 曾任EMC高级研究员 专注于大数据与云计算领域
  • 超简单的麻将算法

    麻将的算法 提高篇 1 先说说 xff0c 数值的构成 类型字 0 xff1a 东南西北中发白 1 xff0c 2 xff0c 3 xff0c 4 xff0c 5 xff0c 6 xff0c 7 类型万 1 xff1a 1 万 2万3 万
  • Android布局常用

    1 控件隐藏 在XML 文件里设置属性隐藏 android visibility 61 34 invisible 34 android visibility 61 34 visible 34 android visibility 61 34
  • 乘法

    乘法 请仔细把下面的看懂 xff0c 看完后 xff0c 也许你能口算出 1 xff5e 199 之间数的平方 xff0c 或许能口算出多个数的结果 1 乘法的本质 xff1a 乘法的本质就是求和 从上面两张图片中 xff0c 你可以知道
  • Android Activity之间跳转与传值

    一 Activity 跳转与传值 xff0c 主要是通过 Intent 类来连接多个 Activity xff0c 通过 Bundle 类来传递数据 最常见最一般的页面跳转代码 xff0c 很简单 xff0c 如下 xff1a Intent
  • URLEncoder.encode和decode

    http www apkbus com forum php mod 61 viewthread amp tid 61 13853 amp fromuid 61 3402
  • JPCT-AE资料相关

    JPCT AE相关 1 网站参考 xff1a 官方网站 http www jpct net download html API http www jpct net jpct ae doc JPCT AE wiki http www jpct
  • 分享本人VSCode配色(如何修改VSCode各种颜色)

    按下Command 43 Shift 43 P打开命令面板输入settings Open Settings为用户自定义设置Open Default Settings为默认设置 xff08 只读 xff0c 不能修改的 xff09 选中Ope
  • ROS学习番外篇12—Mac M1(Pro+Max)安装ROS1或ROS2须知

    由于苹果换了芯片架构 xff0c 因此裸机安装ROS2或者源码安装ROS1和ROS2变得非常困难 使用Parallels Desktop或者其他虚拟机 xff08 比如UTM xff09 安装Ubuntu然后再在Ubuntu上安装ROS是目
  • stm32cubemx hal学习记录:PWR 低功耗停止模式

    一 低功耗停止模式 1 所有时钟都已经停止 2 进入方式 xff1a 配置PWR CR寄存器的PDDS 43 LPDS位 43 SLEEPDEEP位 43 WFI或WFE命令 3 唤醒方式 xff1a 任意外部中断 4 关闭所有1 8v区域
  • Ubuntu下查看文件、文件夹和磁盘空间的大小

    在实际使用ubuntu时候 xff0c 经常要碰到需要查看文件以及文件夹大小的情况 有时候 xff0c 自己创建压缩文件 xff0c 可以使用 ls hl 查看文件大小 参数 h 表示Human Readable xff0c 使用GB MB
  • stm32cubemx hal学习记录:FreeRTOS任务管理

    一 基本配置 1 配置RCC USART1 时钟84MHz 2 配置SYS xff0c 将Timebase Source修改为除滴答定时器外的其他定时器 xff0c 因为滴答定时器被用于时钟基准 xff0c 可以实现任务切换 Timebas
  • 【面试笔试-c/c++】2013年校园招聘创新工场笔试题(北邮场)

    2013年校园招聘创新工场笔试题 xff08 北邮场 xff09 及一面 题目节后补上 回家了 xff0c 上网不方便 面试题 一面 xff1a 1 手写二叉树的中序非递归遍历 xff0c 一步一步解释代码 xff0c 给个二叉树示范代码流
  • PX4驱动分析之MPU6000

    PX4驱动分析之MPU6000 前言 xff1a 首先分析PX4中MPU6000传感器驱动的注册 xff0c 调用 xff0c 实例的过程 xff0c 先要理解一个事情 就是PX4是使用了一个类Linux操作系统的Nuttx操作系统 也就是
  • PX4分析系列之添加北醒TOF传感器(使用UART)

    PX4分析系列之添加北醒TOF传感器 xff08 使用UART xff09 提示 xff1a 一个飞行器爱好者 xff0c 才疏学浅 通过自己学习PX4源码的过程 xff0c 进行分析和记录 欢迎各路大神讨论 xff0c 并指正文中错误 x