RoboMaster电机驱动

2023-05-16

1.硬件

1.1 电机

RM有很多不同型号的电机,不同型号的电机有它不同的用途,但是以用途分类的话主要是分成两种电机:

  1. 用来精准控制位置的电机,在RM中的主要是云台电机。

    RM官网上的云台电机只有一款:GM6020。云台电机的特点就是:运动无噪音、大力矩、高精度。尤其是大力矩高精度,这点对于云台电机很重要。还有一点与其他的电机不太一样的是,云台电机一般是电压驱动。这一点在使用的细节上也有体现

    云台电机是利用压电材料输入电压会产生变形的特性,使其能产生超声波频率的机械振动,再透过摩擦驱动的机构设计,让云台电机如同电磁马达一般,可做旋转运动或直线式移动。

  1. 用来提供动力的电机

    提供动力的电机现在在RM有两种,一种是M3508减速直流电机,一种是M2006 P36直流无刷减速电机。前者扭矩更大,一般被用作轮子的驱动;后者往往用来做播弹系统的动力来源。

我们的主控不能直接去控制电机,而需要中间加一个电调来作为中间人,收到主控的命令后通知电机进行相关的运动,并且通过can总线获取电机的温度、转子位置和转子转速等信息返送给主控。GM6020云台电机内部自带电调

1.2 主控

目前主要使用到的主控是C板和A板。因为C板自带陀螺仪,被用来控制机器人的云台部分。A板用来控制机器人底盘的运动。

2.软件

软件部分主要就是如何通过Cubemx配置,并且在clion中编写Cubemx不能配置的部分(我想说的是用来接收can通讯信息的接收过滤器)、电机的具题控制参数与逻辑。

2.1 Cubemx配置

2.1.1 芯片选型

通过查看主控板的手册,可以知道主控芯片用的是STM32F427IIH6芯片,因此在Cubemx中选择对应的芯片型号,进入配置。

2.1.2 时钟配置

2.1.2.1先开启时钟

在RCC栏中使能外部高速时钟HSE,使用的信号选择晶振信号。

2.1.2.2 配置时钟树

​ f4系列的时钟树相较于f1系列明显长的更大,更复杂,先粗浅的配置它一下,之后有对时钟特殊的要求的时候再进行仔细的配置和了解。之前的f1的外部晶振时钟是8MHZ的因此左侧标红的区域(Input frequency)选择的是8。但是这个开发板的外部晶振是12MHZ的,因此就相应的选择成12。选择HSE通道,然后将系统时钟调到最大(180Mhz),直接在HCLK处填入180,Cube就会自动帮你配置。

2.1.3 debug配置

Pinout & Configuration中的System Core配置SYS的时候将Debug选择成Serial Wire

如果没有勾选Serial Wire 程序只能下载一遍,然后需要将BOOT1、BOOT2引脚电平通过跳线帽均置为高电平并复位开发板,然后再尝试将正确的程序重新下载,下载完成后,需要将BOOT引脚都恢复为低电平。

2.1.4 can外设配置

2.1.4.1 can外设开启

在Connectivity选项栏中选中要开启的CAN外设。点击Activated开启。

2.1.4.2 引脚选择

然后去查看开发板的原理图,找到相应的外设的引脚,看看和他默认的是否相同。有的一些外设对应的引脚和Cube里默认的引脚是不一样的,这一点很重要,要确认一下。

RM开发板手册资料:RoboMaster开发板套件

如果引脚不对应那么根据原理图中的引脚,在Cubemx中找到对应的引脚选择上对应的功能

2.1.4.3 开启接收中断

电调会通过can总线发送电机信息给主控,can总线收到信息后进入接收中断,因此要开启can的接收中断。

2.1.4.4 配置波特率

由于CAN属于异步通讯,没有时钟信号线,连接在同一个总线网络中的各个节点会像串口异步通讯那样,节点间使用约定好的波特率进行通讯。

can外设的通信速率最大是1MHZ,因此我们需要调节CAN外设分频系数、BS1段长度、BS2段长度来把波特率调到1Mhz。

经过前人的经验总结:分别设置成3 、10、3的时候正好可以成1Mhz,但是不能直接按顺序设置,因为如果预分频系数设置成3,BS1段是不允许设置成10的,因此要先将预分频系数调大,然后调BS1和BS2段最后再将分频设置成3.

波特率计算知识点:

2.1.5 生成文件

2.1.5.1 生成成对的.c/.h文件

2.1.5.2 配置使用clion IDE 打开

之后生成代码即可

在生成好文件后选择打开文件夹(Open Folder),而不是直接打开工程(Open Project),否则它会不知道用什么打开

之后返回打开的文件夹的上一层,然后右键用clion打开文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yHjmWgli-1651241400621)(https://www.houenup.com/wp-content/uploads/2022/03/image-2022030117300085-300x86.png)]

2.2 代码部分配置

2.2.1 接收过滤器配置

2.2.1.1 配置代码
CAN_FilterTypeDef can_filter_st;   					//实例化一个can接收过滤器
can_filter_st.FilterBank = 0;						//选择过滤器0
can_filter_st.FilterActivation = ENABLE;			//开启该过滤器
can_filter_st.FilterMode = CAN_FILTERMODE_IDMASK;	//筛选器模式是ID掩码模式
can_filter_st.FilterScale = CAN_FILTERSCALE_32BIT;	//筛选器位宽
can_filter_st.FilterIdHigh = 0x0000;				
can_filter_st.FilterIdLow = 0x0000;
can_filter_st.FilterMaskIdHigh = 0x0000;
can_filter_st.FilterMaskIdLow = 0x0000;
can_filter_st.FilterFIFOAssignment = CAN_RX_FIFO0	//把接收到的报文放入到FIFO0中
HAL_CAN_ConfigFilter(&hcan1, &can_filter_st);		//把过滤器配置配置给can1外设						
2.2.1.2 相关知识点
接收中断:

一旦往FIFO存入一个报文,硬件就会更新FMP[1:0]位,并且如果CAN_IER寄存器的FMPIE位为’1’,那么就会产生一个中断请求。
当FIFO 变 满 时( 即 第3 个 报 文 被 存 入) , CAN_RFR 寄 存 器 的FULL 位 就 被 置’1’ , 并 且 如 果CAN_IER寄存器的FFIE位为’1’,那么就会产生一个满中断请求。
在溢出的情况下, FOVR位被置’1’,并且如果CAN_IER寄存器的FOVIE位为’1’,那么就会产生一个溢出中断请求。

接收FIFO:

​ CAN外设一共有2个接收FIFO,每个FIFO中有3个邮箱,即最多可以缓存6个接收到的报文。当接收到报文时,FIFO的报文计数器会自增,而STM32内部读取FIFO数据后,报文计数器会自减,通过状态寄存器可获知报文计数器的值

STM32的 CAN 有两个 FIFO,分别是 FIFO0和 FIFO1。为了便于区分,下面 FIFO0写作FIFO_0,FIFO1写作 FIFO_1。
每组过滤器组必须关联且只能关联一个 FIFO。复位默认都关联到 FIFO_0。所谓“关联”是指假如收到的报文从某个过滤器通过了,那么该报文会被存到该过滤器相连的 FIFO。从另一方面来说,每个 FIFO 都关联了一串的过滤器组,两个 FIFO 刚好瓜分了所有的过滤器组。每当收到一个报文,CAN 就将这个报文先与 FIFO_0关联的过滤器比较,如果被匹配,就将此报文放入 FIFO_0中。如果不匹配, 再将报文与 FIFO_1关联的过滤器比较, 如果被匹配, 该报文就放入 FIFO_1中。如果还是不匹配,此报文就被丢弃。
每个 FIFO 的所有过滤器都是并联的,只要通过了其中任何一个过滤器,该报文就有效。如果一个报文既符合 FIFO_0的规定,又符合 FIFO_1的规定,显然,根据操作顺序,它只会放到 FIFO_0中。
每个 FIFO 中只有激活了的过滤器才起作用,换句话说,如果一个 FIFO 有20个过滤器,但是只激话了5个,那么比较报文时,只拿这5个过滤器作比较。一般要用到某个过滤器时,在初始化阶段就直接将它激活。需要注意的是,每个 FIFO 必须至少激活一个过滤器,它才有可能收到报文。如果一个过滤器都没有激活,那么是所有报文都报废的。一般的,如果不想用复杂的过滤功能, FIFO 可以只激活一组过滤器组,且将它设置成 32位的屏蔽位模式,两个标准值寄存器(FxR1,FxR2)都设置成0。这样所有报文均能通过。(STM32提供的例程里就是这么做的! )

验收筛选器:

​ 在CAN协议中,消息的标识符与节点地址无关,但与消息内容有关。因此,发送节点将报文广播给所有接收器时,接收节点会根据报文标识符的值来确定软件是否需要该消息,为了简化软件的工作,STM32的CAN外设接收报文前会先使用验收筛选器检查,只接收需要的报文到FIFO中,筛选器工作的时候,可以调整筛选ID的长度及过滤模式。根据过滤方法分为标识符列表模式掩码模式

筛选器模式:
  1. 标志符列表模式:

​ 它把要接收的报文的ID列成一个表,要求报文ID与列表中的某一个标识符完全相同才可以接收,可以理解为白名单

标识符列表模式下,CAN_FxR1 和 CAN_FxR2中都是要匹配的标识符,收到的帧的标识符必须与其中一个吻合才能通过过滤

  1. 掩码模式:

​ 它把可接收报文ID的某几位作为列表,这几位称为掩码,可以把它理解成关键字搜索,只要掩码(关键字相同),就符合要求,报文就会被保存到接收FIFO。

掩码模式下,那个填写掩码的寄存器与想要筛出来的ID一位一位地对应 ,那个想要筛出来的ID寄存器就填写对应位想要的数,然后掩码寄存器对应的位填写是否需要一致(如果想要该位与需要该位筛选出来的ID的数值相同,则需要在该位的掩码上写上1,不需要相同则写上0即可)

理解:标识符列表模式是为了过滤出一个标识符,而屏蔽位模式因为屏蔽了某些位所以可以过滤出一组标识符,对于不需要用筛选器组的应处以禁用状态

一般我们用的都是普通型的,所以在本文中可以说 STM32有14组过滤器组。根据配置,每1组过滤器组可以有1个,2个或4个过滤器。这些过滤器相当于关卡,每当收到一条报文时,CAN 要先将收到的报文从这些过滤器上”过”一下,能通过的报文是有效报文,收进 FIFO,不能通过的是无效报文(不是发给”我”的报文),直接丢弃。通过对两个可配置寄存器值得改变可以选择过滤器的数量。在一组过滤器中,整组的过滤器都使用同一种工作模式

1.在32位的屏蔽位模式下:
有1个过滤器。
FxR2用于指定需要关心哪些位,FxR1用于指定这些位的标准值。
2.在32位的列表模式下:
有两个过滤器。
FxR1指定过滤器0的标准值,收到报文的标识符只有跟 FxR1完全相同时,才算通过。
FxR2指定过滤器1的标准值。
3.在16位的屏蔽位模式下:
有2个过滤器。
FxR1配置过滤器0,其中,[31-16]位指定要关心的位,[15-0]位指定这些位的标准值。
FxR2配置过滤器1,其中,[31-16]位指定要关心的位,[15-0]位指定这些位的标准值。
4.在16位的列表模式下:
有4个过滤器。
FxR1的[15-0]位配置过滤器0,FxR1的[31-16]位配置过滤器1。
FxR2的[15-0]位配置过滤器2,FxR2的[31-16]位配置过滤器3。

2.2.2 开启对应can外设

HAL_CAN_Start(&hcan1);		//开启can1

2.2.3 开启接收中断

 HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
 CAN_IT_RX_FIFO0_MSG_PENDING:当FIFO0中有消息的时候进入中断。

可以看出CAN_IT_RX_FIFO0_MSG_PENDING中的FIFO0和我们配置过滤器时的报文存放位置式相对应的。

can_filter_st.FilterFIFOAssignment = CAN_RX_FIFO0 //把接收到的报文放入到FIFO0中

2.2.4 在接收中断中获取并解析数据

2.2.4.1 重定义can接收中断回调函数

can中断回调函数是弱定义,我们在任意一个地方重写中断回调函数,并在其中进行对数据的操作。

can接收的中断回调函数是

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
2.2.4.2 接收报文结构体
typedef struct
{
  uint32_t StdId;   			//存储了报文的标准标识符 11位

  uint32_t ExtId;				//存储了报文的扩展标识符 29位

  uint32_t IDE;					//存储了IDE扩展标志     

  uint32_t RTR;     			//存储了RTR远程帧标志

  uint32_t DLC;     			//存储了报文数据段的长度,0-8

  uint32_t Timestamp; 			//时间戳	

  uint32_t FilterMatchIndex; 	

} CAN_RxHeaderTypeDef;
2.2.4.3 接收函数
HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo, CAN_RxHeaderTypeDef *pHeader, uint8_t aData[])
作用:从Rx FIFO收取一个can帧
hcan:CAN句柄指针2
Rx FIFO:从哪个FIFO中取。可填 CAN_RX_FIFO0, CAN_RX_FIFO1
*pHeader:接收报文定义结构体的指针
aData[]:接收数据域的指针

接收函数的作用就是从对应的FIFO中收取一帧can数据,然后把Can数据解剖,然后把对应的部分放在我们事先实例化好的接收结构体中,其中最主要的就是DATA部分。

因为can总线上只要有信号通过过滤器进入fifo那么就会进入接收中断,如果can总线上挂载的数据多了,我们就需要根据他们发过来的报文中的ID来分别他们是谁,并通过判断语句进行对应的操作。

2.2.4.4 解析数据

所谓数据的解析,就是从接收函数填充好的接收结构体中拿出我们需要知道的信息,然后读懂DATA中的数据的意思(包括转子位置、转速等信息)。而填充给结构体的数据是电调发过来的,这一帧数据是怎样存放的,电调自己是有一套报文格式的,我们可以通过这个格式来解析对应的信息。

在这里找到C620电调的使用说明:https://www.robomaster.com/zh-CN/products/components/general/M3508

通过查阅手册,我们了解到如何通过标识符来判断这是哪个电机发来的信息如何在DATA中解析到我们想要的数据

我们可以定义一个结构体,每当我们解析数据的时候,直接把对应的data中的数据解析出来存放到对应的实例化好的结构体中。 解析的过程也可以定义一个函数来处理。

结构体定义:
typedef struct
{
    uint16_t ecd;
    int16_t speed_rpm;
    int16_t given_current;
    uint8_t temperate;
    int16_t last_ecd;
} motor_measure_t;

解析函数:
get_motor_measure(ptr, data)               
{
     (ptr)->last_ecd = (ptr)->ecd;     
     (ptr)->ecd = (uint16_t)((data)[0] << 8 | (data)[1]);            
     (ptr)->speed_rpm = (uint16_t)((data)[2] << 8 | (data)[3]);      
     (ptr)->given_current = (uint16_t)((data)[4] << 8 | (data)[5]);  
     (ptr)->temperate = (data)[6];    
        
 }

2.2.5 接收数据总结与示例

2.2.5.1总结:

接收数据这里写的有点多,这里做一个总结。

首先我们要先启用相应的can总线,这是一定的。

然后在can总线上,因为只有一根总线,而并不是所有的信息我们都要接收(虽然在我们配置的时候配置的是都接受),因此需要配置接收过滤器来过滤掉我们不需要的数据。

如果数据通过了过滤器,进入到了对应的FIFO,那么它就会产生一个中断,因此我们要使能这个接收中断,这样才能在中断产生的时候进入到中断中去,进行下一步的处理。

数据因为进入fifo而呼叫了一个中断,我们进入这个中断的时候就需要用对应的函数来获取这个进入fifo中的数据,然后根据一定的格式来解析它。

在解析的时候为了条例更清晰并且便于我们的操作,我们可以规定一个数据结构体,以及信息解析的一个“方法”。然后在接收中断中我们需要实例化两个结构体。一个结构体是stm32规定的接受数据的结构体,我们获取的帧数据会被解剖填入这个结构体中,其中包括stdid这一项,我们可以通过这一项的数值来判断这帧数据是谁发来的,从而进行对应的操作。 另一个结构体就是我们自己定义的结构体,这个结构体主要是配合我们自己定义的解析数据的方法来使用,将can数据帧中的DATA段数据一项一项地解析出来0。

2.2.5.2中断回调函数示例
#define CAN_CHASSIS_ALL_ID  0x200
#define CAN_3508_M1_ID  0x201
#define CAN_3508_M2_ID 0x202
#define CAN_3508_M3_ID 0x203
#define CAN_3508_M4_ID 0x204

数据结构体定义
typedef struct
{
    uint16_t ecd;
    int16_t speed_rpm;
    int16_t given_current;
    uint8_t temperate;
    int16_t last_ecd;
} motor_measure_t;

数据解析方法定义
#define get_motor_measure(ptr, data)                                    \
    {                                                                   \
        (ptr)->last_ecd = (ptr)->ecd;                                   \
        (ptr)->ecd = (uint16_t)((data)[0] << 8 | (data)[1]);            \
        (ptr)->speed_rpm = (uint16_t)((data)[2] << 8 | (data)[3]);      \
        (ptr)->given_current = (uint16_t)((data)[4] << 8 | (data)[5]);  \
        (ptr)->temperate = (data)[6];                                   \
    }
    
static motor_measure_t motor_chassis[7];  //实例化一个结构体数据,数组中的每一个结构体存放一个对应电机的相关数据,因为整台车上有7个电机因此数组大小为7



void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    CAN_RxHeaderTypeDef rx_header;
    uint8_t rx_data[8];

    HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data);

    switch (rx_header.StdId)
    {
        case CAN_3508_M1_ID:
        case CAN_3508_M2_ID:
        case CAN_3508_M3_ID:
        case CAN_3508_M4_ID:
        {
            static uint8_t i = 0;
            //get motor id
            i = rx_header.StdId - CAN_3508_M1_ID;
            get_motor_measure(&motor_chassis[i], rx_data);
            break;
        }

        default:
        {
            break;
        }
    }
}

2.2.4 can发送配置

can发送有两点:

  1. 配置好报文结构体
  2. 通过函数HAL_CAN_AddTxMessage发送报文
2.2.4.1 发送数据结构体配置
CAN_TxHeaderTypeDef  chassis_tx_message;
chassis_tx_message.StdId = 0x200;				//指定标准标识符

chassis_tx_message.IDE = CAN_ID_STD;			/*要传输的消息的标识符类型
                       							标准帧:CAN_ID_STD
                        						扩展帧:CAN_ID_EXT*/
                        						
	
chassis_tx_message.RTR = CAN_RTR_DATA;			/*要传输的消息的帧类型
                         						数据帧:CAN_RTR_DATA
                        						远程帧:CAN_RTR_REMOTE */

chassis_tx_message.DLC = 0x08;					/*将要传输的帧的长度。
												取值范围为0 ~ 8	*/
2.2.4.2 发送数据
发送数据报文结构

发送数据的结构不是自己随便的定义的,因为我们can发送的信息时让电调接收的,电调接收信息有一个数据帧的格式,我们需要根据这个帧的格式来发送我们的数据,才能控制我们想要控制的东西。

在这里找到C620电调的使用说明:M3508减速电机套装 (robomaster.com)

通过翻阅C620电调的使用说明我们可以看到我们可以通过控制标识符以及在data段中的对应位置填写数值来控制8个不同的电机的电流大小

发送函数
HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox)

1. CAN_HandleTypeDef *hcan: CAN的句柄指针,如果是can1就输入&hcan1, can2 就输入 &hcan2
2. CAN_TxHeaderTypeDef *pHeader:待发送的CAN数据帧信息的结构体指针。包含了CAN的ID,格式等重要信息。
3. uint8_t aData[] : 装载了待发送的数据的数组名称
4. uint32_t *pTxMailbox: 用于存储CAN发送所使用的邮箱号

​ 这个发送邮箱一般没用

2.2.4.3 发送数据总结与示例
2.2.4.3.1 总结

相较于接收数据,发送数据更加的直接一些。我们只需要关注,怎么发出去,把什么发出去这两个问题即可。

怎么发出去? 用函数HAL_CAN_AddTxMessage发出去。

发出去什么?发出去我们组织好的数据。

何谓组织好的数据?首先报文结构要组织好,然后报文内容要组织好。

报文的结构如何组织?stm32给我们规定了结构体 CAN_TxHeaderTypeDef,我们按照结构体的结构配置即可,其中最主要的一个内容是StdId,这一项决定了我们要把数据发给谁。

内容是什么?我们发送数据的主要内容就是给电机传达转速,也就是电流大小,而电流大小要放在DATA中的对应位置,这样电调才能够准确的解析并执行。

2.2.4.3.2示例
static CAN_TxHeaderTypeDef  chassis_tx_message;
static uint8_t              chassis_can_send_data[8];
int16_t motor1,motor2,motor3,motor4;
uint32_t send_mail_box; //发送邮箱一般没什么用 随便是个什么值

motor1=4000;
motor2=4000;
motor3=4000;
motor4=4000;
chassis_can_send_data[0] = motor1 >> 8;
chassis_can_send_data[1] = motor1;
chassis_can_send_data[2] = motor2 >> 8;
chassis_can_send_data[3] = motor2;
chassis_can_send_data[4] = motor3 >> 8;
chassis_can_send_data[5] = motor3;
chassis_can_send_data[6] = motor4 >> 8;
chassis_can_send_data[7] = motor4;
/* USER CODE END 2 *
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
  /* USER CODE END WHILE */
    HAL_CAN_AddTxMessage(&hcan1, &chassis_tx_message, chassis_can_send_data, &send_mail_box);
      HAL_Delay(2);
    /* USER CODE BEGIN 3 */
 }
  /* USER CODE END 3 */
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RoboMaster电机驱动 的相关文章

  • 使用vscode开发apicloud

    1 第一步 xff1a VScode安装apicloud插件 xff1b 2 第二步 xff1a 配置apicloud插件里面工作区的Apicloud Subdirectories路径 路径是 xff1a VUE目录 src 3 第三步 x
  • 构造函数的调用规则

    在面向对象编程中 xff0c 构造函数是用于创建对象的特殊函数 构造函数的调用规则如下 xff1a 当创建一个对象时 xff0c 会自动调用该对象的构造函数 构造函数的名称必须与类的名称相同 构造函数可以有多个重载版本 xff0c 但是必须
  • 深拷贝与浅拷贝

    深拷贝和浅拷贝是指在计算机编程中 xff0c 当需要复制一个对象时 xff0c 复制出来的副本与原对象之间的关系的不同 浅拷贝是指在复制对象时 xff0c 只复制了对象本身的值 xff0c 而没有复制对象包含的子对象 也就是说 xff0c
  • C++三种继承方式的区别

    访问方式分为两种 xff0c 一种是类内访问 xff0c 还有一种是类外访问 xff1b 所谓类内访问 xff0c 就是类内的函数中是使用了属性 xff1b 类外访问 xff0c 就是新建一个实例对象 xff0c 并访问这个对象的属性 xf
  • python爬虫之数据解析(BeautifulSoup)

    BeautifulSoup也是python爬虫常用的一种数据解析方法 xff0c 主要就两步 1 实例化一个Beautifulsoup对象 xff0c 平且将页面源码数据加载到该对象中 2 通过调用Beautifulsoup对象中相关的属性
  • 蓝桥杯嵌入式第十四届省赛题目解析

    前几天刚刚参加完第十四届的省赛 xff0c 这届题目比我想象中的要难 xff0c 其实想一想这也是应该的 xff0c 以前的知识点都被摸透了 xff0c 也是需要加入新的知识点了 xff0c 但是我还是想说能不能别在我参加的时候加大题目难度
  • dockerfile构建

    2 简答题 编写Dockerfile制作镜像 xff0c 生成镜像名为my build Nginx2 首先创建目录dockerfile nginx2 xff0c 保存Dockerfile文件 具体要求如下 xff1a 1 基于镜像cento
  • 安装虚拟机之后怎么配置虚拟环境、深度学习、深度强化学习环境安装

    安装步骤目录 一 配置虚拟机VMware安装包 amp Ubuntu的光盘映像文件 xff1a VMware安装Ubuntu安装 二 进入虚拟机配置环境深度 xff08 强化 xff09 学习环境的配置1 得知系统所自带python版本 x
  • 力扣-刷题方法总结(测试文章)

    知乎方面收集到的资料 xff08 非原创 xff0c 题主只是对其进行统一的整理 xff0c 方便后续查看 xff09 算法训练讲究循序渐进 xff1a 1 先从简单开始 xff0c 然后过度到中等 xff0c 再过渡到困难的进程 2 如何
  • 文件分隔符 ‘/‘(斜杠) 和 ‘\‘(反斜杠) 的使用

    前言 在学习时 xff0c 总会用到 Windows 和 Linux xff0c 输入路径时 xff0c 文件路径分隔符有时用 xff08 斜杠 xff09 xff0c 有时用 xff08 反斜杠 xff09 xff0c 属实不好区分 xf
  • VMware虚拟机安装Win11教程(解决常见报错)

    前言 今天闲来无事 xff0c 就想着装一下最新版的win11玩一下 xff0c 然后来来去去还是折腾了一些时间 xff0c 有遇到一些错误不过最好都找到了解决办法 xff0c 下面我就分享一下VMware虚拟机安装win11的详细步骤 V
  • vue打包后neditor不显示了

    原因是vue和vue template compiler 1 两者的版本不一致 xff1b 2 两者的版本低了 xff1b 例如 xff1a 我出问题的版本是 34 vue 34 34 2 5 10 34 34 vue template c
  • 【Docker常用命令】

    Docker常用命令 xff08 学习笔记 xff09 一 Docker基础命令二 Docker镜像命令三 Docker容器命令3 1 运行容器3 2 退出容器3 3 查看容器进程 xff0c 日志3 4 再次进入容器3 5 容器启停3 6
  • OpenCV学习——ArUco模块

    前提介绍 xff1a ArUco模块是OpenCV的contrib拓展库中一个模块 xff0c 需要安装OpenCV的 contrib拓展库 才能正常使用 ArUco标记 xff1a ArUco 标记是由 宽黑色边框 和 确定其标识符 xf
  • 【Vue】报错:Avoid mutating a prop directly since the value will be overwritten whenever the parent

    当我们直接改变父组件的 props 值是会报以下警告 xff1a Vue warn Avoid mutating a prop directly since the value will be overwritten whenever th
  • 深蓝学院-机器人运动规划学习笔记-第一章

    第一课 移动机器人运动规划 Motion planning for mobile robots IntroductionCourse outlineTypical planning methods overviewMap represent
  • opencv+python实战日记 入门篇(八)色块识别

    色块识别 import cv2 import numpy as np frameWidth 61 640 frameHeight 61 480 cap 61 cv2 VideoCapture 0 获取摄像头 cap set 3 640 ca
  • highway_env中自定义环境

    前言 highway env中集成了很多强化学习或者控制算法测试的驾驶环境 xff0c 但很多时候我们需要依据需求对环境进行自定义 xff0c 这里给出了自定义环境的一些步骤 xff0c 主要是基于gym 61 61 0 26版本 创建步骤
  • 深度相机和激光雷达的融合标定(Autoware)

    深度相机和激光雷达是智能汽车上常用的传感器 但深度相机具有特征难以提取 xff0c 容易受到视角影响 激光雷达存在数据不够直观且容易被吸收 xff0c 从而丢失信息 因此在自动驾驶领域 xff0c 需要对于不同传感器做数据的融合和传感器的标
  • 基于OpenCv和ROS的图像灰度化处理

    直接调用opencv灰度化函数 xff0c 对于本地图像进行处理 实现C 43 43 代码如下 xff1a 图像灰度化 include lt iostream gt cv cvtColor头文件 include lt opencv2 img

随机推荐

  • IMU的轨迹解算和航迹显示

    基于ros操作系统 xff0c 调用IMU数据包 xff0c 利用数据解算小车运动的轨迹 xff0c 并在rviz中实现轨迹的可视化 其中IMU四元数对于位移速度和加速度的转换 轨迹解算和换机显示的代码 xff1a IMU航迹推算 incl
  • 对IMU数据进行卡尔曼滤波

    我们要使用IMU数据 xff0c 必须对数据进行预处理 xff0c 卡尔曼滤波就是很好的方式 1 卡尔曼滤波 卡尔曼滤波 xff08 Kalman filtering xff09 是一种利用线性系统状态方程 xff0c 通过系统输入输出观测
  • PHPExcel导出导入问题”continue” targeting switch is equivalent to “break”.Did you mean to use “continue 2”?

    在 php 7 3 的 switch 中使用 continue 会出现警告 1 2 3 最好的方式是把 PHPExcel Shared OLE php 文件中的 continue 改为 continue 2 或 break 亲测 xff0c
  • 强化学习highway_env代码解读

    写在前面 作为强化学习的新手 xff0c 写这个系列的博客主要是为了记录学习过程 xff0c 同时也与大家分享自己的所见所想 前段时间发布了人生第一篇博客 xff0c 是关于highway env的自定义环境 但博客主要是关于如何创建一个自
  • Highway_env(Intersection)修改离散动作空间

    前言 在十字路口环境中 xff0c 主车默认的动作空间是以5m s变化的加减速以及保持原速三个动作 有时候为了学习更优化的策略 xff0c 同时与自己设置的奖励函数吻合 xff0c 需要修改环境的动作空间 这里我们主要添加两个较小加速度的纵
  • 离散动作的修改(基于highway_env的Intersection环境)

    之前写的一篇博客将离散和连续的动作空间都修改了 xff0c 这里做一下更正 基于十字路口的环境 xff0c 为了添加舒适性评判指标 xff0c 需要增加动作空间 xff0c 主要添加两个不同加速度值的离散动作 需要修改以下几个地方 xff1
  • VM 导入.ova/.ovf,未通过 OVF 规范一致性或虚拟硬件合规性检查.

    今天在用虚拟机VM导入ubuntu riscv ova文件新建Ubuntu时报错 xff1a 未通过OVF规范一致性或虚拟硬件合规性检查 网上查了一下 xff0c 了解到这是因为VM内置的Ofvtool工具的版本较低导致的 xff0c 解决
  • 借助FileZilla实现Ubuntu和 Windows之间文件互传

    借助FileZilla实现Windows和 Ubuntu间文件互传 xff0c 需要使用 FTP服务 xff0c 设置方法如下 xff1a 1 Windows下安装FTP客户端 FileZilla xff08 该软件免费 xff0c 可以直
  • 使用Ubuntu系统中的gparted工具对Ubuntu磁盘扩充

    最近在使用Ubuntu时 xff0c 发现经常提示内存空间不足 就总结了扩充Ubuntu内存的主要流程 xff0c 操作步骤如下 xff1a 第一步 xff1a 在虚拟机操作界面 xff08 关闭要进行磁盘扩充的Ubuntu xff09 进
  • 通过挂载的方式,解决由于权限无法将rootfs直接拷贝到SD卡的EXT4分区的问题

    最近在使用SD卡制作Linux启动文件时 xff0c 要将自己制作的根文件系统 xff08 rootfs xff09 拷到SD卡的EXT4分区时 xff0c 发现由于权限问题无法直接拷贝 xff0c 现通过挂载的方式解决该问题 xff0c
  • RISC-V架构下,Busybox工具的安装

    今天在RISC V架构下安装Busybox工具箱时 xff0c 找了很多的资料 xff0c 但都是ARM架构下的安装教程 xff0c 尽管内核不同但有一定的参考价值 xff0c 安装完成后对RISC V下Busybox工具箱的安装过程做出了
  • 串行通信协议小结(Serial Protocols)(1)

    通信关键点 同步通信 xff08 例如SPI xff09 双方之间的数据传输使用公共时钟信号进行同步 xff0c 数据以稳定的流传输 不需要额外的比特来标记传输的每个数据块的开始 结束 xff0c 因此速度更快 异步通信 xff08 例如U
  • MATLAB课程笔记(二)——MATLAB基础知识

    MATLAB系统环境 MATLAB操作界面的组成 采用与office 2010相同风格的操作界面 gt gt 命令提示符表示MATLAB处于准备状态 xff1a 续行符 MATLAB的搜索路径 gt gt clear 清除工作区的全部变量
  • SVN的日常使用

    1 已经加入ignore的文件夹 xff0c 解除方法 xff1a 直接到被ignore的位置 xff0c 执行 xff1a svn add lt 你被ignore的文件名 gt no ignore no ignore是取消忽略 如果是ad
  • RM遥控器接收程序的分析

    由遥控器接收分析串口与DMA RM的遥控器在使用的过程中在大体上可以分成两个部分 xff1a 信息的接收 与 信息的解析 xff0c 在信息的接收中主要用到了串口的空闲中断和DMA双缓冲区接收在本篇的信息接收部分主要根据RM官方给出的代码来
  • robomaster麦轮运动解算

    1 资源与代码 1 1 参考文章 本文主要参考的三篇文章如下 xff1a 麦轮运动特性分析 xff1a https mp weixin qq com s biz 61 MzI3MTIyMjQwNQ 61 61 amp mid 61 2247
  • FreeRTOS内核——任务与任务切换

    2 任务 相关函数 1 xTaskCreateStatic 2 prvInitialiseNewTask 3 prvInitialiseTaskLists 4 vTaskStartScheduler 5 xPortStartSchedule
  • FreeRTOS应用——任务

    12 任务 12 1 相关函数 12 1 1 任务创建函数与启动调度 12 1 1 1 xTaskCreateStatic 静态创建任务 if configSUPPORT STATIC ALLOCATION 61 61 1 TaskHand
  • FreeRTOS应用——消息队列

    13 消息队列 消息队列是一种常用于任务键通信的数据结构 xff0c 队列可以在任务与任务间 中断与任务间传递信息 xff0c 实现了任务接收来自其他任务或者中断的不定长数据 任务能从队列中读取信息 xff0c 当队列中的消息为空时 xff
  • RoboMaster电机驱动

    1 硬件 1 1 电机 RM有很多不同型号的电机 xff0c 不同型号的电机有它不同的用途 xff0c 但是以用途分类的话主要是分成两种电机 xff1a 用来精准控制位置的电机 xff0c 在RM中的主要是云台电机 RM官网上的云台电机只有