OpenCDA代码学习笔记(1)——CARLA-SUMO联合仿真demo

2023-10-27

本文主要记录一下自己最近学习开源项目OpenCDA代码的笔记。简而言之,该项目用Python实现了全栈式自动驾驶算法的开发,也实现了CARLA-SUMO的联合仿真(该部分参考了CARLA官方给出的联合仿真实例代码)。学习该项目代码的主要目的是为了能够与现有的MARL开源算法库pymarl2结合,然后测试自己开发的算法。本文第一部分先介绍一下OpenCDA的主要文件结构,项目中类的定义及相关关系,以及总结官方文档中进行自定义算法植入customization的思路。第二部分主要对其中的DEMO: platoon_joining2lanefree_cosim进行具体的代码分析。本文所涉及的CARLA和SUMO traci的接口函数都可以在官网中查到。

以思维导图(树状图)的方式记录看代码的过程真是非常高效,也是受这篇博客(pymarl代码讲解)的启发。本文中完整的思维导图文件欢迎从我的github repo自取。

1. 主要文件结构、类定义、植入自定义算法

主要文件结构

OpenCDA的主要文件结构就是根目录下的opencda,其中assets包含了各类测试用例的地图文件或对应SUMO中的.net.xml.rou.xml文件等;co_simulation文件夹中的sumo_integration对应CARLA 0.9.11中的Co-simulation部分中同名的文件夹;core文件夹非常重要,包含了从感知到决策规划的所有模块,此外还实现了地图管理等功能;customize文件夹中包含了一些自定义的算法,例如yolov5模型的导入就在customize/ml_libs中;最后,scenario_testing文件夹包含了OpenCDA所有的测试用demo源文件(.yaml.py文件),包含了ScenarioManagerscenario_testing/utils/sim_api.py和联合仿真中的CoScenarioManagerscenario_testing/utils/cosim_api.py

OpenCDA
├── docs  # documents of opencda, no need to pay attention.
├── opencda
│   ├── assests  # customized map and sumo xml package.
│   ├── co_simulation  # source codes for sumo background traffic generation.
│   ├── core  # the core part of the code
│   │   └── actutation # implementation of control algorithms
│   │   ├── application # implementation of cooperative driving applications
│   │   ├── common # base class and communication class for cavs
│   │   ├── map # HDMap manager
│   │   ├── plan # planning algorithms
│   │   └── sensing # perception and localization algorithms.
│   ├── customize # where the users put their customized algorithm to replace the default modules
│   ├── scenario_testing # where all scenario testing scripts and yaml files exist
│   │   └── config_yaml # the yaml file defining the testing scenarios
│   │   ├── evluations # evluation scripts for different modules' performance
│   │   ├── utils # utility functions to construct scenarios based on given yaml files.
├── scripts  # installation scripts
├── tests  # unit tests

类定义、植入自定义算法

OpenCDA中的类结构见下图所示,其中最顶层的类是ScenarioManager和从之继承的CoScenarioManager(用于某个具体测试样例场景的管理);前者用于只用CARLA的仿真任务,后者用于CARLA-SUMO的联合仿真任务,类的定义代码路径见上文所述。定义了ScenarioManagerCoScenarioManager之后,针对某个具体任务(比如联合仿真中的DEMO是platoon merging),调用该类下的方法create_platoon_managercreate_vehicle_manager分别创建PlatooningManagerVehicleManager,前者是根据车队中包含的车辆数为其中每一辆车都构造一个VehicleManager,而VehicleManager类中又包含了感知,定位等相关任务的管理器类,详细的可以参考OpenCDA的官方文档。本文的第二部分将借助联合仿真DEMO中的代码对这些类中具体的属性和方法进行记录。

另外,OpenCDA也提供了用户植入自定义算法的接口,把自定义的算法模块加入到路径opencda/customize/...并利用inheritance重写默认算法即可,主要就是两个方法,一个是update_information,一个是run_step。之后,将自定义的模块导入到VehicleManager类中。

2. OpenCDA中CARLA-SUMO联合仿真DEMO

A. 实现的任务及代码整体框架

这一部分记录联合仿真DEMO中具体的代码实现,对应scenario_testing/中的platoon_joining2lanefree_cosim.py文件和同名的yaml文件。这一部分的记录形式主要是思维导图配合解释性的文字。首先,先了解一下该DEMO的具体任务:在SUMO控制的交通流下,辅路行驶的CAV(Connected and Autonomous Vehicle)将汇入行驶在主路,由四辆CAVs组成的车队(其中CAVs由 CARLA控制),最终形成新的车队驶往目的地。这一任务又可以分为两个子任务,第一个是单CAV汇入主路,第二是加入原先的车队。此外,在仿真中,CAVs被标记为蓝色,对应CARLA中的lincoln车型(blueprint为vehicle.lincoln.mkz2017),SUMO交通流中的车辆被标记为白色,在CARLA中类型随机。该DEMO的输出包括两部分:1)运动学相关(速度,加速度,TTC);2)定位相关(x,y坐标,yaw angle, 对应的误差)。

接下来是代码整体框架及对应的函数。根目录下的opencda.py中的main()包括了以下步骤:1)找到运行时命令行中的场景参数所对应的py文件和配置yaml文件;2)运行测试文件中对应的run_scenario()函数。下图首先给出run_scenario()中所需要的参数,一类参数对应选择哪一类场景opt,另一类参数对应选择某个场景后,该场景本身的参数config_yamlrun_scenario()函数又包含了三个主要步骤:1)初始化类和相关变量;2)开启循环,其中包括CoScenarioManager.tick()函数,该函数的作用类似于强化学习中的env.step(),设置CARLA中的spectator,最后分别对platoon和single CAV运行一步;3)构造evaluation manager用以记录实验结果,并最终销毁CARLA中的actor结束程序。

B. 初始化部分

首先记录run_scenario()中的初始化部分的框架,第一步,将上文中提到的yaml文件转化为dictionary类型,之后构建CavWorld类的一个实例,目的是为了存储所用车辆的信息和在联合仿真中用到的sumo-carla ID关系的dictionary。接下来找到测试用例所使用的SUMO配置文件(.sumocfg)和对应的OpenDrive文件(.xodr),并将其输入给CoScenarioManager类的实例构造。构建该实例的过程不仅包含了CoScenarioManager的初始化,还包含了其父类ScenarioManager的初始化。实例化之后,调用ScenarioManager中的create_platoon_managercreate_vehicle_manager方法分别构造车队成员的VehicleManager和单CAV的VehicleManager。初始化的最后构建EvaluationManager的实例,并设置好spectator和spectator_vehicle用于监测雷达点云和相机的输出。

B.1. CoScenarioManager类的实例化

介绍完初始化部分的整体框架后,对其中CoScenarioManager类的实例化进行记录。首先对其父类ScenarioManager进行实例化,其主要负责在CARLA中生成车辆。具体而言,在初始化相关变量和设置随机种子之后构造carla.Client()。如果使用的是自定义的xodr地图(该DEMO使用的是自定义OpenDrive地图),则用CARLA中的APIcarla.Client.generate_opendrive_world()导入地图,该函数对应的函数是opencda/scenario_testing/utils/customized_map_api中的load_customized_world。对于不使用自定义OpenDrive地图的情况,直接使用carla.Client.load_world('town_name')即可。接下来对CARLA服务器进行一些设定,其中包括设置同步模式和天气,分别对应设置carla.World.get_settings().sychronous_mode,将天气参数传给carla.World.set_weather()


CoScenarioManager类的初始化主要对SUMO仿真器和相关参数进行配置(见下图),其包括以下几个步骤:1)相关dictionaries的初始化;2)配置SUMO启动相关的参数(例如port, host, gui等),并对SumoSimulation类进行初始化,构建实例(该类对应的文件路径是opencda/co_simulation/sumo_integration/sumo_simulation.py);3)SUMO-CARLA的ID mapping;4)设置BridgeHelper类中的相关属性(blueprint library和地图网络相关的offset),该类对应的文件路径是:opencda/co_simulation/sumo_integration/bridge_helper.py

B.2. 构造VehicleManager

CoScenarioManager这一主要类初始化完成之后,则要为每个车队成员和单CAV构建VehicleManager。对每个车队成员VehicleManager的构建包括了对blueprint,spawn point,color,任务目标地点等变量的定义,详细过程见下图。

单CAVVehicleManager的构造流程与上文车队成员类似,但多出来了一步是要利用PlatooningPlugin.set_platoon()对其当前的车队状态进行标记。

C. 仿真循环部分

本节主要对仿真循环部分的CoScenarioManager.tick()和run step部分进行记录(整体框架见下图)。前者主要包含两部分,其一是将由SUMO车流控制生成的车辆同步到CARLA中,其二是将CARLA中CAVs对应生成到SUMO中,形成一个闭环。

后者则主要对应于PlatooningManager.update_information()PlatooningManager.run_step()两个方法。这两个方法又包含了VehicleManager.update_info()VehicleManager.run_step(),这两个方法与单CAV的方法等价。

C.1. CoScenarioManager.tick()

CoScenarioManager.tick()的作用就相当于RL环境中常见的step函数功能。先来看下SUMO同步到CARLA的具体步骤,如下图所示:


第一步先调用SumoSimulation.tick()方法,该方法用traci.simulationStep()接口将SUMO,和其中的信号灯运行一步。之后利用traci.simulation.getDepartedIDList()traci.simulation.getArrivedIDList()获取当前交通流下的车辆ID和已经到达目的地的车辆ID。第二步,将SUMO中的车辆在CARLA中生成,具体步骤包括:1)在SUMO中订阅对应车辆ID的具体信息(订阅需要利用SUMO中预先定义好的整数值,见SUMO官方doc即可);2)使用traci.vehicle.getSubscriptionResults(id)获取订阅的相关信息;3)获取该车辆在CARLA中的对应blueprint(随机),利用BridgeHelper.get_carla_transform()方法获取CARLA中对应的transform,并调用CoScenarioManager.spawn_actor()方法对该车辆进行生成(主要使用carla.command.SpawnActorcarla.command.SetSimulatPhysics指令);4)最后,将CARLA中生成的车辆ID复制到CoScenarioManager.sumo2carla_ids 字典中。

接下来介绍CARLA同步到SUMO的具体步骤,流程见下图:

主要步骤有:1)调用carla.World.tick();2)更新相关的数据结构;3)将CARLA中生成的CAVs同步生成到SUMO中,其中包括用carla.World.get_actor()获取CARLA中的车辆信息,获取车辆类型信息,用SumoSimulation.spawn_actor()将该车辆在SUMO中生成,并用SumoSimulation.subscribe()订阅其相关信息。4)销毁掉已经到达目的地的CARLA CAVs;5)更新相关数据结构,字典CoScenarioManager.carla2sumo_ids;6)基于CARLA中的信息更新SUMO中交通流的信息。

C.2. Run Step部分

整体框架

run step的主要步骤就是两个循环,第一个循环构造PlatooningManager,其中最主要的两个函数是update_information()run_step(),在这两个函数的内部会分别调用VehicleManagerupdate_info()run_step()方法。第二个则是为单CAV构造VehicleManager,最主要的两个函数是update_info()run_step(),这两个函数与PlatooningManager中的流程是完全等价的。

车队管理器PlatooningManager

下图是第一个循环的主要框架,每一个车队一开始由4辆车组成,每一辆车对应的车辆管理器VehicleManager要对核心方法进行调用update_info()run_step()。接下来分别对这两个方法的主要逻辑进行记录。

首先是车辆管理器中的update_info方法,其主要目的就是调用感知和定位模块以提取ego vehicle及周围车辆的信息。其可以分为以下几个步骤:1)定位,获取ego的速度(ego_spd)和位姿(ego_pos),如果定位模块没被激活,则直接从CARLA服务器获取速度和位姿,否则利用GNSS和卡尔曼滤波进行定位。2)目标检测:DEMO中没有启用YOLO5和LIDAR进行融合目标检测,而是直接利用CARLA服务器中的相关信息,DEMO中只是用了前向相机;3)更新MapManager中的位姿信息,调用MapManager.update_information()方法;4)更新V2XManager中ego的速度和位姿信息,调用V2XManager.update_info(ego_pos, ego_spd),主要目的就是获取ego车辆周围的车辆,并更新PlatooningPlugin中的速度与位姿信息;5)更新PlatooningBehaviorAgent,该类继承于BehaviorAgent,其中的详细逻辑见下文;6)更新ControlManager(PID控制器,文件路径为:opencda/core/actuation/pid_controller.py),将速度和位姿传入控制器,并判断是否采用动态调整PID参数的机制(DEMO中没有采用动态调整PID参数的机制)。

关于PlatooningBehaviorAgent.update_information()函数的具体细节见下图:


第二个核心函数是VehicleManager.run_step()方法,基本框架如下图:

其包含1)MapManager.run_step(),如果激活的话使用rasterization,此DEMO并没有激活该功能。2)最核心的部分:PlatooningBehaviorAgent.run_step()。其输入是目标速度,输出是目标速度和目标位姿(或者称之为waypoint),其主要逻辑就是处理以下几种cases:

  • 判断车辆是否是CDA模式
  • 单CAV不断搜索要加入的车队
  • 要汇入车队的车辆选择汇入并行驶到meeting point
  • 要汇入车队的车辆选择汇入并已经准备好汇入
  • 要汇入车队的车辆从后方汇入
  • 要汇入车队的车辆从前方汇入
  • 处理领队车辆的行为
  • 维持状态和open gap状态


3)调用ControlManager.run_step(),输入是目标速度和waypoint,输出是控制指令,其类型为carla.VehicleControl。其Controller.run_step(target_speed, waypoint) 逻辑是首先处理紧急停车的情况,之后进行水平和纵向控制,最终进行加速度和转角的clipping操作,将其限定在预先设定的范围内。

单CAV

单CAV所调用的核心方法在platoon情况下都有涉及,所以这里只记录一下单CAV的大致框架。其框架与上文类似,不一样的地方在于需要每一步对单CAV是否加入车队进行检查。如果车辆还没有加入车队,则依次调用VehicleManager.update_info()VehicleManager.run_step()

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

OpenCDA代码学习笔记(1)——CARLA-SUMO联合仿真demo 的相关文章

  • Python中Shift和Caps Lock的状态

    我正在使用 Python 2 5 编写 TkInter 应用程序 我需要找出大写锁定和 Shift 键的状态 true 或 false 我在整个网络上进行了搜索 但找不到解决方案 Tkinter 中的键盘事件可能很棘手 我建议您按顺序查看以
  • pygame中物体的速度?

    我正在编写一个简单的 pygame 程序 仅包含在屏幕上移动一个框 盒子移动得很快 我想知道如何控制速度 在我的代码中 更新后的位置移动了 1 而不是更小 因为如果数字不是整数 就会使事情变得更加复杂 import os sys impor
  • 根据 cron 规范计算下一个计划时间

    在给定当前时间和 cron 规范的情况下 计算事件下一次运行时间的有效方法是什么 我正在寻找 每分钟循环检查是否符合规范 以外的东西 规格示例可能是 每月1日 15日15 01 每小时整点的 10 20 30 40 50 分钟 Python
  • Python setup.py 运行 shell 脚本

    我需要在创建 Python 包时在 sdist 阶段运行我自己的脚本 我写了以下脚本 你知道更好的方法吗 您能否推荐更好的一个或链接到 setuptools 的官方文档 其中已解释了这一时刻 import subprocess import
  • Python 中的文字可以被覆盖吗?

    找不到更好的方式来表达标题 请随时更正 我对 Python 还很陌生 目前正在尝试该语言 我注意到所有内置类型都不能与其他成员一起扩展 例如 我想添加一个each方法到list类型 但那是不可能的 我意识到它是出于效率原因而设计的 并且大多
  • 十六进制转储文件的Pythonic方式

    我的问题很简单 有什么方法可以用 bash 命令以 Python 方式进行编码吗 hexdump e 2 1 02x file dat 显然 不使用 os popen 或任何快捷方式 编辑 虽然我没有明确指定 但如果代码在 Python3
  • 清理嵌套的 Try/Excepts

    我刚刚编写了一段代码 令我印象深刻的是 它的嵌套程度远远超过了最佳值 我想了解如何改进其风格 特别是使其更符合 扁平优于嵌套 的原则 for app in apps if app split 1 0 zc only look for cro
  • 没有实例的 Django Formset

    In this http docs djangoproject com en dev topics forms modelforms inline formsetsDjango Doc 解释了如何创建一个表单集 该表单集允许您编辑属于特定作
  • 如何从sqlalchemy中的select语句创建新表?

    我正在使用 sqlalchemy 的核心功能来编写一些抽象层 该层本身需要能够从 select 语句创建表 示例代码 metadata MetaData bind engine table Table table name metadata
  • 无法为从图中加载的张量变量赋值

    我已经训练了一个模型并保存了它 现在 我试图了解权重扰动如何影响其准确性 因此我需要修改权重变量中保存的值 本质上会为其添加一些噪声 问题是加载它们后我无法为它们分配值 我正在使用 TensorFlow 版本 1 2 1 来训练和加载模型
  • dulwich - 从远程仓库身份验证克隆

    我找不到有关此主题的任何资源 我需要通过提供用户名和密码从私有存储库进行克隆 然而 当它们作为关键字参数提供给 dulwich get client from path 时 会出现错误 提示 未知参数 用户名 这似乎是一件简单的事情 但我找
  • 为什么 argparse 给我一个列表中的列表?

    我刚刚注意到 argparse 中的一个行为让我困惑 我猜我以前从未将它用于愚蠢的文件列表 import argparse parser argparse ArgumentParser parser add argument multi a
  • 安装/编译 pylzma(lzma python 绑定)

    我已经向作者提出了这个问题website http www joachim bauch de projects pylzma comment page 1 comment 5211 但我想我也可以在这里问 我一直在尝试使用以下设置安装 py
  • 为什么 python 的 __init__ 函数没有 return 语句,即使它是一个函数

    这可能是一个愚蠢的问题 但我很想知道答案 根据官方文件 init 不需要return语句 有什么特殊原因会这样吗 gt gt gt class Complex def init self realpart imagpart self r r
  • python pandas 将两行或多行文本合并为一行

    我有包含文本数据的数据框 如下所示 name address number 1 Bob bob No 56 2 gmail com 3 Carly email protected cdn cgi l email protection No
  • 在 django 中运行普通 sql 查询时如何获取字段名称

    在我的 django 视图之一中 我使用纯 sql 不是 orm 查询数据库并返回结果 sql select from foo bar cursor connection cursor cursor execute sql rows cur
  • Flask 从线程中删除会话变量

    我尝试实施投票系统 它的工作原理是这样的 如果用户对帖子进行投票 我会在会话变量中记录其临时状态 已投票 已加星标等 如果当前用户在我将结果保存到临时表之前尚未投票 用户可以在 5 分钟内更改投票 5 分钟后 结果将使用线程永久写入数据库
  • Pylance 无法在 VSCode Jupyter 笔记本中工作

    皮兰斯工作于 py files 但不适用于 Jupyter ipynb笔记本 我尝试保存 ipynb 同样的问题 如何在我的笔记本中启用 Pylance 警告 Jupyter 扩展似乎不支持 Pylance 我提交这个问题就是为了解决这个缺
  • 如何使用 python 绘制具有两个斜率的线

    我使用下面的代码绘制一条具有两个斜率的线 如图所示 斜率应该在一定限制 limit 5 之后下降 我正在使用矢量化方法来设置斜率值 还有其他方法来设置斜率值 有人可以帮助我吗 import matplotlib pyplot as plt
  • “from-import”是否执行整个模块?

    好的 所以我知道from import与 完全 相同import 但这显然不是因为命名空间的填充方式不同 我的问题主要是因为我有一个utils我的应用程序中的每个其他模块都使用一个或两个函数的模块 我正在努力合并标准库logging模块 据

随机推荐

  • 家用可燃气浓度报警控制系统

    使用软件Keil uVision4 proteus 8 Professions 一 研究目的 计算机控制系统通常具有精度高 速度快 存储容量大和有逻辑判断功能等特点 因此可以实现高级复杂的控制方法 获得快速精密的控制效果 在控制系统中 为了
  • 9i 11g linux,Linux平台下Oracle9i/10g/11gR1IO-Fencing的hangcheck-timer模块说

    Linux 平台下Oracle 9i 10g 11gR1 IO Fencing 的hangcheck timer 模块说明 Hangcheck timer 是Linux 提供的一个内核级的IO Fenc 一 官网的说明 参考MOS 9i 1
  • apt-get的用法

    apt命令用法 packagename指代为软件包的名称 apt get update 在修改 etc apt sources list或 etc apt preferences之後运行该命令 此外您需要定期运行这一命令以确保您的 软件包列
  • Go语言学习5-切片类型

    切片类型 引言 1 切片 1 1 类型表示法 1 2 值表示法 1 3 属性和基本操作 1 4 切片使用的复杂用法 总结 引言 上篇我们介绍了 Go语言的数组类型 本篇将介绍Go语言的切片类型 主要如下 1 切片 切片可以看作是对数组的一种
  • SSD系列算法原理讲解----(1)SSD系列算法介绍(主干网络、多尺度Feature Map预测)(笔记)

    SSD系列算法原理介绍 SSD算法介绍 Single Shot MultiBox Detector One stage方法 Wei Liu在ECCV 2016提出 直接回归目标类别和位置 不同尺度的特征图上进行检测 端到端的训练 图像的分辨
  • 前端面试问答题(1)

    1 页面从输入URL到页面加载显示完成 这个过程中都发生了什么 1 输入域名地址 2 发送至DNS服务器并获得域名对应的WEB服务器IP地址 3 与WEB服务器建立TCP连接 4 服务器的永久重定向响应 从 http example com
  • Java 代理模式详解

    前言 在软件设计过程中 我们经常需要对对象或系统进行扩展 但是在开发过程中 直接修改现有代码可能会带来一些风险和不良影响 比如破坏原有的稳定性 影响已有的功能等 而代理模式则是通过引入一个代理对象来间接访问目标对象 从而为应用程序提供额外的
  • linux入门基础

    这本阿里P8撰写的算法笔记 再次推荐给大家 身边不少朋友学完这本书最后加入大厂 Github 疯传 史上最强悍 阿里大佬 LeetCode刷题手册 开放下载了 一 虚拟机的管理 概念 虚拟机 Virtual Machine 指通过软件模拟的
  • MySQL分片高可用集群之Cobar部署使用

    MySQL分片高可用集群之Cobar部署使用 2015 10 22 14 58 47 标签 mysql 高可用 分片 cobar 分库 原创作品 允许转载 转载时请务必以超链接形式标明文章 原始出处 作者信息和本声明 否则将追究法律责任 h
  • Chatgpt4来了,测试小姐姐实测,在失业的边缘疯狂试探~

    GPT 4是OpenAI于2023年3月发布的最新人工智能模型 它是继GPT 3 5之后的又一次重大突破 它的核心技术是基于Transformer的自回归语言模型 它使用了大量的无标注数据进行预训练 学习了自然语言和其他模态之间的通用表示和
  • 关于传递函数的频率响应和低通滤波器

    关于传递函数的频率响应和低通滤波器 参考资料 动态系统的建模与分析 9 一阶系统的频率响应 低通滤波器 Matlab Simulink分析 哔哩哔哩 bilibili 以前关于这部分只是知道了而已 并没有用MATLAB认真试验过 这里借着D
  • moxa Nport配置tcp/udp实现数据发送和回传(补充数据接收错乱处理方法)

    moxa Nport配置tcp udp实现数据发送和回传 记一次吐血经历 目的 现有一内网环境需要连外网进行钉钉推送 开始使用串口连接实体电脑的方式实现 现需要撤除实体电脑 故选用串口服务器的方式实现 型号是moxa NPort5150 网
  • snipaste截图软件滚动截图_Windows截图:snipaste & QQ截图工具

    介绍Windows端两款便利的截图工具 snipaste 和 QQ截图工具 我在使用snipaste的时候 最常用的是三个功能 截图 截图并自动复制到剪切板 贴图 使用QQ截图工具 须后台运行QQ 的时候 最常用的是 OCR文本识别 标注
  • 1.4 CNN的崛起

    目录 四 CNN的崛起 4 1 SVM vs NN 4 2 ILSVRC 4 2 1 分类任务描述 4 2 2 SVM 的覆灭 4 3 CNN 的发展 四 CNN的崛起 4 1 SVM vs NN 虽然反向传播算法的提出 使得神经网络的学习
  • python内点法_最优化问题(三) 之 外点法(罚函数法)

    1 基本概念 罚函数法又称乘子法 是将约束优化问题转换为无约束最优化问题的方法之一 其基本思想就是通过在原始的目标函数中添加一个障碍函数 也可以理解成惩罚函数 来代替约束条件中的不等式约束 如果当前解不满足约束条件 就在目标项上加上一个正向
  • Web前端——CSS复习(3.27-3.31)

    1 渐变 1 什么是渐变 渐变 指的是两种或多种颜色之间的平滑过渡 aa 渐变可指定多个中间颜色值 色标 bb 渐变可以用在任何适用背景图片的地方 线性渐变 径向渐变 重复渐变 2 渐变语法 在CSS3中使用background image
  • leetcode shell题解

    195 Tenth Line print just the 10th line of a file sed n 10 10p file txt 194 Transpose File For example if file txt has t
  • 主流编程语言介绍

    目录 前言 一 编程语言作用 1 1 Python 1 2 Java 1 3 JavaScript 1 4 Go 1 5 PHP 二 Python和PHP学习网站 2 1 菜鸟教程 2 2 W3school 总结 前言 主流的编程语言有很多
  • 流图(程序图)表示程序的控制流——>McCabe方法度量程序空间复杂度

    McCabe方法 McCabe方法根据程序控制流的复杂程度定量度量程序的复杂程度 这样度量出的结果称为程序的环形复杂度 为了突出表现程序的控制流 人们通常使用流图 也称程序图 1 流图 所谓流图实质上是 退化了的 程序流程图 它仅仅描绘程序
  • OpenCDA代码学习笔记(1)——CARLA-SUMO联合仿真demo

    本文主要记录一下自己最近学习开源项目OpenCDA代码的笔记 简而言之 该项目用Python实现了全栈式自动驾驶算法的开发 也实现了CARLA SUMO的联合仿真 该部分参考了CARLA官方给出的联合仿真实例代码 学习该项目代码的主要目的是