如何在任何STM32上面安装micro_ros

就我知道的:micro-ros只能在特定的昂贵的开发板上面运行,但是偶然发现了这个文章,似乎提供了一个全新的方式来在ros2和单片机之间通讯,如果能够这样肯定也能够提高效率,但即使不行,使用串口库也应该比较简单。

GitHub - lFatality/stm32_micro_ros_setup: Example of how to setup micro-ROS on any STM32 microcontroller

README.md

Setting up micro-ROS on any STM32 microcontroller

This repository gives an example of how to set up micro-ROS on any STM32 microcontroller. For this repository an STM32F429ZI was chosen but you are free to choose another one.

You can also find the instructions in video form here: https://youtu.be/xbWaHARjSmk

Goal

If you follow all steps in the tutorial you should have an STM32 microcontroller with a micro-ROS publisher that transmits messages via UART to your PC running ROS 2. Here you can receive the messages via ros2 topic echo.

Steps

In the following the required steps to achieve the goal are presented in detail. It will show how to do this for a microcontroller that is not listed as a device directly supported by micro-ROS. (看到没有:即使是不受官方支持的,也可以使用MICRO_ROS,那个官方支持的开发板实在太少,而且太贵,所以我才说成本太高,现在看来有办法降低成本了)If you find that you have problems check out the Troubleshooting section below.(如果有问题请看后面的”Trobleshooting“部分

micro-ROS

1.) Create a new CubeMx project for your micro controller
2.) In System Core -> RCC -> High Speed Clock (HSE) select Crystal/Ceramic Resonator


3.) In System Core -> SYS -> Timebase Source select TIM1


4.) In Middleware -> FREERTOS -> Interface select CMSIS_V2


4.1.) In Middleware -> FREERTOS -> Configuration -> Task and Queues double click the defaultTask and set a stack size of 3000. It has to be greater than 10.000 byte (3000 words * 4 byte = 12.000 byte).F103C8T6有20KB,明明没有超为什么不行?

 注意了:STM32C8T6在这里好像出了问题:因为这个Stack Size我感觉好像超了

如果遇到这个问题需要首先修改堆栈大小:

 修改步骤:修改Config parmeters-->Memory management settings---->TOTAL_HEAP_SIZE设置为16000;然后就可以解决这个问题

 看吧已经改好了

5.) In Connectivity choose the UART / USART that you want to use.


5.1.) In the Uart configuration, go to DMA Settings. Click on the Add button. Click on the Select dropdown and choose both Rx and Tx.


5.2.) Click on the Rx DMA you've just created and for Mode choose Circular.


5.3.) For the priority of the DMA choose Very high for both Rx and Tx.


5.4.) Go to NVIC Settings of the UART and activate the UARTx global interrupt.


6.) Set up the Clock Configuration for your micro controller
7.) In Project Manager select a folder where to generate your code
7.1.) In Toolchain / IDE select Makefile(这里有点不一样:平时都选择keil)


7.2.) Optional: In Project Manager -> Code Generator select Generate peripheral intitialization as a pair of '.c/.h' files per peripheral
8.) Click on Generate Code
9.) In the root folder of the code you've just generated, clone the following repository (into a subfolder, don't change its name).:

git clone https://github.com/micro-ROS/micro_ros_stm32cubemx_utils.git

10.) Make sure you have the right branch for your ROS version checked out 11.) In the Makefile that was generated by CubeMx put the following code snippet after the part where it says build the application:

#######################################
# micro-ROS addons
#######################################
LDFLAGS += micro_ros_stm32cubemx_utils/microros_static_library/libmicroros/libmicroros.a
C_INCLUDES += -Imicro_ros_stm32cubemx_utils/microros_static_library/libmicroros/microros_include

# Add micro-ROS utils
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/custom_memory_manager.c
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_allocators.c
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_time.c

# Set here the custom transport implementation
C_SOURCES += micro_ros_stm32cubemx_utils/extra_sources/microros_transports/dma_transport.c

print_cflags:
  @echo $(CFLAGS)

11.) Pull and run the following docker to generate the micro-ros lib. Make sure you use the right ROS version when you pull / run the docker. This should be executed in the root folder of your project.

docker pull microros/micro_ros_static_library_builder:galactic
docker run -it --rm -v $(pwd):/project --env MICROROS_LIBRARY_FOLDER=micro_ros_stm32cubemx_utils/microros_static_library microros/micro_ros_static_library_builder:galactic

12.) If it asks for the CFLAGS, if you can see some, continue. They might look like this:

Found CFLAGS:
-------------
-mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -DUSE_HAL_DRIVER -DSTM32F429xx -ICore/Inc -IDrivers/STM32F4xx_HAL_Driver/Inc -IDrivers/STM32F4xx_HAL_Driver/Inc/Legacy -IMiddlewares/Third_Party/FreeRTOS/Source/include -IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS -IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -IDrivers/CMSIS/Device/ST/STM32F4xx/Include -IDrivers/CMSIS/Include -IDrivers/CMSIS/Include -Imicro_ros_stm32cubemx_utils/microros_static_library/libmicroros/microros_include -Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 -MMD -MP -MFprint_cflags
-------------

If instead the CFLAGS are empty there was likely a mistake. If you get an error about a missing separator in the Makefile, check the line in the Makefile. For me there were 2 similar includes. I deleted one of them.

13.) If you get an error like this during building:

'rcutils' exports library 'dl' which couldn't be found

That's ok and can be ignored.

14.) Go into Core/main.cpp and adjust it so that it's similar to the sample_main.cpp you can find in the micro_ros_stm32cubemx_utils repository we found earlier. The most interesting parts are the following:

#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <uxr/client/transport.h>
#include <rmw_microxrcedds_c/config.h>
#include <rmw_microros/rmw_microros.h>

#include <std_msgs/msg/int32.h>
bool cubemx_transport_open(struct uxrCustomTransport * transport);
bool cubemx_transport_close(struct uxrCustomTransport * transport);
size_t cubemx_transport_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err);
size_t cubemx_transport_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err);

void * microros_allocate(size_t size, void * state);
void microros_deallocate(void * pointer, void * state);
void * microros_reallocate(void * pointer, size_t size, void * state);
void * microros_zero_allocate(size_t number_of_elements, size_t size_of_element, void * state);
void StartDefaultTask(void *argument)
{
    /* USER CODE BEGIN StartDefaultTask */
    /* Infinite loop */
    // micro-ROS configuration

    rmw_uros_set_custom_transport(
      true,
      (void *) &huart2,
      cubemx_transport_open,
      cubemx_transport_close,
      cubemx_transport_write,
      cubemx_transport_read);

    rcl_allocator_t freeRTOS_allocator = rcutils_get_zero_initialized_allocator();
    freeRTOS_allocator.allocate = microros_allocate;
    freeRTOS_allocator.deallocate = microros_deallocate;
    freeRTOS_allocator.reallocate = microros_reallocate;
    freeRTOS_allocator.zero_allocate =  microros_zero_allocate;

    if (!rcutils_set_default_allocator(&freeRTOS_allocator)) {
        printf("Error on default allocators (line %d)\n", __LINE__);
    }

    // micro-ROS app

    rcl_publisher_t publisher;
    std_msgs__msg__Int32 msg;
    rclc_support_t support;
    rcl_allocator_t allocator;
    rcl_node_t node;

    allocator = rcl_get_default_allocator();

    //create init_options
    rclc_support_init(&support, 0, NULL, &allocator);

    // create node
    rclc_node_init_default(&node, "cubemx_node", "", &support);

    // create publisher
    rclc_publisher_init_default(
      &publisher,
      &node,
      ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
      "cubemx_publisher");

    msg.data = 0;

    for(;;)
    {
      rcl_ret_t ret = rcl_publish(&publisher, &msg, NULL);
      if (ret != RCL_RET_OK)
      {
        printf("Error publishing (line %d)\n", __LINE__);
      }

      msg.data++;
      osDelay(10);
    }
    /* USER CODE END StartDefaultTask */
}

15.) Open the project in your favorite IDE. In general you should now be able to build and debug your program. To built I used the arm-none-eabi-toolchain. To flash and debug I used openocd. If you can not build check step 15.1.

15.1.) It might be that you can not build yet because of missing syscalls. In that case you might get errors like undefined reference to _kill or undefined reference to _getpid. In that case add a syscalls.c file to your project and also add it to the Makefile so that it will be compiled. You can find an example syscalls.c at the end of this page.

micro-ROS agent

19.) Now you need a micro-ROS agent. It's responsible to create the communication between your embedded controller and the rest of your ROS 2 software. Create a different folder that will be used as a ROS 2 workspace.

20.) Clone the micro_ros_setup repository and build it by executing the following steps from the root of your workspace folder:

source /opt/ros/$ROS_DISTRO/setup.bash
git clone -b $ROS_DISTRO https://github.com/micro-ROS/micro_ros_setup.git src/micro_ros_setup
rosdep update && rosdep install --from-path src --ignore-src -y
colcon build
source install/local_setup.bash

21.) Build the agent packages

ros2 run micro_ros_setup create_agent_ws.sh
ros2 run micro_ros_setup build_agent.sh
source install/local_setup.sh

I got a warning about stderr output when running build_agent.sh (at the end of the build process) but I ignored that. I also had a problem were build_agent.sh complained about being unable to find a package (Package 'micro_ros_agent' specified with --packages-up-to was not found). This was because I didn't follow the steps to build the workspace first correctly (step 20).

22.) Start the micro-ros-agent. For example:

ros2 run micro_ros_agent micro_ros_agent serial -b 115200 --dev /dev/ttyACM0

serial: for UART use, other options available -b: baudrate --dev: the device to use

To get help with the usage:

ros2 run micro_ros_agent micro_ros_agent --help

23.) In the agent you should see something like this:

[1641665035.090947] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1641665035.130109] info     | Root.cpp           | create_client            | create                 | client_key: 0x041835D4, session_id: 0x81
[1641665035.130212] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x041835D4, address: 0
[1641665035.156038] info     | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x041835D4, participant_id: 0x000(1)
[1641665035.171020] info     | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x041835D4, topic_id: 0x000(2), participant_id: 0x000(1)
[1641665035.181034] info     | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x041835D4, publisher_id: 0x000(3), participant_id: 0x000(1)
[1641665035.191347] info     | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x041835D4, datawriter_id: 0x000(5), publisher_id: 0x000(3)
[1641665052.957930] info     | SessionManager.hpp | establish_session        | session re-established | client_key: 0x041835D4, address: 0

This is some kind of handshake between the agent and the embedded system. You might have to restart your MCU, the agent should be started first it seems.

If you see something like this instead:

[1641665033.757172] info     | TermiosAgentLinux.cpp | init                     | Serial port not found. | device: /dev/ttyACM0, error 2, waiting for connection...
[1641665034.757430] info     | TermiosAgentLinux.cpp | init                     | Serial port not found. | device: /dev/ttyACM0, error 2, waiting for connection...

You have likely selected the wrong device or your MCU is not connected.

23.) You should now be able to see the messages published by the MCU on ROS2:

ros2 topic echo /cubemx_publisher

The data would look like this:

---
data: 2399
---
data: 2400
---
data: 2401
---
data: 2402
---
data: 2403
---
data: 2404
---

Troubleshooting

Problem 1

When stepping through the code the programs hangs at rclc_support_init.

Solution 1

Be sure that the UART you use when calling rmw_uros_set_custom_transport is the one that you set up for ROS (e.g. with the right DMA settings). Also be aware that the call to this function can take some time (~10 seconds). When running the micro-ROS agent it usually is faster though.

Problem 2

The publishing doesn't work. I go into the error case in the infinite loop of the main task:

rcl_ret_t ret = rcl_publish(&publisher, &msg, NULL);
if (ret != RCL_RET_OK)
{
  printf("Error publishing (line %d)\n", __LINE__); // <-------------------- this is entered
}

In my case I can see some prints on the UART before entering the while loop. There is a lot of random bytes but sometimes I can see XRCE.

Solution 2

You need a running micro-ROS agent. See steps 19.) and following. If you have an agent running but it still doesn't work, look at problem / solution 6.

Problem 3

When trying to flash the board, I get an openocd bug saying something with "free"

Solution 3

Unplug MCU and replug it (power).

Problem 4

When I run the agent and MCU the agent says

fynn@sphalerite:~/main/dev/tests/micro-ros/agent_ws$ ros2 run micro_ros_agent micro_ros_agent serial -b 115200 --dev /dev/ttyACM0
[1643036775.906617] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1643036775.906762] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 4

but nothing else happens and I can't receive my data.

Solution 4 :

Check that your MCU doesn't crash anywhere (e.g. in the syscalls).

Problem 5

I get an error saying that _getpid and _kill are not defined.

Solution 5

You need to define a syscalls.c file and add these function with their functionality. You can find an example of such a file at the end of this page.

Problem 6

When I run the agent and the MCU, the agent says

[1641665035.090947] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1641665035.130109] info     | Root.cpp           | create_client            | create                 | client_key: 0x041835D4, session_id: 0x81
[1641665035.130212] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x041835D4, address: 0

but it's not creating a participant or topic. I can't receive my data.

Solution 6

Check that you don't have another serial program (putty, hterm, gtkterm, ...) connected to your device (at least not to that same UART). Also be sure that your hardware setup is correct, e.g. that you have GND connected between the two nodes when using a UART connection.

Problem 7

If you're using Eclipse: When compiling Eclipse says Error: Program "" not found in PATH

Solution 7

Right click your project -> Properties -> C/C++ Build -> Uncheck "Use default build command" and exchange ${cross_make} with a simple make

Problem 8

If you're using Eclipse:
I get an error that the program "" can not be executed

Solution 8

Right click your project -> Properties -> C/C++ Build: Untick Use default build command. Define Build command as: make

Problem 10

If you're using Eclipse and it says that it can't find the arm-none-eabi-gcc

Solution 10

You need to download and extract the toolchain. You can find it here: Downloads | GNU Arm Embedded Toolchain Downloads – Arm Developer

Then set up your Eclipse to know where it is: Right click your project -> Properties -> MCU -> Arm Toolchains Paths: Toolchain name: xPack GNU Arm Embedded GCC Toolchain folder: path/to/your/arm-none-eabi-toolchain/bin

In the bin folder should be arm-none-eabi-gcc among others.

If it still doesn't work, try just opening the following menu: Right click your project -> Properties -> C/C++ Build -> Settings

Example syscalls.c

/**
*****************************************************************************
**
**  File        : syscalls.c
**
**  Author        : Auto-generated by System workbench for STM32
**
**  Abstract    : System Workbench Minimal System calls file
**
**                   For more information about which c-functions
**                need which of these lowlevel functions
**                please consult the Newlib libc-manual
**
**  Target      : STMicroelectronics STM32
**
**  Distribution: The file is distributed “as is,” without any warranty
**                of any kind.
**
*****************************************************************************
** @attention
**
** <h2><center>&copy; COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
**   1. Redistributions of source code must retain the above copyright notice,
**      this list of conditions and the following disclaimer.
**   2. Redistributions in binary form must reproduce the above copyright notice,
**      this list of conditions and the following disclaimer in the documentation
**      and/or other materials provided with the distribution.
**   3. Neither the name of STMicroelectronics nor the names of its contributors
**      may be used to endorse or promote products derived from this software
**      without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************************
*/

// the code was modified by Fynn Boyer

/* Includes */
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>


/* Variables */
//#undef errno
extern int errno;
extern int __io_putchar(int ch) __attribute__((weak));
extern int __io_getchar(void) __attribute__((weak));

register char * stack_ptr asm("sp");

char *__env[1] = { 0 };
char **environ = __env;

extern char _estack;  // see ld file
extern char _Min_Stack_Size;  // see ld file

/* Functions */
void initialise_monitor_handles()
{
}

int _getpid(void)
{
    return 1;
}

int _kill(int pid, int sig)
{
    errno = EINVAL;
    return -1;
}

void _exit (int status)
{
    _kill(status, -1);
    while (1) {}        /* Make sure we hang here */
}

__attribute__((weak)) int _read(int file, char *ptr, int len)
{
    int DataIdx;

    for (DataIdx = 0; DataIdx < len; DataIdx++)
    {
        *ptr++ = __io_getchar();
    }

return len;
}

__attribute__((weak)) int _write(int file, char *ptr, int len)
{
    int DataIdx;

    for (DataIdx = 0; DataIdx < len; DataIdx++)
    {
        __io_putchar(*ptr++);
    }
    return len;
}

caddr_t _sbrk(int incr) {
    extern char __heap_start__ asm("end");  // Defined by the linker.
    static char *heap_end;
    char *prev_heap_end;

    if (heap_end == NULL) heap_end = &__heap_start__;

    prev_heap_end = heap_end;

    if (heap_end + incr > &_estack - _Min_Stack_Size) {
            __asm("BKPT #0\n");
        errno = ENOMEM;
        return (caddr_t)-1;

    }

    heap_end += incr;
    return (caddr_t)prev_heap_end;

}

int _close(int file)
{
    return -1;
}


int _fstat(int file, struct stat *st)
{
    st->st_mode = S_IFCHR;
    return 0;
}

int _isatty(int file)
{
    return 1;
}

int _lseek(int file, int ptr, int dir)
{
    return 0;
}

int _open(char *path, int flags, ...)
{
    /* Pretend like we always fail */
    return -1;
}

int _wait(int *status)
{
    errno = ECHILD;
    return -1;
}

int _unlink(char *name)
{
    errno = ENOENT;
    return -1;
}

int _times(struct tms *buf)
{
    return -1;
}

int _stat(char *file, struct stat *st)
{
    st->st_mode = S_IFCHR;
    return 0;
}

int _link(char *old, char *new)
{
    errno = EMLINK;
    return -1;
}

int _fork(void)
{
    errno = EAGAIN;
    return -1;
}

int _execve(char *name, char **argv, char **env)
{
    errno = ENOMEM;
    return -1;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/224086.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android Camera 预览尺寸的选取与旋转角度的设定

Camera 在音视频的世界中, 就像我们的眼睛一样, 是负责图像采集的入口, 要想实现一款高可用的 Camera, 我认为需要关注以下几个方面 相机的预览相机的拍摄相机的录制 OpenGL ES 主要用于图像的渲染, 因此这里主要聚焦于相机的预览, 想要让相机的数据呈现到我们屏幕上, 主要有…

Java 将word转为PDF的三种方式和处理在服务器上下载后乱码的格式

我这边是因为业务需要将之前导出的word文档转换为PDF文件&#xff0c;然后页面预览下载这样的情况。之前导出word文档又不是我做的&#xff0c;所以为了不影响业务&#xff0c;只是将最后在输出流时转换成了PDF&#xff0c;当时本地调用没什么问题&#xff0c;一切正常&#xf…

「X」Embedding in NLP|Token 和 N-Gram、Bag-of-Words 模型释义

ChatGPT&#xff08;GPT-3.5&#xff09;和其他大型语言模型&#xff08;Pi、Claude、Bard 等&#xff09;凭何火爆全球&#xff1f;这些语言模型的运作原理是什么&#xff1f;为什么它们在所训练的任务上表现如此出色&#xff1f; 虽然没有人可以给出完整的答案&#xff0c;但…

c++新经典模板与泛型编程:const修饰符的移除与增加

const修饰符的移除 让你来写移除const修饰符&#xff0c;你会怎么样来写&#xff1f; &#x1f602;&#x1f602;trait类模板&#xff0c;如下 #include <iostream>// 泛化版本 template<typename T> struct RemoveConst {using type T; };// 特化版本 template…

案例059:基于微信小程序的在线投稿系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

18、XSS——cookie安全

文章目录 1、cookie重要字段2、子域cookie机制3、路径cookie机制4、HttpOnly Cookie机制5、Secure Cookie机制6、本地cookie与内存cookie7、本地存储方式 一般来说&#xff0c;同域内浏览器中发出的任何一个请求都会带上cookie&#xff0c;无论请求什么资源&#xff0c;请求时&…

ubuntu中显卡驱动,cuda,cudnn安装

1. 在ubuntu中安装显卡驱动 参考&#xff1a;https://blog.csdn.net/m0_37605642/article/details/119651996 2.在ubuntu中安装cuda 参考&#xff1a;https://blog.csdn.net/m0_61431544/article/details/127007300 2.1 安装cuda cuda官网&#xff1a; https://developer.n…

配置端口安全示例

组网需求 如图1所示&#xff0c;用户PC1、PC2、PC3通过接入设备连接公司网络。为了提高用户接入的安全性&#xff0c;将接入设备Switch的接口使能端口安全功能&#xff0c;并且设置接口学习MAC地址数的上限为接入用户数&#xff0c;这样其他外来人员使用自己带来的PC无法访问公…

基于单片机出租车计价器控制系统

**单片机设计介绍&#xff0c;基于单片机出租车计价器控制系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的出租车计价器控制系统是一个用于控制和管理出租车费用计算的电子设备。下面是一个简单的系统设计介绍&…

【若依系列】1.项目修改成自己包名并启动服务

项目下载地址&#xff1a; 分离版本 https://gitee.com/y_project/RuoYi-Vue 修改工具下载 https://gitee.com/lpf_project/common-tools 相关截图&#xff1a; 1.项目结构&#xff1a; 2.修改包名工具&#xff1a; 工具截图&#xff0c;根据对应提示自定义修改即可&#x…

HarmonyOS4.0从零开始的开发教程08构建列表页面

HarmonyOS&#xff08;六&#xff09;构建列表页面 List组件和Grid组件的使用 简介 在我们常用的手机应用中&#xff0c;经常会见到一些数据列表&#xff0c;如设置页面、通讯录、商品列表等。下图中两个页面都包含列表&#xff0c;“首页”页面中包含两个网格布局&#xff…

为何开展数据清洗、特征工程和数据可视化、数据挖掘与建模?

1.2为何开展数据清洗、特征工程和数据可视化、数据挖掘与建模 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解1.2节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。内容涵盖数据科学…

AWS基于x86 vs Graviton(ARM)的RDS MySQL性能对比

概述 这是一个系列。在前面&#xff0c;我们测试了阿里云经济版&#xff08;“ARM”&#xff09;与标准版的性能/价格对比&#xff1b;华为云x86规格与ARM&#xff08;鲲鹏增强&#xff09;版的性能/价格对比。现在&#xff0c;再来看看AWS的ARM版本的RDS情况 在2018年&#…

深度学习猫狗分类 - python opencv cnn 计算机竞赛

文章目录 0 前言1 课题背景2 使用CNN进行猫狗分类3 数据集处理4 神经网络的编写5 Tensorflow计算图的构建6 模型的训练和测试7 预测效果8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习猫狗分类 ** 该项目较为新颖&a…

华为配置流量抑制示例

如拓扑图所示&#xff0c;SwitchA作为二层网络到三层路由器的衔接点&#xff0c;需要限制二层网络转发的广播、未知组播和未知单播报文&#xff0c;防止产生广播风暴&#xff0c;同时限制二三层网络转发的已知组播和已知单播报文&#xff0c;防止大流量冲击。 配置思路 用如下…

gpt1与bert区别

区别1&#xff1a;网络结构&#xff08;主要是Masked Multi-Head-Attention和Multi-Head-Attention&#xff09; gpt1使用transformer的decoder&#xff0c;单向编码&#xff0c;是一种基于语言模型的生成式模型&#xff0c;更适合生成下一个单词或句子 bert使用transformer的…

Vue 父传子组件传参 defineProps

defineProps 属性&#xff1a;用于接收父组件传递过来的数据。 注意&#xff1a;如果 defineProps 接收的参数名&#xff0c;和已有变量名相同&#xff0c;就会造成命名冲突。 语法格式&#xff1a; // 无限制 const props defineProps([参数名, 参数名]);// 限制数据类型 …

Spring Boot 项目的创建、配置文件、日志

文章目录 Spring Boot 优点创建 Spring Boot 项目创建项目认识目录网页创建&#xff08;了解&#xff09; 约定大于配置Spring Boot 配置文件配置文件格式读取配置项properties 配置文件yml 配置文件基本语法进阶语法配置对象配置集合yml 设置不同环境的配置文件 Spring Boot 日…

springboot——自动装配

自动装配 Condition: Condition内置方法&#xff1a;boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)&#xff0c;返回值为布尔型 重写matches方法的类&#xff1a;SpringBootCondition等 SpringBootCondition&#xff1a;springboot自带的实现类…

QT5.4.1无法打开文件

问题描述&#xff1a;起初是在QT代码中运行打开文件代码&#xff1a; QString gFilename QFileDialog::getOpenFileName(this,"open File",path,"*", nullptr,QFileDialog::DontUseNativeDialog);时&#xff0c;出现了堵塞情况&#xff0c;经过多次实验一…