ROS2 高级组件中的webots介绍
前言
这一篇文章主要是和大家分享一下关于ROS2 高级组件中的webots,会介绍关于webots的知识点,以及如何安装和测试环节,最后就是利用 webots 实现一个差速轮式机器人的运动仿真。
正文内容
webots 引入和学习资料
webots 是来自瑞士的 Cyberbotics 公司(Cyberbotics 官网)推出的机器人仿真软件,旨在降低机器人技术开发的门槛,并加速从理论到实践的转化过程。该平台用户群体非常广泛,涵盖了教育、科研和工业界。2018年以前,webots 是一款商业软件,2018年12月以后,Webots作为开放源码软件在Apache 2.0许可下发布(webots github)。
webots 和 ros:webots 本身是一款独立的仿真软件,跟 ros 没有关系。后来,ros1 有了 webots_ros 软件包,ros2 有了 webots_ros2 软件包,从而打通了 ros 与 webots 之间的接口,使得两者之间可以顺利通信。
webots 安装以及样例测试
(1)webots 安装:由于 webots 是从商业转向的开源,因此安装非常简单,如下。本系列 ros2 文章的基础环境是 Ubuntu22.04 + ros2 humble,安装的 webots 版本是 webotsR2023b。
cd ~
# webots_ros2
sudo apt-get install ros-humble-webots-ros2
# ~/.ros/webotsR2023b/webots
ros2 launch webots_ros2_universal_robot multirobot_launch.py
# WEBOTS_HOME
export WEBOTS_HOME=/home/ycao/.ros/webotsR2023b/webots
(2)在 webots_ros2 中,利用 webots 实现了多种机器人仿真,包括 TurtleBot3 ,Tesla Model3,测试 TurtleBot3 :
# TurtleBot3
ros2 launch webots_ros2_turtlebot robot_launch.pyros2 run teleop_twist_keyboard teleop_twist_keyboard
测试 Tesla Model3
ros2 launch webots_ros2_tesla robot_launch.py
自编写 webots_demo
(1)创建 webots_demo 软件包以及相关文件
cd ~/colcon_ws/src
ros2 pkg create --build-type ament_python --license Apache-2.0 webots_demo --dependencies rclpy geometry_msgs webots_ros2_driver
cd webots_demo
mkdir launch worlds
touch launch/mbot_launch.py
touch resource/mbot.urdf
touch webots_demo/mbot_driver.py webots_demo/obstacle_avoider.py
(2)在 worlds 目录中添加 my_world.wbt,这个文件是 webots 的建模文件,里面包含虚拟仿真环境和一个差速轮式机器人。
(3)编写 mbot_driver.py:这是差速轮式机器人车轮电机控制程序
import rclpy
from geometry_msgs.msg import TwistHALF_DISTANCE_BETWEEN_WHEELS = 0.045
WHEEL_RADIUS = 0.025class MbotDriver:def init(self, webots_node, properties):self._robot = webots_node.robotself._left_motor = self._robot.getDevice('left wheel motor')self._right_motor = self._robot.getDevice('right wheel motor')self._left_motor.setPosition(float('inf'))self._left_motor.setVelocity(0)self._right_motor.setPosition(float('inf'))self._right_motor.setVelocity(0)self._target_twist = Twist()rclpy.init(args=None)self._node = rclpy.create_node('mbot_driver')self._node.create_subscription(Twist, 'cmd_vel', self._cmd_vel_callback, 1)def _cmd_vel_callback(self, twist):self._target_twist = twistdef step(self):rclpy.spin_once(self._node, timeout_sec=0)forward_speed = self._target_twist.linear.xangular_speed = self._target_twist.angular.zcommand_motor_left = (forward_speed - angular_speed * HALF_DISTANCE_BETWEEN_WHEELS) / WHEEL_RADIUScommand_motor_right = (forward_speed + angular_speed * HALF_DISTANCE_BETWEEN_WHEELS) / WHEEL_RADIUSself._left_motor.setVelocity(command_motor_left)self._right_motor.setVelocity(command_motor_right)
(4)编写 mbot.urdf:这是差速轮式机器人的 URDF 描述文件(Unified Robot Description Format,统一的机器人描述文件格式,使用 xml 格式),为机器人添加了左右距离传感器,并指定了车轮电机控制器。
<?xml version="1.0" ?>
<robot name="My robot"><webots><device reference="ds0" type="DistanceSensor"><ros><topicName>/left_sensor</topicName><alwaysOn>true</alwaysOn></ros></device><device reference="ds1" type="DistanceSensor"><ros><topicName>/right_sensor</topicName><alwaysOn>true</alwaysOn></ros></device> <plugin type="webots_demo.mbot_driver.MbotDriver" /></webots>
</robot>
(5)编写 obstacle_avoider.py:这个程序基于左右距离传感器的数据,通过 cmd_vel topic 控制机器人避障。
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Range
from geometry_msgs.msg import TwistMAX_RANGE = 0.15class ObstacleAvoider(Node):def __init__(self):super().__init__('obstacle_avoider')self._publisher = self.create_publisher(Twist, 'cmd_vel', 1)self.create_subscription(Range, 'left_sensor', self._left_sensor_callback, 1)self.create_subscription(Range, 'right_sensor', self._right_sensor_callback, 1)def _left_sensor_callback(self, message):self._left_sensor_value = message.rangedef _right_sensor_callback(self, message):self._right_sensor_value = message.rangecommand_message = Twist()command_message.linear.x = 0.1if self._left_sensor_value < 0.9 * MAX_RANGE or self._right_sensor_value < 0.9 * MAX_RANGE:command_message.angular.z = -2.0self._publisher.publish(command_message)def main(args=None):rclpy.init(args=args)avoider = ObstacleAvoider()rclpy.spin(avoider)avoider.destroy_node()rclpy.shutdown()if __name__ == '__main__':main()
(6)编写 mbot_launch.py :
import os
import launch
from launch_ros.actions import Node
from launch import LaunchDescription
from ament_index_python.packages import get_package_share_directory
from webots_ros2_driver.webots_launcher import WebotsLauncher
from webots_ros2_driver.webots_controller import WebotsControllerdef generate_launch_description():package_dir = get_package_share_directory('webots_demo')mbot_description_path = os.path.join(package_dir, 'resource', 'mbot.urdf')# https://cyberbotics.com/doc/guide/tutorialswebots_world = WebotsLauncher(world=os.path.join(package_dir, 'worlds', 'my_world.wbt'))mbot_controller = WebotsController(robot_name='mbot_car',parameters=[{'robot_description': mbot_description_path},], )obstacle_avoider = Node(package='webots_demo',executable='obstacle_avoider',)return LaunchDescription([webots_world,mbot_controller,obstacle_avoider,launch.actions.RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit(target_action=webots_world,on_exit=[launch.actions.EmitEvent(event=launch.events.Shutdown())],))])
(7)修改 setup.py
import os
from glob import glob
from setuptools import find_packages, setuppackage_name = 'webots_demo'setup(name=package_name,version='0.0.0',packages=find_packages(exclude=['test']),data_files=[('share/ament_index/resource_index/packages',['resource/' + package_name]),('share/' + package_name, ['package.xml']),(os.path.join('share', package_name, 'launch'), glob(os.path.join('launch', '*_launch.py'))),(os.path.join('share', package_name, 'worlds'), glob(os.path.join('worlds', '*.wbt'))),(os.path.join('share', package_name, 'resource'), glob(os.path.join('resource', '*.urdf')))],install_requires=['setuptools'],zip_safe=True,maintainer='ycao',maintainer_email='1641395022@qq.com',description='TODO: Package description',license='Apache-2.0',tests_require=['pytest'],entry_points={'console_scripts': ['mbot_driver = webots_demo.mbot_driver:main','obstacle_avoider = webots_demo.obstacle_avoider:main'],},
)
(8)编译并运行
cd ~/colcon_ws/src
colcon build --packages-select webots_demo
source install/local_setup.bash
ros2 launch webots_demo mbot_launch.py
总结
本文主要通过一个差速轮式机器人仿真样例,为大家引入 webots ,但没有深入探究 webots 的建模细节。 有兴趣的朋友可以自己深入研究一下内容哟。
相关文章:
ROS2 高级组件中的webots介绍
前言 这一篇文章主要是和大家分享一下关于ROS2 高级组件中的webots,会介绍关于webots的知识点,以及如何安装和测试环节,最后就是利用 webots 实现一个差速轮式机器人的运动仿真。 正文内容 webots 引入和学习资料 webots 是来自瑞士的 Cy…...
SvelteKit 最新中文文档教程(17)—— 仅服务端模块和快照
前言 Svelte,一个语法简洁、入门容易,面向未来的前端框架。 从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1: Svelte …...
Java 基础-29-final关键字-详解
在Java编程语言中,final是一个非常重要的关键字,它用于不同的上下文中以表示某些东西是不可变的。本文将详细介绍final关键字的各种用法和其应用场景。 1. final变量 当你将一个变量声明为final时,这意味着一旦给这个变量赋值后,…...
从数据透视到AI分析,用四层架构解决运维难题
在数字化转型的浪潮中,企业 IT 系统已从单一架构演变为多云、多设备、多应用的复杂生态。传统监控工具因覆盖不全、响应滞后、分析能力弱而逐渐失效。Site24x7 以“全栈覆盖 智能协同”为核心,构建了一套四层递进式监控架构,实现从基础设施到…...
大智慧前端面试题及参考答案
如何实现水平垂直居中? 在前端开发中,实现元素的水平垂直居中是一个常见的需求,以下是几种常见的实现方式: 使用绝对定位和负边距:将元素的position设置为absolute,然后通过top、left属性将其定位到父元素的中心位置,再使用负的margin值来调整元素自身的偏移,使其水平垂…...
PyQt学习记录
PyQt学习记录 要在界面上 创建一个控件,就需要在程序代码中 创建 这个 控件对应类 地一个 实例对象。 在Qt系统中,控件(widget)是 层层嵌套 的,除了最顶层的控件,其他的控件都有父控件。 几个函数 函数mo…...
人工智能赋能管理系统,如何实现智能化决策?
随着信息技术的飞速发展,人工智能(AI)已经成为推动各行各业变革的重要力量。在企业管理领域,人工智能技术的引入为管理系统的智能化决策提供了强有力的支持。本文将深入探讨人工智能如何赋能管理系统,实现智能化决策&a…...
【深度学习新浪潮】DeepSeek近期的技术进展及未来动向
一、近期技术进展 模型迭代与性能提升 DeepSeek-V3-0324版本更新:2025年3月24日发布,作为V3的小版本升级,参数规模达6850亿,采用混合专家(MoE)架构,激活参数370亿。其代码能力接近Claude 3.7,数学推理能力显著提升,且在开源社区(如Hugging Face)上线。DeepSeek-R1模…...
存储型XSS漏洞解析
一、存储型XSS漏洞的核心原理 定义与攻击流程 存储型XSS(Stored XSS)是一种将恶意脚本永久存储在服务器端(如数据库、文件系统)的跨站脚本攻击方式。其攻击流程分为四步: 注入阶段:攻击者通过输入点&…...
Python实现 MCP 客户端调用(高德地图 MCP 服务)查询天气工具示例
文章目录 MCP 官网GithubMCP 仓库简介架构高德地图 MCP 客户端示例python-sdk 客户端java-sdk 客户端 MCP 官网 https://modelcontextprotocol.io/introduction Github python-sdk:https://github.com/modelcontextprotocol/python-sdkjava-sdk:https…...
Flink介绍——实时计算核心论文之S4论文总结
PE对象的构成与功能 我们先来看下S4是怎么抽象流式计算的。 S4将所有的计算过程抽象为一个个Processing Element(处理元素)对象,简称为PE对象。 每一个PE对象,都有四部分组成,分别是: 功能(F…...
第二十四章:Python-folium库实现中国地图绘制
一、folium库简介 hchinamap库是一个专门用于绘制中国地图的R包,它通过与Highmaps图表库的结合,提供了一种简单的方式来绘制中国及其各省市自治区的地图。虽然hchinamap库是为R语言设计的,但在Python中也可以通过类似的库(如matpl…...
云巅之上:数字文明的重构与超越
序章:算力新纪元 2024年初春,当SpaceX的星舰将首批云计算节点送入近地轨道时,地球上的数字原住民们正通过云端AI助手规划着一天的行程。这场静默的革命已悄然进入新阶段——云计算不再只是工具,而是成为数字文明的"第六元素…...
蓝桥杯高频考点——高精度(含C++源码)
高精度 前言高精度加法例题思路及代码solution 1(初阶版 40分)solution 2(完全体 AC) 高精度乘法例题思路及代码solution 1(TLE 但是代码很清晰)solution 1的问题solution 2(优化 AC)…...
程序化广告行业(52/89):程序化创意深度剖析
程序化广告行业(52/89):程序化创意深度剖析 大家好!我一直对程序化广告领域充满热情,在学习过程中发现其中有很多有趣又实用的知识。今天写这篇博客,就是希望能和大家一起学习进步,深入探索程序…...
selenium和pytessarct提取古诗文网的验证码(python爬虫)
代码实现的主要功能: 浏览器自动化控制 验证码图像获取与处理 OCR验证码识别 表单自动填写与提交 登录状态验证 异常处理与资源清理 1. 浏览器初始化与页面加载 driver webdriver.Chrome() driver.get("https://www.gushiwen.cn/user/login.aspx?fro…...
封装可拖动弹窗(vue jquery引入到html的版本)
vue cli上简单的功能,在js上太难弄了,这个弹窗功能时常用到,保存起来备用吧 备注:deepseek这个人工智障写一堆有问题的我,还老服务器繁忙 效果图: html代码: <div class"modal-mask&qu…...
JavaScript重难点突破:期约与异步函数
同步和异步 同步(Synchronous) 定义:任务按顺序依次执行,前一个任务完成前,后续任务必须等待。 特点:阻塞性执行,程序逻辑直观,但效率较低 异步(Asynchron…...
Spring事务的传播机制
目录 Spring 中事务的实现编程式事务(了解即可):声明式事务(利用注解自动开启和提交事务):事务回滚注意事项: Spring 事务传播机制:1.Propagation.REQUIRED:7.Propagation.NESTED:Propagation.NESTED和1.Pr…...
LlamaIndex实现RAG增强:融合检索(Fusion Retrieval)与混合检索(Hybrid Search)
🧠 向所有学习者致敬! “学习不是装满一桶水,而是点燃一把火。” —— 叶芝 我的博客主页: https://lizheng.blog.csdn.net 🌐 欢迎点击加入AI人工智能社区! 🚀 让我们一起努力,共创…...
什么是向量搜索Vector Search?
🧠 向所有学习者致敬! “学习不是装满一桶水,而是点燃一把火。” —— 叶芝 我的博客主页: https://lizheng.blog.csdn.net 🌐 欢迎点击加入AI人工智能社区! 🚀 让我们一起努力,共创…...
【接口重复请求】axios通过AbortController解决页面切换过快,接口重复请求问题
处理网络请求时,我们经常会遇到需要中途取消请求的情况,比如用户在两个tab之间反复横跳的场景,如果每个接口都从头请求到结束,那必然会造成很大的服务压力。 AbortController是一个Web API,它提供了一个信号对象&…...
GitHub与Gitee各是什么?它们的区别与联系是什么?
李升伟 整理 GitHub 介绍 GitHub 是一个基于 Git 的代码托管平台,主要用于版本控制和协作开发。它支持多人协作,提供代码托管、问题跟踪、代码审查、项目管理等功能。GitHub 是全球最大的开源社区,许多知名开源项目都在此托管。 主要功能&…...
OpenCV图像形态学:原理、操作与应用详解
一、引言 图像形态学(Image Morphology)是图像处理领域的一个重要分支,它基于集合论、格论、拓扑学和随机函数理论,主要用于分析和处理图像的几何结构。形态学操作通过特定的结构元素(Structuring Element)…...
ubuntu git cola gui
直接的方法, samba, win 里用 tortoiseSVN 需要先在命令行,运行 git 命令,看到操作提示, 按照提示做 然后右键看 git diff 其它的方法 linux下可视化git工具git-cola安装与使用(HTTP方式)_git…...
RTX5080 安装torch,torchvision ,torchaudio 指南
一、前置准备 5080 显卡 是sm120 架构,只有torch的preview版本可以使用,而且该版本仅支持cuda12.8. 请你放弃下载以及使用低版本cuda cudnn torch 的想法。 请你学习conda 创建环境,激活环境,在虚拟环境里使用pip ,…...
ubuntu开发mcu环境
# 编辑 vim或者vscode # 编译 arm-none-eabi # 烧写 openocd 若是默认安装,会在/usr/share/openocd/scripts/{interface,target} 有配置接口和目标版配置 示例: openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg 启动后,会…...
《UNIX网络编程卷1:套接字联网API》第5章 TCP客户服务器程序示例
《UNIX网络编程卷1:套接字联网API》第5章 TCP客户/服务器程序示例 5.1 本章目标与示例程序概述 本章通过一个完整的TCP回射(Echo)客户/服务器程序,深入解析TCP套接字编程的核心流程与关键问题。示例程序的功能为:客户…...
花洒洗澡完毕并关闭后过段时间会突然滴水的原因探究
洗澡完毕后的残留水 在洗澡的过程中,我们通常会使用到大量的水。这些水会通过花洒管子到达花洒顶喷流出。由于大顶喷花洒的喷头较大,关闭后里面的存水会更多。 气压失衡后的滴水 当花洒关闭后,内部的水管和花洒头中仍存有一定量的水。由于…...
子组件使用:visible.sync=“visible“进行双向的绑定导致该弹窗与其他弹窗同时显示的问题
问题描述:最近写代码时遇到了一个问题:点击A弹窗后关闭,继续点击B弹窗,这时会同时弹窗A、B两个弹窗。经过排查后发现在子组件定义时使用了:visible.sync"visible"属性进行双向的数据绑定 <template> <el-dial…...
TTL 值 | 在 IP 协议、ping 工具及 DNS 解析中的作用
注:本文为 “TTL” 相关文章合辑。 未整理去重。 如有内容异常,请看原文。 TTL 值的意义 2007-10-18 11:33:17 TTL 是 IP 协议包中的一个值,用于标识网络路由器是否应丢弃在网络中停留时间过长的数据包。数据包可能因多种原因在一定时间内…...
代码调试:VS调试实操
1.什么是BUG? BUG原意是“虫子”,在计算机领域是指未被发现的错误,又叫程序漏洞 2.什么是调试? 当你在写完代码时需要去找代码中的问题,这个过程就叫调试 我们必须承认有这个问题并且去修复问题,可以透…...
IGMP(Internet Group Management Protocol)与组播技术深度解析
一、组播技术核心概念 1. 组播 vs 单播/广播 传输类型目标地址网络负载典型应用场景单播单一明确IP随接收者数量线性增长网页浏览、文件下载广播全网段(如255.255.255.255)强制全网设备处理ARP请求、DHCP发现组播D类地址(224.0.0.0~239.255…...
JWT(JSON Web Token)
目录 一 JWT简单介绍 二、JWT 的组成结构 1 Header(头部) 2 Payload(载荷) 三、JWT 工作原理 好文分享 session、cookie、token 详解_token session cookie-CSDN博客 一 JWT简单介绍 概念:是一种开放标准&#…...
深入理解多线程编程:从基础概念到实战应用
二进制信号量:线程同步的基础 什么是二进制信号量? 二进制信号量是一种特殊的信号量,其值只能是0或1。它是最简单的线程同步机制之一,常用于线程间的简单协调。 #include <semaphore.h>sem_t sem; // 声明二进制信号量 se…...
【STM32设计】基于STM32的智能门禁管理系统(指纹+密码+刷卡+蜂鸣器报警)(代码+资料+论文)
本课题为基于单片机的智能门禁系统,整个系统由AS608指纹识别模块,矩阵键盘,STM32F103单片机,OLED液晶,RFID识别模块,继电器,蜂鸣器等构成,在使用时,用户可以录入新的指纹…...
【MVP 和 MVVM 相比 MVC 有哪些优化点?】
MVP 和 MVVM 相比 MVC 的优化及原因 1. MVC 的痛点 在传统 MVC 模式中: 视图(View)和模型(Model)直接交互:View 可能直接监听 Model 的变化(如观察者模式),导致耦合。…...
蓝桥云客 刷题统计
刷题统计 问题描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 a 道题目,周六和周日每天做 b 道题目。请你帮小明计算,按照计划他将在第几天实现做题数大于等于 n 题? 输入格式 输入一行包含三个整数 a, b 和 …...
【28BYJ-48】STM32同时驱动4个步进电机,支持调速与正反转
资料下载:待更新。。。。 先驱动起来再说,干中学!!! 1、实现功能 STM32同时驱动4个步进电机,支持单独调速与正反转控制 需要资源:16个任意IO口1ms定时器中断 目录 资料下载:待更…...
【第十三届“泰迪杯”数据挖掘挑战赛】【2025泰迪杯】【代码篇】A题解题全流程(持续更新)
【第十三届“泰迪杯”数据挖掘挑战赛】【2025泰迪杯】【代码篇】A题解题全流程(持续更新) 环境配置: 显存>24GBPyTorch 2.3.0Python 3.12(ubuntu22.04)CUDA 12.1autoDL服务器平台,(好处:可以分享镜像&…...
迅为RK3568开发板驱动开发指南helloworld驱动实验-驱动的基本框架
Linux 驱动的基本框架主要由模块加载函数,模块卸载函数,模块许可证声明,模块参数,块导出符号,模块作者信息等几部分组成,其中模块参数,模块导出符号,模块作者信息是选的部分…...
Spring Boot 3.4.3 基于 JSqlParser 和 MyBatis 实现自定义数据权限
前言 在企业级应用中,数据权限控制是保证数据安全的重要环节。本文将详细介绍如何在 Spring Boot 3.4.3 项目中结合 JSqlParser 和 MyBatis 实现灵活的数据权限控制,通过动态 SQL 改写实现多租户、部门隔离等常见数据权限需求。 一、环境准备 确保开发环境满足以下要求: …...
软件工程面试题(二十三)
1、public class Test {public static void add(Integer i){int val=i.intValue(); val+=3; i=new Integer(val); } public static void main(String[] args) {Integer i=new Integer(0); add(i); System.out.println(i.intValue());...
spring boot 集成redis 中RedisTemplate 、SessionCallback和RedisCallback使用对比详解,最后表格总结
对比详解 1. RedisTemplate 功能:Spring Data Redis的核心模板类,提供对Redis的通用操作(如字符串、哈希、列表、集合等)。使用场景:常规的Redis增删改查操作。特点: 支持序列化配置(如String…...
leetcode-热题100(3)
leetcode-74-搜索二维矩阵 矩阵最后一列升序排序,在最后一列中查找第一个大于等于target的元素 然后在该元素所在行进行二分查找 bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target) {int n matrixSize;int m matrixColSize[0];in…...
【大模型系列篇】大模型基建工程:使用 FastAPI 构建 SSE MCP 服务器
今天我们将使用FastAPI来构建 MCP 服务器,Anthropic 推出的这个MCP 协议,目的是让 AI 代理和你的应用程序之间的对话变得更顺畅、更清晰。FastAPI 基于 Starlette 和 Uvicorn,采用异步编程模型,可轻松处理高并发请求,尤…...
基于大模型预测风湿性心脏病二尖瓣病变的多维度诊疗研究报告
目录 一、引言 1.1 研究背景与意义 1.2 研究目的与创新点 二、大模型技术概述 2.1 大模型的原理与架构 2.2 在医疗领域的应用现状 三、术前评估与预测 3.1 患者数据收集与分析 3.1.1 临床数据收集 3.1.2 影像数据处理 3.2 大模型预测模型建立 3.2.1 数据预处理 3.…...
5.模型训练-毕设篇
vgg: base_model_vgg13 models.vgg13(pretrainedTrue) base_model_vgg13.classifier[-1] nn.Linear(4096, num_classes) base_model_vgg13.to(device)(b_img_rgb.to(device)).shapebase_model_vgg13 models.vgg13(pretrainedTrue) 作用:加载预训练的…...
[物联网iot]对比WIFI、MQTT、TCP、UDP通信协议
第一步:先理解最基础的关系(类比快递) 假设你要给朋友寄快递: Wi-Fi:相当于“公路和卡车”,负责把包裹从你家运到快递站。 TCP/UDP:相当于“快递公司的运输规则”。 TCP:顺丰快递&…...
【含文档+PPT+源码】基于Python的股票数据可视化及推荐系统的设计与实现
项目介绍 本课程演示的是一款基于Python的股票数据可视化及推荐系统的设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Python学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行…...