Copy disabled (too large)
Download .txt
Showing preview only (57,077K chars total). Download the full file to get everything.
Repository: guardstrikelab/carla_apollo_bridge
Branch: master
Commit: b0c2e088fb70
Files: 74
Total size: 111.0 MB
Directory structure:
gitextract_4hezuig_/
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── discussion.md
│ │ ├── feature_request.md
│ │ ├── proposal.md
│ │ └── question.md
│ ├── pull_request_template.md
│ ├── scripts/
│ │ └── automerge.py
│ └── workflows/
│ └── issue_bot.yaml
├── .gitignore
├── .pre-commit-config.yaml
├── .pylintrc
├── LICENSE
├── README.md
├── carla_bridge/
│ ├── __init__.py
│ ├── actor/
│ │ ├── actor.py
│ │ ├── ego_vehicle.py
│ │ ├── pseudo_actor.py
│ │ ├── spectator.py
│ │ ├── static.py
│ │ ├── traffic.py
│ │ ├── traffic_participant.py
│ │ ├── vehicle.py
│ │ └── walker.py
│ ├── carla_api/
│ │ ├── carla-0.9.14-py3.7-linux-x86_64.egg
│ │ ├── controller.py
│ │ ├── global_route_planner.py
│ │ ├── local_planner.py
│ │ └── misc.py
│ ├── config/
│ │ ├── objects.json
│ │ └── settings.yaml
│ ├── core/
│ │ ├── actor_factory.py
│ │ ├── carla_spawn_objects.py
│ │ ├── carmera_info.py
│ │ ├── geometry.py
│ │ ├── node.py
│ │ └── spawn_object_param.py
│ ├── install.sh
│ ├── main.py
│ ├── map/
│ │ ├── carla_town01/
│ │ │ ├── base_map.txt
│ │ │ ├── routing_map.txt
│ │ │ └── sim_map.txt
│ │ ├── carla_town02/
│ │ │ ├── base_map.txt
│ │ │ ├── routing_map.txt
│ │ │ └── sim_map.txt
│ │ ├── carla_town04/
│ │ │ ├── base_map.txt
│ │ │ ├── routing_map.txt
│ │ │ └── sim_map.txt
│ │ ├── carla_town07/
│ │ │ ├── base_map.txt
│ │ │ ├── routing_map.txt
│ │ │ └── sim_map.txt
│ │ └── carla_town10hd/
│ │ ├── base_map.txt
│ │ ├── routing_map.txt
│ │ └── sim_map.txt
│ ├── refined_controller/
│ │ ├── control_conf.pb.txt
│ │ ├── mpc_controller.cc
│ │ └── mpc_controller.h
│ ├── requirements.txt
│ ├── sensor/
│ │ ├── camera.py
│ │ ├── gnss.py
│ │ ├── imu.py
│ │ ├── lidar.py
│ │ ├── object_sensor.py
│ │ ├── radar.py
│ │ ├── sensor.py
│ │ └── traffic_lights_sensor.py
│ └── utils/
│ ├── logurus.py
│ └── transforms.py
├── carla_scripts/
│ ├── carla-compose.yml
│ ├── docker_run_carla.sh
│ └── stop_carla.sh
└── docs/
├── GettingStarted.md
├── RefinedController.md
└── deployment_introduction.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
*.whl filter=lfs diff=lfs merge=lfs -text
*.egg filter=lfs diff=lfs merge=lfs -text
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Report a bug in carla_apollo_bridge
title: ''
labels: kind/bug
assignees: ''
---
## Describe the bug
<!-- A clear and concise description of what the bug is -->
### In what area(s)?
<!-- Remove the '> ' to select -->
> /area runtime
> /area operator
> /area placement
> /area docs
> /area test-and-release
## Steps to Reproduce the Problem
<!-- How can a maintainer reproduce this issue (be detailed) -->
Steps to reproduce the behavior:
1. Run this command in the container to start Dreamview: `./scripts/bootstrap.sh`
2. Start the bridge and spawn the ego vehicle: `python carla_cyber_bridge/bridge.py` and `python carla_spawn_objects/carla_spawn_objects.py`
3. Start a co-simulation: `Open apollo client: http://localhost:8888`
4. Other operate...
## Expected Behavior
<!-- Briefly describe what you expect to happen -->
## Actual Behavior
<!-- Briefly describe what is actually happening -->
## Screenshots or Video
<!-- If applicable, add screenshots to help explain your problem -->
## Environments (please complete the following information):
- System info: [use `uname --all` on LInux]
- Cuda version [use `nvidia-smi`]
- Docker version [use `docker -v`]
- Docker-compose version [use `docker-compose -v`]
- Versions of other dependent software...
## Additional context
<!-- Add any other context about the problem here -->
## What version of carla_apollo_bridge?
<!-- Delete all but your choice -->
> 0.2.x
> 0.1.x
> edge: output of `git describe --dirty`
## Release Note
<!-- How should the fix for this issue be communicated in our release notes? It can be populated later. -->
<!-- Keep it as a single line. Examples: -->
<!-- RELEASE NOTE: **ADD** New feature in carla_apollo_bridge. -->
<!-- RELEASE NOTE: **FIX** Bug in runtime. -->
<!-- RELEASE NOTE: **UPDATE** Runtime dependency. -->
RELEASE NOTE:
================================================
FILE: .github/ISSUE_TEMPLATE/discussion.md
================================================
---
name: Discussion
about: Start a discussion for carla_apollo_bridge
title: ''
labels: kind/discussion
assignees: ''
---
<!-- Please visit https://bbs.carla.org.cn/ to ask questions and troubleshoot. For all other design discussions please continue. -->
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature Request
about: Create a Feature Request for carla_apollo_bridge
title: ''
labels: kind/enhancement
assignees: ''
---
<!-- If you need to report a security issue please visit https://bbs.carla.org.cn/ -->
## In what area(s)?
<!-- Remove the '> ' to select -->
> /area runtime
> /area operator
> /area placement
> /area docs
> /area test-and-release
## Describe the feature
<!-- Please also discuss possible business value -->
## Release Note
<!-- How should this new feature be announced in our release notes? It can be populated later. -->
<!-- Keep it as a single line. Examples: -->
<!-- RELEASE NOTE: **ADD** New feature in carla_apollo_bridge. -->
<!-- RELEASE NOTE: **FIX** Bug in runtime. -->
<!-- RELEASE NOTE: **UPDATE** Runtime dependency. -->
RELEASE NOTE:
================================================
FILE: .github/ISSUE_TEMPLATE/proposal.md
================================================
---
name: Proposal
about: Create a technical proposal for carla_apollo_bridge
title: ''
labels: kind/proposal
assignees: ''
---
<!-- If you need to report a security issue please visit https://bbs.carla.org.cn/ask -->
## In what area(s)?
<!-- Remove the '> ' to select -->
> /area runtime
> /area operator
> /area placement
> /area docs
> /area test-and-release
## Describe the proposal
<!-- Please use this for a concrete design proposal for functionality. -->
<!-- If you just want to request a new feature and discuss the possible business value, create a Feature Request. -->
================================================
FILE: .github/ISSUE_TEMPLATE/question.md
================================================
---
name: Question
about: Ask a question about carla_apollo_bridge
title: ''
labels: kind/question
assignees: ''
---
**Note:** If you have a general support question and are looking for a quicker response, please checkout our discord channel for answers from the community:
https://bbs.carla.org.cn/ask
## In what area(s)?
<!-- Remove the '> ' to select -->
> /area runtime
> /area operator
> /area placement
> /area docs
> /area test-and-release
## Ask your question here
================================================
FILE: .github/pull_request_template.md
================================================
# Description
<!--
Please explain the changes you've made.
-->
## Issue reference
<!--
We strive to have all PR being opened based on an issue, where the problem or feature have been discussed prior to implementation.
-->
Please reference the issue this PR will close: #_[issue number]_
## Checklist
Please make sure you've completed the relevant tasks for this PR, out of the following list:
* [ ] Code compiles correctly
* [ ] Created/updated tests
* [ ] Unit tests passing
* [ ] End-to-end tests passing
[//]: # (* [ ] Extended the documentation / Created issue in the https://github.com/guardstrikelab/docs/ repo: guardstrikelab/docs#_[issue number]_)
[//]: # (* [ ] Specification has been updated / Created issue in the https://github.com/guardstrikelab/docs/ repo: guardstrikelab/docs#_[issue number]_)
[//]: # (* [ ] Provided sample for the feature / Created issue in the https://github.com/guardstrikelab/docs/ repo: guardstrikelab/docs#_[issue number]_)
================================================
FILE: .github/scripts/automerge.py
================================================
#
# Copyright 2021 The carla_apollo_bridge Authors
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This script automerges PRs in carla_apollo_bridge.
import os
from github import Github
g = Github(os.getenv("GITHUB_TOKEN"))
repo = g.get_repo(os.getenv("GITHUB_REPOSITORY"))
maintainers = [m.strip() for m in os.getenv("MAINTAINERS").split(',')]
def fetch_pulls(mergeable_state, labels = {'automerge'}):
return [pr for pr in repo.get_pulls(state='open', sort='created') \
if (not pr.draft) and pr.mergeable_state == mergeable_state and \
(not labels or len(labels.intersection({l.name for l in pr.labels})) > 0)]
def is_approved(pr):
approvers = [r.user.login for r in pr.get_reviews() if r.state == 'APPROVED' and r.user.login in maintainers]
return len([a for a in approvers if repo.get_collaborator_permission(a) in ['admin', 'write']]) > 0
# First, find a PR that can be merged
pulls = fetch_pulls('clean')
print(f"Detected {len(pulls)} open pull requests in {repo.name} to be automerged.")
merged = False
for pr in pulls:
if is_approved(pr):
# Merge only one PR per run.
print(f"Merging PR {pr.html_url}")
try:
pr.merge(merge_method='squash')
merged = True
break
except:
print(f"Failed to merge PR {pr.html_url}")
if len(pulls) > 0 and not merged:
print("No PR was automerged.")
# Now, update all PRs that are behind, regardless of automerge label.
pulls = fetch_pulls('behind', {'automerge', 'autoupdate'})
print(f"Detected {len(pulls)} open pull requests in {repo.name} to be updated.")
for pr in pulls:
print(f"Updating PR {pr.html_url}")
try:
pr.update_branch()
except:
print(f"Failed to update PR {pr.html_url}")
pulls = fetch_pulls('dirty')
print(f"Detected {len(pulls)} open pull requests in {repo.name} to be automerged but are in dirty state.")
for pr in pulls:
print(f"PR is in dirty state: {pr.html_url}")
print("Done.")
================================================
FILE: .github/workflows/issue_bot.yaml
================================================
name: Close inactive issues
on:
schedule:
- cron: "30 1 * * *"
jobs:
close-issues:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v5
with:
days-before-issue-stale: 30
days-before-issue-close: 14
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
days-before-pr-stale: -1
days-before-pr-close: -1
repo-token: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# log
*.log.*
# C extensions
#*.so
# Distribution / packaging
.Python
#build/
develop-eggs/
# dist/
downloads/
# eggs/
# .eggs/
#lib/
#lib64/
#parts/
sdist/
#var/
#wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
# *.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
#.tox/
#.nox/
#.coverage
#.coverage.*
.cache
nosetests.xml
coverage.xml
#*.cover
#*.py,cover
.hypothesis/
.pytest_cache/
# Translations
#*.mo
#*.pot
# Django stuff:
*.log
local_settings.py
#db.sqlite3
#db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
#.env
#.venv
#env/
#venv/
#ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
================================================
FILE: .pre-commit-config.yaml
================================================
repos:
- repo: https://kgithub.com/PyCQA/isort.git
rev: 5.12.0 # Use the revision sha / tag you want to point at
hooks:
- id: isort
args: ["--profile", "black"]
- repo: https://kgithub.com/psf/black
rev: 23.7.0
hooks:
- id: black
# - repo: https://gitlab.com/pycqa/flake8
# rev: 4.0.1
# hooks:
# - id: flake8
# language_version: python3
- repo: https://kgithub.com/pre-commit/mirrors-pylint
rev: 56b3cb4
hooks:
- id: pylint
args:
- --rcfile=.pylintrc
================================================
FILE: .pylintrc
================================================
# This Pylint rcfile contains a best-effort configuration to uphold the
# best-practices and style described in the Google Python style guide:
# https://google.github.io/styleguide/pyguide.html
#
# Its canonical open-source location is:
# https://google.github.io/styleguide/pylintrc
[MASTER]
# Files or directories to be skipped. They should be base names, not paths.
ignore=third_party
# Files or directories matching the regex patterns are skipped. The regex
# matches against base names, not paths.
ignore-patterns=
# Pickle collected data for later comparisons.
persistent=no
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
# Use multiple processes to speed up Pylint.
jobs=4
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=abstract-method,
apply-builtin,
arguments-differ,
attribute-defined-outside-init,
backtick,
bad-option-value,
basestring-builtin,
buffer-builtin,
c-extension-no-member,
consider-using-enumerate,
cmp-builtin,
cmp-method,
coerce-builtin,
coerce-method,
delslice-method,
div-method,
duplicate-code,
eq-without-hash,
execfile-builtin,
file-builtin,
filter-builtin-not-iterating,
fixme,
getslice-method,
global-statement,
hex-method,
idiv-method,
implicit-str-concat,
import-error,
import-self,
import-star-module-level,
inconsistent-return-statements,
input-builtin,
intern-builtin,
invalid-str-codec,
locally-disabled,
long-builtin,
long-suffix,
map-builtin-not-iterating,
misplaced-comparison-constant,
missing-function-docstring,
metaclass-assignment,
next-method-called,
next-method-defined,
no-absolute-import,
no-else-break,
no-else-continue,
no-else-raise,
no-else-return,
no-init, # added
no-member,
no-name-in-module,
no-self-use,
nonzero-method,
oct-method,
old-division,
old-ne-operator,
old-octal-literal,
old-raise-syntax,
parameter-unpacking,
print-statement,
raising-string,
range-builtin-not-iterating,
raw_input-builtin,
rdiv-method,
reduce-builtin,
relative-import,
reload-builtin,
round-builtin,
setslice-method,
signature-differs,
standarderror-builtin,
suppressed-message,
sys-max-int,
too-few-public-methods,
too-many-ancestors,
too-many-arguments,
too-many-boolean-expressions,
too-many-branches,
too-many-instance-attributes,
too-many-locals,
too-many-nested-blocks,
too-many-public-methods,
too-many-return-statements,
too-many-statements,
trailing-newlines,
unichr-builtin,
unicode-builtin,
unnecessary-pass,
unpacking-in-except,
useless-else-on-loop,
useless-object-inheritance,
useless-suppression,
using-cmp-argument,
wrong-import-order,
xrange-builtin,
zip-builtin-not-iterating,
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text
# Tells whether to display a full report or only the messages
reports=no
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=
[BASIC]
# Good variable names which should always be accepted, separated by a comma
good-names=main,_
# Bad variable names which should always be refused, separated by a comma
bad-names=
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Include a hint for the correct naming format with invalid-name
include-naming-hint=no
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
property-classes=abc.abstractproperty,cached_property.cached_property,cached_property.threaded_cached_property,cached_property.cached_property_with_ttl,cached_property.threaded_cached_property_with_ttl
# Regular expression matching correct function names
function-rgx=^(?:(?P<exempt>setUp|tearDown|setUpModule|tearDownModule)|(?P<camel_case>_?[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_?[a-z][a-z0-9_]*))$
# Regular expression matching correct variable names
variable-rgx=^[a-z][a-z0-9_]*$
# Regular expression matching correct constant names
const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
# Regular expression matching correct attribute names
attr-rgx=^_{0,2}[a-z][a-z0-9_]*$
# Regular expression matching correct argument names
argument-rgx=^[a-z][a-z0-9_]*$
# Regular expression matching correct class attribute names
class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
# Regular expression matching correct inline iteration names
inlinevar-rgx=^[a-z][a-z0-9_]*$
# Regular expression matching correct class names
class-rgx=^_?[A-Z][a-zA-Z0-9]*$
# Regular expression matching correct module names
module-rgx=^(_?[a-z][a-z0-9_]*|__init__)$
# Regular expression matching correct method names
method-rgx=(?x)^(?:(?P<exempt>_[a-z0-9_]+__|runTest|setUp|tearDown|setUpTestCase|tearDownTestCase|setupSelf|tearDownClass|setUpClass|(test|assert)_*[A-Z0-9][a-zA-Z0-9_]*|next)|(?P<camel_case>_{0,2}[A-Z][a-zA-Z0-9_]*)|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=(__.*__|main|test.*|.*test|.*Test)$
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=10
[TYPECHECK]
# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=
[FORMAT]
# Maximum number of characters on a single line.
max-line-length=120
# TODO(https://github.com/PyCQA/pylint/issues/3352): Direct pylint to exempt
# lines made too long by directives to pytype.
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=(?x)(
^\s*(\#\ )?<?https?://\S+>?$|
^\s*(from\s+\S+\s+)?import\s+.+$)
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=yes
# Maximum number of lines in a module
max-module-lines=99999
# String used as indentation unit. The internal Google style guide mandates 2
# spaces. Google's externaly-published style guide says 4, consistent with
# PEP 8. Here, we use 2 spaces, for conformity with many open-sourced Google
# projects (like TensorFlow).
indent-string=' '
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=TODO
[STRING]
# This flag controls whether inconsistent-quotes generates a warning when the
# character used as a quote delimiter is used inconsistently within a module.
check-quote-consistency=yes
[VARIABLES]
# Tells whether we should check for unused import in __init__ files.
init-import=no
# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_)
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,_cb
# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six,six.moves,past.builtins,future.builtins,functools
[LOGGING]
# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging,absl.logging,tensorflow.io.logging
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=4
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
[SPELLING]
# Spelling dictionary name. Available dictionaries: none. To make it working
# install python-enchant package.
spelling-dict=
# List of comma separated words that should not be checked.
spelling-ignore-words=
# A path to a file that contains private dictionary; one word per line.
spelling-private-dict-file=
# Tells whether to store unknown words to indicated private dictionary in
# --spelling-private-dict-file option instead of raising a message.
spelling-store-unknown-words=no
[IMPORTS]
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,
TERMIOS,
Bastion,
rexec,
sets
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=enchant, absl
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
[CLASSES]
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,
__new__,
setUp
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,
_fields,
_replace,
_source,
_make
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls,
class_
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=builtins.StandardError,
builtins.Exception,
builtins.BaseException
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
<a name="readme-top"></a>
<!-- PROJECT LOGO -->
<br />
<div align="center">
<!-- <a href="https://github.com/othneildrew/Best-README-Template">
<img src="images/logo.png" alt="Logo" width="80" height="80">
</a> -->
<h1 align="center">Carla Apollo Bridge</h1>
<p align="center">
<b>Carla & Apollo Co-simulation</b>
<!-- <br /> -->
<!-- <a href="https://github.com/othneildrew/Best-README-Template"><strong>Explore the docs »</strong></a>
<br /> -->
<br />
<a href="https://github.com/guardstrikelab/apollo_carla">View Demo</a>
·
<a href="https://github.com/guardstrikelab/apollo_carla/issues">Report Bug</a>
·
<a href="https://github.com/guardstrikelab/apollo_carla/pulls">Request Feature</a>
<br>
</p>
</div>
<!-- TABLE OF CONTENTS -->
<!-- <details>
<summary>Table of Contents</summary>
<ol>
<li>
<a href="#about-the-project">About Carla Apollo Bridge</a>
<ul>
<li><a href="#built-with">Built With</a></li>
</ul>
</li>
<li>
<a href="#getting-started">Getting Started</a>
<ul>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#installation">Installation</a></li>
</ul>
</li>
<li><a href="#usage">Usage</a></li>
<li><a href="#roadmap">Roadmap</a></li>
<li><a href="#contributing">Contributing</a></li>
<li><a href="#license">License</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="#acknowledgments">Acknowledgments</a></li>
</ol>
</details> -->





[](https://www.tickgit.com/browse?repo=github.com/guardstrikelab/carla_apollo_bridge)




[](https://github.com/guardstrikelab/carla_apollo_bridge/blob/master/LICENSE)

<!-- ABOUT THE PROJECT -->
## About
This project aims to provide a data and control bridge for the communication between Carla and Apollo. It was tested with [Carla 0.9.14](https://github.com/carla-simulator/carla/tree/0.9.14) and the [Apollo v8.0.0](https://github.com/ApolloAuto/apollo/tree/v8.0.0) (v8.0.0)

<!-- GETTING STARTED -->
## Getting Started
Please refer to [Getting Started](docs/GettingStarted.md)
<!-- Premium -->
## Premium
If you want to delve deeper into using Apollo for simulation in Carla, you can refer to the following information.
We ([SYNKROTRON](https://synkrotron.ai/)) offer a range of advanced features, including:
### HIL cluster management
Supporting remote scheduling of VTD HIL, Dspace HIL, task management, data import and export, simulation logs, and simulation report retrieval.
### SIL simulation capability
Supporting perceptual algorithm testing, regulatory testing, and end-to-end testing of perceptual regulation. The algorithm supports Apollo/ROS/Simulink/C++ access.
### Scenario library management
Unified management of scene libraries, classification, grouping, and labeling of scene libraries, support for automatic push of scene libraries to HIL SIL simulation software for simulation testing.
### Sensor model management
Supporting the definition of sensor internal and external parameters for different vehicle models and versions, and supporting the deployment of sensor configurations for a certain vehicle model to the HIL SIL simulation platform.
### Scenario building
Supporting different departments and teams to build scenarios through UI and code, making it easy for testing departments to use.
### Analyze and evaluate
Supporting the testing department to uniformly write testing rules in the cloud for backup.
### Cloud simulation task creation
With the freedom to select scenarios and evaluation rules, sensor models, and tested objects (algorithm software or domain controllers) to initiate simulation tasks, and automatically send back test reports.
### Task management
Supporting different departments and teams to conduct simulation tasks, scenario building tasks, evaluation rule writing tasks, algorithm code submission tasks, etc. based on different business permissions.
## Contact
If you wish to try it out, please contact us through one of the following methods.
- email: xiaofei@synkrotron.ai
- email: leili@synkrotron.ai
<!-- CONTRIBUTING -->
## Contribution
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contribution you make is **greatly appreciated**.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".
Don't forget to give the project a star! Thanks again!
1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## License
Distributed under the Apache-2.0 License. See `LICENSE` for more information.
## Acknowledgments
This work is based on the following open-source projects:
* [Apollo](https://github.com/ApolloAuto/apollo)
* [Carla Apollo Bridge](https://github.com/AuroAi/carla_apollo_bridge)
* [Carla Apollo](https://github.com/casper-auto/carla-apollo)
<p align="right">(<a href="#readme-top">back to top</a>)</p>
================================================
FILE: carla_bridge/__init__.py
================================================
================================================
FILE: carla_bridge/actor/actor.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2018-2019 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
#
"""
Base Classes to handle Actor objects
"""
from carla_bridge.actor.pseudo_actor import PseudoActor
import carla_bridge.utils.transforms as trans
class Actor(PseudoActor):
"""
Generic base class for all carla actors
"""
def __init__(self, uid, name, parent, node, carla_actor):
"""
Constructor
:param uid: unique identifier for this object
:type uid: int
:param name: name identiying this object
:type name: string
:param parent: the parent of this
:type parent: bridge.Parent
:param node: node-handle
:type node: CyberNode
:param carla_actor: carla actor object
:type carla_actor: carla.Actor
"""
super().__init__(uid=uid, name=name, parent=parent, node=node)
self.carla_actor = carla_actor
self.carla_actor_id = carla_actor.id
def destroy(self):
"""
Function (override) to destroy this object.
Remove the reference to the carla.Actor object.
:return:
"""
self.carla_actor = None
super().destroy()
def get_current_cyber_pose(self):
"""
Function to provide the current ROS pose
:return: the ROS pose of this actor
:rtype: geometry_msgs.msg.Pose
"""
return trans.carla_transform_to_cyber_pose(self.carla_actor.get_transform())
def get_current_cyber_transform(self):
"""
Function to provide the current ROS pose
:return: the ROS pose of this actor
:rtype: geometry_msgs.msg.Pose
"""
return trans.carla_transform_to_cyber_transform(
self.carla_actor.get_transform()
)
def get_current_cyber_twist_rotated(self):
"""
Function to provide the current ROS twist rotated
:return: the ROS twist of this actor
"""
return trans.carla_velocity_to_cyber_twist(
self.carla_actor.get_velocity(),
self.carla_actor.get_angular_velocity(),
self.carla_actor.get_transform().rotation,
)
def get_current_cyber_twist(self):
"""
Function to provide the current ROS twist
:return: the ROS twist of this actor
"""
return trans.carla_velocity_to_cyber_twist(
self.carla_actor.get_velocity(), self.carla_actor.get_angular_velocity()
)
def get_current_cyber_accel(self):
"""
Function to provide the current ROS accel
:return: the ROS twist of this actor
"""
return trans.carla_acceleration_to_cyber_accel(
self.carla_actor.get_acceleration()
)
def get_id(self):
"""
Getter for the carla_id of this.
:return: unique carla_id of this object
:rtype: int64
"""
return self.carla_actor_id
def set_carla_actor(self, carla_actor):
self.carla_actor = carla_actor
================================================
FILE: carla_bridge/actor/ego_vehicle.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2018-2020 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
#
"""
Classes to handle Carla vehicles
"""
import math
import numpy as np
import carla
from carla import VehicleControl, Location
from modules.common_msgs.localization_msgs.localization_pb2 import LocalizationEstimate, LocalizationStatus
from modules.common_msgs.chassis_msgs.chassis_pb2 import Chassis
from modules.common_msgs.control_msgs.control_cmd_pb2 import ControlCommand
from modules.common_msgs.transform_msgs.transform_pb2 import TransformStamped, TransformStampeds
from carla_bridge.actor.vehicle import Vehicle
import carla_bridge.utils.transforms as trans
class EgoVehicle(Vehicle):
"""
Vehicle implementation details for the ego vehicle
"""
def __init__(self, uid, name, parent, node, carla_actor, world):
"""
Constructor
:param uid: unique identifier for this object
:type uid: int
:param name: name identiying this object
:type name: string
:param parent: the parent of this
:param node: node-handle
:type node: CompatibleNode
:param carla_actor: carla actor object
:type carla_actor: carla.Actor
"""
super(EgoVehicle, self).__init__(uid=uid,
name=name,
parent=parent,
node=node,
carla_actor=carla_actor)
self.world = world
self.vehicle_info_writed = False
self.vehicle_control_override = False
self.vehicle_loc_set = False
self.right_turn_ratio = 0.7
self.left_turn_ratio = 0.85
self.vehicle_chassis_writer = node.new_writer(
"/apollo/canbus/chassis",
Chassis,
qos_depth=10)
self.vehicle_pose_writer = node.new_writer(
"/apollo/localization/pose",
LocalizationEstimate,
qos_depth=10)
self.localization_status_writer = node.new_writer(
"/apollo/localization/msf_status",
LocalizationStatus,
qos_depth=10)
self.tf_writer = node.new_writer("/tf", TransformStampeds)
self.control_reader = node.new_reader(
"/apollo/control",
ControlCommand,
lambda data: self.control_command_updated(data, manual_override=False))
def get_tf_msg(self):
pose = self.get_current_cyber_pose()
tf_msg = TransformStamped()
tf_msg.header.timestamp_sec = self.node.get_time()
tf_msg.header.frame_id = 'world'
tf_msg.child_frame_id = 'localization'
tf_msg.transform.translation.x = pose.position.x
tf_msg.transform.translation.y = pose.position.y
tf_msg.transform.translation.z = pose.position.z
tf_msg.transform.rotation.qx = pose.orientation.qx
tf_msg.transform.rotation.qy = pose.orientation.qy
tf_msg.transform.rotation.qz = pose.orientation.qz
tf_msg.transform.rotation.qw = pose.orientation.qw
return tf_msg
def send_vehicle_msgs(self):
"""
send messages related to vehicle status
:return:
"""
vehicle_chassis = Chassis()
vehicle_chassis.header.timestamp_sec = self.node.get_time()
vehicle_chassis.header.frame_id = 'ego_vehicle'
vehicle_chassis.engine_started = True
vehicle_chassis.speed_mps = self.get_vehicle_speed_abs(self.carla_actor)
vehicle_chassis.throttle_percentage = self.carla_actor.get_control().throttle * 100.0
vehicle_chassis.brake_percentage = self.carla_actor.get_control().brake * 100.0
vehicle_chassis.steering_percentage = -self.carla_actor.get_control().steer * 100.0
vehicle_chassis.parking_brake = self.carla_actor.get_control().hand_brake
vehicle_chassis.driving_mode = Chassis.DrivingMode.COMPLETE_AUTO_DRIVE
self.vehicle_chassis_writer.write(vehicle_chassis)
transform = self.carla_actor.get_transform()
spectator = self.world.get_spectator()
spectator.set_transform(
carla.Transform(transform.location + carla.Location(x=-10 * math.cos(math.radians(transform.rotation.yaw)),
y=-10 * math.sin(math.radians(transform.rotation.yaw)),
z=15),
carla.Rotation(pitch=-45, yaw=transform.rotation.yaw)))
tf_stampeds = TransformStampeds()
tf_stampeds.transforms.append(self.get_tf_msg())
self.tf_writer.write(tf_stampeds)
self.write_localization()
def write_localization(self):
transform = self.carla_actor.get_transform()
linear_vel = self.carla_actor.get_velocity()
angular_vel = self.carla_actor.get_angular_velocity()
accel = self.carla_actor.get_acceleration()
localization_estimate = LocalizationEstimate()
localization_estimate.header.timestamp_sec = self.node.get_time()
localization_estimate.header.frame_id = "novatel"
cyber_pose = trans.carla_transform_to_cyber_pose(transform)
localization_estimate.pose.position.x = cyber_pose.position.x
localization_estimate.pose.position.y = cyber_pose.position.y
localization_estimate.pose.position.z = cyber_pose.position.z
localization_estimate.pose.orientation.qx = cyber_pose.orientation.qx
localization_estimate.pose.orientation.qy = cyber_pose.orientation.qy
localization_estimate.pose.orientation.qz = cyber_pose.orientation.qz
localization_estimate.pose.orientation.qw = cyber_pose.orientation.qw
cyber_twist = trans.carla_velocity_to_cyber_twist(linear_vel, angular_vel)
localization_estimate.pose.linear_velocity.x = cyber_twist.linear.x
localization_estimate.pose.linear_velocity.y = cyber_twist.linear.y
localization_estimate.pose.linear_velocity.z = cyber_twist.linear.z
localization_estimate.pose.angular_velocity.x = cyber_twist.angular.x
localization_estimate.pose.angular_velocity.y = cyber_twist.angular.y
localization_estimate.pose.angular_velocity.z = cyber_twist.angular.z
cyber_line_accel = trans.carla_acceleration_to_cyber_accel(accel)
localization_estimate.pose.linear_acceleration.x = cyber_line_accel.linear.x
localization_estimate.pose.linear_acceleration.y = cyber_line_accel.linear.y
localization_estimate.pose.linear_acceleration.z = cyber_line_accel.linear.z
roll, pitch, yaw = trans.cyber_quaternion_to_cyber_euler(cyber_pose.orientation)
enu_accel_velocity = trans.n2b(
pitch,
roll,
yaw,
np.array(
[
cyber_line_accel.linear.x,
cyber_line_accel.linear.y,
cyber_line_accel.linear.z,
]
),
)
localization_estimate.pose.linear_acceleration_vrf.x = enu_accel_velocity[0, 0]
localization_estimate.pose.linear_acceleration_vrf.y = enu_accel_velocity[0, 1]
localization_estimate.pose.linear_acceleration_vrf.z = enu_accel_velocity[0, 2]
enu_angular_velocity = trans.n2b(
pitch,
roll,
yaw,
np.array(
[cyber_twist.angular.x, cyber_twist.angular.y, cyber_twist.angular.z]
),
)
localization_estimate.pose.angular_velocity_vrf.x = enu_angular_velocity[0, 0]
localization_estimate.pose.angular_velocity_vrf.y = enu_angular_velocity[0, 1]
localization_estimate.pose.angular_velocity_vrf.z = enu_angular_velocity[0, 2]
localization_estimate.pose.euler_angles.x = (
transform.rotation.roll / 180 * math.pi
)
localization_estimate.pose.euler_angles.y = (
transform.rotation.pitch / 180 * math.pi
)
localization_estimate.pose.euler_angles.z = (
transform.rotation.yaw / 180 * math.pi
)
localization_estimate.pose.heading = math.radians(-transform.rotation.yaw)
self.vehicle_pose_writer.write(localization_estimate)
def update(self, frame, timestamp):
"""
Function (override) to update this object.
On update ego vehicle calculates and sends the new values for VehicleControl()
:return:
"""
self.send_vehicle_msgs()
super(EgoVehicle, self).update(frame, timestamp)
def destroy(self):
"""
Function (override) to destroy this object.
Terminate ROS readers
Finally forward call to super class.
:return:
"""
super(EgoVehicle, self).destroy()
def control_command_override(self, enable):
"""
Set the vehicle control mode according to cyber topic
"""
self.vehicle_control_override = enable.data
def control_command_updated(self, cyber_vehicle_control, manual_override):
"""
Receive a ControlCommand msg and send to CARLA
This function gets called whenever a ControlCommand is received.
If the mode is valid (either normal or manual), the received ROS message is
converted into carla.VehicleControl command and sent to CARLA.
This bridge is not responsible for any restrictions on velocity or steering.
It's just forwarding the ROS input to CARLA
:param manual_override: manually override the vehicle control command
:param cyber_vehicle_control: current vehicle control input received via ROS
:type cyber_vehicle_control: ControlCommand
:return:
"""
if manual_override == self.vehicle_control_override:
vehicle_control = VehicleControl()
vehicle_control.throttle = cyber_vehicle_control.throttle / 100.0
vehicle_control.brake = cyber_vehicle_control.brake / 100.0
rate = cyber_vehicle_control.steering_rate / 100.0
if cyber_vehicle_control.steering_target < 0:
cyber_vehicle_control.steering_target = (
cyber_vehicle_control.steering_target * self.right_turn_ratio
)
else:
cyber_vehicle_control.steering_target = (
cyber_vehicle_control.steering_target * self.left_turn_ratio
)
vehicle_control.steer = -cyber_vehicle_control.steering_target / 100.0
vehicle_control.hand_brake = cyber_vehicle_control.parking_brake
vehicle_control.reverse = cyber_vehicle_control.gear_location == Chassis.GearPosition.GEAR_REVERSE
self.carla_actor.apply_control(vehicle_control)
def enable_autopilot_updated(self, enable_auto_pilot):
"""
Enable/disable auto pilot
:param enable_auto_pilot: should the autopilot be enabled?
:type enable_auto_pilot: BoolResult
:return:
"""
self.carla_actor.set_autopilot(enable_auto_pilot.value)
@staticmethod
def get_vector_length_squared(carla_vector):
"""
Calculate the squared length of a carla_vector
:param carla_vector: the carla vector
:type carla_vector: carla.Vector3D
:return: squared vector length
:rtype: float64
"""
return carla_vector.x * carla_vector.x + \
carla_vector.y * carla_vector.y + \
carla_vector.z * carla_vector.z
@staticmethod
def get_vehicle_speed_squared(carla_vehicle):
"""
Get the squared speed of a carla vehicle
:param carla_vehicle: the carla vehicle
:type carla_vehicle: carla.Vehicle
:return: squared speed of a carla vehicle [(m/s)^2]
:rtype: float64
"""
return EgoVehicle.get_vector_length_squared(carla_vehicle.get_velocity())
@staticmethod
def get_vehicle_speed_abs(carla_vehicle):
"""
Get the absolute speed of a carla vehicle
:param carla_vehicle: the carla vehicle
:type carla_vehicle: carla.Vehicle
:return: speed of a carla vehicle [m/s >= 0]
:rtype: float64
"""
speed = math.sqrt(EgoVehicle.get_vehicle_speed_squared(carla_vehicle))
return speed
================================================
FILE: carla_bridge/actor/pseudo_actor.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2019 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
#
"""
Base Class to handle Pseudo Actors (that are not existing in Carla world)
"""
import numpy as np
from modules.common_msgs.basic_msgs.header_pb2 import Header
class PseudoActor(object):
"""
Generic base class for Pseudo actors (that are not existing in Carla world)
"""
def __init__(self, uid, name, parent, node):
"""
Constructor
:param uid: unique identifier for this object
:type uid: int
:param name: name identiying this object
:type name: string
:param parent: the parent of this
:type parent: bridge.PseudoActor
:param prefix: the topic prefix to be used for this actor
:type prefix: string
:param node: node-handle
:type node: CyberNode
"""
self.uid = uid
self.name = name
self.parent = parent
self.node = node
if self.uid is None:
raise TypeError("Actor ID is not set")
if self.uid > np.iinfo(np.uint32).max:
raise ValueError(
"Actor ID exceeds maximum supported value '{}'".format(self.uid)
)
def destroy(self):
"""
Function to destroy this object.
:return:
"""
self.parent = None
@staticmethod
def get_blueprint_name():
"""
Get the blueprint identifier for the pseudo sensor
:return: name
"""
raise NotImplementedError("The pseudo actor is missing a blueprint name")
def get_msg_header(self, frame_id=None, timestamp=None):
"""
Get a filled ROS message header
:return: ROS message header
:rtype: std_msgs.msg.Header
"""
header = Header()
if frame_id:
header.frame_id = frame_id
else:
header.frame_id = self.get_prefix()
if not timestamp:
timestamp = self.node.get_time()
header.timestamp_sec = timestamp
return header
def get_prefix(self):
"""
get the fully qualified prefix of object
:return: prefix
:rtype: string
"""
if self.parent is not None:
return self.parent.get_prefix() + "/" + self.name
else:
return self.name
def get_topic_prefix(self):
"""
get the topic name of the current entity.
:return: the final topic name of this object
:rtype: string
"""
return "/carla/" + self.get_prefix()
def update(self, frame, timestamp):
"""
Function to update this object. Derived classes can add code.
"""
pass
================================================
FILE: carla_bridge/actor/spectator.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2018-2019 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
#
"""
Classes to handle Carla spectator
"""
from carla_bridge.actor.actor import Actor
class Spectator(Actor):
"""
Actor implementation details for spectators
"""
def __init__(self, uid, name, parent, node, carla_actor):
"""
Constructor
:param uid: unique identifier for this object
:type uid: int
:param name: name identiying this object
:type name: string
:param parent: the parent of this
:param node: node-handle
:type node: CompatibleNode
:param carla_actor: carla actor object
:type carla_actor: carla.Actor
"""
super(Spectator, self).__init__(uid=uid,
name=name,
parent=parent,
node=node,
carla_actor=carla_actor)
================================================
FILE: carla_bridge/actor/static.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2018-2019 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
#
"""
Classes to handle Carla static obstacles
"""
from modules.common_msgs.perception_msgs.perception_obstacle_pb2 import (
PerceptionObstacle,
)
from carla_bridge.actor.traffic_participant import TrafficParticipant
class Static(TrafficParticipant):
"""
Actor implementation details for static obstacles
"""
def __init__(self, uid, name, parent, node, carla_actor):
"""
Constructor
:param uid: unique identifier for this object
:type uid: int
:param name: name identiying this object
:type name: string
:param parent: the parent of this
:type parent: bridge.Parent
:param node: node-handle
:type node: bridge.CarlaCyberBridge
:param carla_actor: carla actor object
:type carla_actor: carla.Actor
"""
self.classification = PerceptionObstacle.UNKNOWN_UNMOVABLE
super().__init__(
uid=uid, name=name, parent=parent, node=node, carla_actor=carla_actor
)
def get_classification(self):
"""
Function (override) to get classification
:return:
"""
return self.classification
================================================
FILE: carla_bridge/actor/traffic.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2018-2019 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
#
"""
Classes to handle Carla traffic objects
"""
from carla import TrafficLightState
from modules.common_msgs.perception_msgs.traffic_light_detection_pb2 import (
TrafficLight as ApolloTrafficLight,
)
from actor.actor import Actor
class Traffic(Actor):
"""
Actor implementation details for traffic objects
"""
def __init__(self, uid, name, parent, node, carla_actor):
"""
Constructor
:param uid: unique identifier for this object
:type uid: int
:param name: name identiying this object
:type name: string
:param parent: the parent of this
:type parent: bridge.Parent
:param node: node-handle
:type node: CyberNode
:param carla_actor: carla actor object
:type carla_actor: carla.Actor
"""
super().__init__(
uid=uid, name=name, parent=parent, node=node, carla_actor=carla_actor
)
class TrafficLight(Actor):
"""
Traffic implementation details for traffic lights
"""
def __init__(self, uid, name, parent, node, carla_actor):
"""
Constructor
:param uid: unique identifier for this object
:type uid: int
:param name: name identiying this object
:type name: string
:param parent: the parent of this
:type parent: bridge.Parent
:param node: node-handle
:type node: CyberNode
:param carla_actor: carla actor object
:type carla_actor: carla.TrafficLight
"""
super().__init__(
uid=uid, name=name, parent=parent, node=node, carla_actor=carla_actor
)
def get_status(self):
"""
Get the current state of the traffic light
"""
carla_state = self.carla_actor.get_state()
if carla_state == TrafficLightState.Red:
return ApolloTrafficLight.RED
elif carla_state == TrafficLightState.Yellow:
return ApolloTrafficLight.YELLOW
elif carla_state == TrafficLightState.Green:
return ApolloTrafficLight.GREEN
elif carla_state == TrafficLightState.Off:
return ApolloTrafficLight.BLACK
else:
return ApolloTrafficLight.UNKNOWN
def get_id(self):
opendrive_id = self.carla_actor.get_opendrive_id()
carla_map = self.carla_actor.get_world().get_map()
light_waypoint = carla_map.get_waypoint(self.carla_actor.get_location())
return f"signal_{light_waypoint.road_id}_{opendrive_id}"
================================================
FILE: carla_bridge/actor/traffic_participant.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2019 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
#
"""
Classes to handle Carla traffic participants
"""
import math
from modules.common_msgs.perception_msgs.perception_obstacle_pb2 import (
PerceptionObstacle,
)
from carla_bridge.actor.actor import Actor
import carla_bridge.utils.transforms as trans
class TrafficParticipant(Actor):
"""
actor implementation details for traffic participant
"""
def __init__(self, uid, name, parent, node, carla_actor):
"""
Constructor
:param uid: unique identifier for this object
:type uid: int
:param name: name identiying this object
:type name: string
:param parent: the parent of this
:type parent: bridge.Parent
:param node: node-handle
:type node: CyberNode
:param carla_actor: carla actor object
:type carla_actor: carla.Actor
"""
self.classification_age = 0
super().__init__(
uid=uid, name=name, parent=parent, node=node, carla_actor=carla_actor
)
def update(self, frame, timestamp):
"""
Function (override) to update this object.
On update vehicles send:
- tf global frame
- object message
- marker message
:return:
"""
self.classification_age += 1
super().update(frame, timestamp)
def get_object_info(self):
"""
Function to send object messages of this traffic participant.
A derived_object_msgs.msg.Object is prepared to be writed via '/carla/objects'
:return:
"""
obj = PerceptionObstacle()
# ID
obj.id = self.get_id()
# Position
carla_transform = self.carla_actor.get_transform()
obj.position.x = carla_transform.location.x
obj.position.y = -carla_transform.location.y
obj.position.z = carla_transform.location.z
# Theta
obj.theta = -math.radians(carla_transform.rotation.yaw)
# Velocity
carla_velocity = self.carla_actor.get_velocity()
obj.velocity.x = carla_velocity.x
obj.velocity.y = -carla_velocity.y
obj.velocity.z = carla_velocity.z
# Acceleration
carla_accel = self.carla_actor.get_acceleration()
obj.acceleration.x = carla_accel.x
obj.acceleration.y = -carla_accel.y
obj.acceleration.z = carla_accel.z
# Shape
obj.length = self.carla_actor.bounding_box.extent.x * 2.0
obj.width = self.carla_actor.bounding_box.extent.y * 2.0
obj.height = self.carla_actor.bounding_box.extent.z * 2.0
# Classification if available in attributes
if self.get_classification() != PerceptionObstacle.Type.UNKNOWN:
obj.type = self.get_classification()
return obj
def get_classification(self): # pylint: disable=no-self-use
"""
Function to get object classification (overridden in subclasses)
"""
return PerceptionObstacle.UNKNOWN
def get_marker_pose(self):
"""
Function to return the pose for traffic participants.
:return: the pose of the traffic participant.
:rtype: geometry_msgs.msg.Pose
"""
return trans.carla_transform_to_cyber_pose(self.carla_actor.get_transform())
================================================
FILE: carla_bridge/actor/vehicle.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2018-2019 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
#
"""
Classes to handle Carla vehicles
"""
from modules.common_msgs.perception_msgs.perception_obstacle_pb2 import (
PerceptionObstacle,
)
from carla_bridge.actor.traffic_participant import TrafficParticipant
class Vehicle(TrafficParticipant):
"""
Actor implementation details for vehicles
"""
def __init__(self, uid, name, parent, node, carla_actor):
"""
Constructor
:param uid: unique identifier for this object
:type uid: int
:param name: name identiying this object
:type name: string
:param parent: the parent of this
:type parent: bridge.Parent
:param node: node-handle
:type node: bridge.CarlaCyberBridge
:param carla_actor: carla vehicle actor object
:type carla_actor: carla.Vehicle
"""
self.classification = PerceptionObstacle.VEHICLE
if "object_type" in carla_actor.attributes:
if carla_actor.attributes["object_type"] == "car":
self.classification = PerceptionObstacle.VEHICLE
elif carla_actor.attributes["object_type"] == "bike":
self.classification = PerceptionObstacle.BICYCLE
elif carla_actor.attributes["object_type"] == "motorcycle":
self.classification = PerceptionObstacle.BICYCLE
elif carla_actor.attributes["object_type"] == "truck":
self.classification = PerceptionObstacle.VEHICLE
elif carla_actor.attributes["object_type"] == "other":
self.classification = PerceptionObstacle.UNKNOWN_MOVABLE
super().__init__(
uid=uid, name=name, parent=parent, node=node, carla_actor=carla_actor
)
def get_classification(self):
"""
Function (override) to get classification
:return:
"""
return self.classification
================================================
FILE: carla_bridge/actor/walker.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2018-2019 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
#
"""
Classes to handle Carla pedestrians
"""
from modules.common_msgs.perception_msgs.perception_obstacle_pb2 import (
PerceptionObstacle,
)
from carla_bridge.actor.traffic_participant import TrafficParticipant
class Walker(TrafficParticipant):
"""
Actor implementation details for pedestrians
"""
def __init__(self, uid, name, parent, node, carla_actor):
"""
Constructor
:param uid: unique identifier for this object
:param name: name identifying this object
:param parent: the parent of this
:param node: node-handle
:param carla_actor: carla walker actor object
"""
super().__init__(
uid=uid, name=name, parent=parent, node=node, carla_actor=carla_actor
)
# def destroy(self):
# """
# Function (override) to destroy this object.
# Terminate CyberRT readers
# Finally forward call to super class.
# :return:
# """
# super(Walker, self).destroy()
def get_classification(self):
"""
Function (override) to get classification
:return:
"""
return PerceptionObstacle.PEDESTRIAN
================================================
FILE: carla_bridge/carla_api/carla-0.9.14-py3.7-linux-x86_64.egg
================================================
[File too large to display: 27.9 MB]
================================================
FILE: carla_bridge/carla_api/controller.py
================================================
# Copyright (c) # Copyright (c) 2018-2020 CVC.
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
""" This module contains PID controllers to perform lateral and longitudinal control. """
import math
from collections import deque
import carla
import numpy as np
from carla_api.misc import get_speed
# pylint: disable=C0103
class VehiclePIDController:
"""
VehiclePIDController is the combination of two PID controllers
(lateral and longitudinal) to perform the
low level control a vehicle from client side
"""
def __init__(
self,
vehicle,
args_lateral,
args_longitudinal,
offset=0,
max_throttle=0.75,
max_brake=0.3,
max_steering=0.8,
):
"""
Constructor method.
:param vehicle: actor to apply to local planner logic onto
:param args_lateral: dictionary of arguments to set the lateral PID controller
using the following semantics:
K_P -- Proportional term
K_D -- Differential term
K_I -- Integral term
:param args_longitudinal: dictionary of arguments to set the longitudinal
PID controller using the following semantics:
K_P -- Proportional term
K_D -- Differential term
K_I -- Integral term
:param offset: If different than zero, the vehicle will drive displaced from the center line.
Positive values imply a right offset while negative ones mean a left one. Numbers high enough
to cause the vehicle to drive through other lanes might break the controller.
"""
self.max_brake = max_brake
self.max_throt = max_throttle
self.max_steer = max_steering
self._vehicle = vehicle
self._world = self._vehicle.get_world()
self.past_steering = self._vehicle.get_control().steer
self._lon_controller = PIDLongitudinalController(
self._vehicle, **args_longitudinal
)
self._lat_controller = PIDLateralController(
self._vehicle, offset, **args_lateral
)
def run_step(self, target_speed, waypoint):
"""
Execute one step of control invoking both lateral and longitudinal
PID controllers to reach a target waypoint
at a given target_speed.
:param target_speed: desired vehicle speed
:param waypoint: target location encoded as a waypoint
:return: distance (in meters) to the waypoint
"""
acceleration = self._lon_controller.run_step(target_speed)
current_steering = self._lat_controller.run_step(waypoint)
control = carla.VehicleControl()
if acceleration >= 0.0:
control.throttle = min(acceleration, self.max_throt)
control.brake = 0.0
else:
control.throttle = 0.0
control.brake = min(abs(acceleration), self.max_brake)
# Steering regulation: changes cannot happen abruptly, can't steer too much.
if current_steering > self.past_steering + 0.1:
current_steering = self.past_steering + 0.1
elif current_steering < self.past_steering - 0.1:
current_steering = self.past_steering - 0.1
if current_steering >= 0:
steering = min(self.max_steer, current_steering)
else:
steering = max(-self.max_steer, current_steering)
control.steer = steering
control.hand_brake = False
control.manual_gear_shift = False
self.past_steering = steering
return control
def change_longitudinal_pid(self, args_longitudinal):
"""Changes the parameters of the PIDLongitudinalController"""
self._lon_controller.change_parameters(**args_longitudinal)
def change_lateral_pid(self, args_lateral):
"""Changes the parameters of the PIDLongitudinalController"""
self._lon_controller.change_parameters(**args_lateral)
class PIDLongitudinalController:
"""
PIDLongitudinalController implements longitudinal control using a PID.
"""
def __init__(self, vehicle, K_P=1.0, K_I=0.0, K_D=0.0, dt=0.03):
"""
Constructor method.
:param vehicle: actor to apply to local planner logic onto
:param K_P: Proportional term
:param K_D: Differential term
:param K_I: Integral term
:param dt: time differential in seconds
"""
self._vehicle = vehicle
self._k_p = K_P
self._k_i = K_I
self._k_d = K_D
self._dt = dt
self._error_buffer = deque(maxlen=10)
def run_step(self, target_speed, debug=False):
"""
Execute one step of longitudinal control to reach a given target speed.
:param target_speed: target speed in Km/h
:param debug: boolean for debugging
:return: throttle control
"""
current_speed = get_speed(self._vehicle)
if debug:
print(f"Current speed = {current_speed}")
return self._pid_control(target_speed, current_speed)
def _pid_control(self, target_speed, current_speed):
"""
Estimate the throttle/brake of the vehicle based on the PID equations
:param target_speed: target speed in Km/h
:param current_speed: current speed of the vehicle in Km/h
:return: throttle/brake control
"""
error = target_speed - current_speed
self._error_buffer.append(error)
if len(self._error_buffer) >= 2:
_de = (self._error_buffer[-1] - self._error_buffer[-2]) / self._dt
_ie = sum(self._error_buffer) * self._dt
else:
_de = 0.0
_ie = 0.0
return np.clip(
(self._k_p * error) + (self._k_d * _de) + (self._k_i * _ie), -1.0, 1.0
)
def change_parameters(self, K_P, K_I, K_D, dt):
"""Changes the PID parameters"""
self._k_p = K_P
self._k_i = K_I
self._k_d = K_D
self._dt = dt
class PIDLateralController:
"""
PIDLateralController implements lateral control using a PID.
"""
def __init__(self, vehicle, offset=0, K_P=1.0, K_I=0.0, K_D=0.0, dt=0.03):
"""
Constructor method.
:param vehicle: actor to apply to local planner logic onto
:param offset: distance to the center line. If might cause issues if the value
is large enough to make the vehicle invade other lanes.
:param K_P: Proportional term
:param K_D: Differential term
:param K_I: Integral term
:param dt: time differential in seconds
"""
self._vehicle = vehicle
self._k_p = K_P
self._k_i = K_I
self._k_d = K_D
self._dt = dt
self._offset = offset
self._e_buffer = deque(maxlen=10)
def run_step(self, waypoint):
"""
Execute one step of lateral control to steer
the vehicle towards a certain waypoin.
:param waypoint: target waypoint
:return: steering control in the range [-1, 1] where:
-1 maximum steering to left
+1 maximum steering to right
"""
return self._pid_control(waypoint, self._vehicle.get_transform())
def _pid_control(self, waypoint, vehicle_transform):
"""
Estimate the steering angle of the vehicle based on the PID equations
:param waypoint: target waypoint
:param vehicle_transform: current transform of the vehicle
:return: steering control in the range [-1, 1]
"""
# Get the ego's location and forward vector
ego_loc = vehicle_transform.location
v_vec = vehicle_transform.get_forward_vector()
v_vec = np.array([v_vec.x, v_vec.y, 0.0])
# Get the vector vehicle-target_wp
if self._offset != 0:
# Displace the wp to the side
w_tran = waypoint.transform
r_vec = w_tran.get_right_vector()
w_loc = w_tran.location + carla.Location(
x=self._offset * r_vec.x, y=self._offset * r_vec.y
)
else:
w_loc = waypoint.transform.location
w_vec = np.array([w_loc.x - ego_loc.x, w_loc.y - ego_loc.y, 0.0])
wv_linalg = np.linalg.norm(w_vec) * np.linalg.norm(v_vec)
if wv_linalg == 0:
_dot = 1
else:
_dot = math.acos(np.clip(np.dot(w_vec, v_vec) / (wv_linalg), -1.0, 1.0))
_cross = np.cross(v_vec, w_vec)
if _cross[2] < 0:
_dot *= -1.0
self._e_buffer.append(_dot)
if len(self._e_buffer) >= 2:
_de = (self._e_buffer[-1] - self._e_buffer[-2]) / self._dt
_ie = sum(self._e_buffer) * self._dt
else:
_de = 0.0
_ie = 0.0
return np.clip(
(self._k_p * _dot) + (self._k_d * _de) + (self._k_i * _ie), -1.0, 1.0
)
def change_parameters(self, K_P, K_I, K_D, dt):
"""Changes the PID parameters"""
self._k_p = K_P
self._k_i = K_I
self._k_d = K_D
self._dt = dt
================================================
FILE: carla_bridge/carla_api/global_route_planner.py
================================================
# Copyright (c) # Copyright (c) 2018-2020 CVC.
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""
This module provides GlobalRoutePlanner implementation.
"""
import math
import carla
import networkx as nx
import numpy as np
from carla_api.local_planner import RoadOption
from carla_api.misc import vector
class GlobalRoutePlanner(object):
"""
This class provides a very high level route plan.
"""
def __init__(self, wmap, sampling_resolution):
self._sampling_resolution = sampling_resolution
self._wmap = wmap
self._topology = None
self._graph = None
self._id_map = None
self._road_id_to_edge = None
self._intersection_end_node = -1
self._previous_decision = RoadOption.VOID
# Build the graph
self._build_topology()
self._build_graph()
self._find_loose_ends()
self._lane_change_link()
def trace_route(self, origin, destination):
"""
This method returns list of (carla.Waypoint, RoadOption)
from origin to destination
"""
route_trace = []
route = self._path_search(origin, destination)
current_waypoint = self._wmap.get_waypoint(origin)
destination_waypoint = self._wmap.get_waypoint(destination)
for i in range(len(route) - 1):
road_option = self._turn_decision(i, route)
edge = self._graph.edges[route[i], route[i + 1]]
path = []
if (
edge["type"] != RoadOption.LANEFOLLOW
and edge["type"] != RoadOption.VOID
):
route_trace.append((current_waypoint, road_option))
exit_wp = edge["exit_waypoint"]
n1, n2 = self._road_id_to_edge[exit_wp.road_id][exit_wp.section_id][
exit_wp.lane_id
]
next_edge = self._graph.edges[n1, n2]
if next_edge["path"]:
closest_index = self._find_closest_in_list(
current_waypoint, next_edge["path"]
)
closest_index = min(len(next_edge["path"]) - 1, closest_index + 5)
current_waypoint = next_edge["path"][closest_index]
else:
current_waypoint = next_edge["exit_waypoint"]
route_trace.append((current_waypoint, road_option))
else:
path = (
path
+ [edge["entry_waypoint"]]
+ edge["path"]
+ [edge["exit_waypoint"]]
)
closest_index = self._find_closest_in_list(current_waypoint, path)
for waypoint in path[closest_index:]:
current_waypoint = waypoint
route_trace.append((current_waypoint, road_option))
if (
len(route) - i <= 2
and waypoint.transform.location.distance(destination)
< 2 * self._sampling_resolution
):
break
elif (
len(route) - i <= 2
and current_waypoint.road_id == destination_waypoint.road_id
and current_waypoint.section_id
== destination_waypoint.section_id
and current_waypoint.lane_id == destination_waypoint.lane_id
):
destination_index = self._find_closest_in_list(
destination_waypoint, path
)
if closest_index > destination_index:
break
return route_trace
def _build_topology(self):
"""
This function retrieves topology from the server as a list of
road segments as pairs of waypoint objects, and processes the
topology into a list of dictionary objects with the following attributes
- entry (carla.Waypoint): waypoint of entry point of road segment
- entryxyz (tuple): (x,y,z) of entry point of road segment
- exit (carla.Waypoint): waypoint of exit point of road segment
- exitxyz (tuple): (x,y,z) of exit point of road segment
- path (list of carla.Waypoint): list of waypoints between entry to exit, separated by the resolution
"""
self._topology = []
# Retrieving waypoints to construct a detailed topology
for segment in self._wmap.get_topology():
wp1, wp2 = segment[0], segment[1]
l1, l2 = wp1.transform.location, wp2.transform.location
# Rounding off to avoid floating point imprecision
x1, y1, z1, x2, y2, z2 = np.round([l1.x, l1.y, l1.z, l2.x, l2.y, l2.z], 0)
wp1.transform.location, wp2.transform.location = l1, l2
seg_dict = dict()
seg_dict["entry"], seg_dict["exit"] = wp1, wp2
seg_dict["entryxyz"], seg_dict["exitxyz"] = (x1, y1, z1), (x2, y2, z2)
seg_dict["path"] = []
endloc = wp2.transform.location
if wp1.transform.location.distance(endloc) > self._sampling_resolution:
w = wp1.next(self._sampling_resolution)[0]
while w.transform.location.distance(endloc) > self._sampling_resolution:
seg_dict["path"].append(w)
w = w.next(self._sampling_resolution)[0]
else:
seg_dict["path"].append(wp1.next(self._sampling_resolution)[0])
self._topology.append(seg_dict)
def _build_graph(self):
"""
This function builds a networkx graph representation of topology, creating several class attributes:
- graph (networkx.DiGraph): networkx graph representing the world map, with:
Node properties:
vertex: (x,y,z) position in world map
Edge properties:
entry_vector: unit vector along tangent at entry point
exit_vector: unit vector along tangent at exit point
net_vector: unit vector of the chord from entry to exit
intersection: boolean indicating if the edge belongs to an intersection
- id_map (dictionary): mapping from (x,y,z) to node id
- road_id_to_edge (dictionary): map from road id to edge in the graph
"""
self._graph = nx.DiGraph()
self._id_map = dict() # Map with structure {(x,y,z): id, ... }
self._road_id_to_edge = (
dict()
) # Map with structure {road_id: {lane_id: edge, ... }, ... }
for segment in self._topology:
entry_xyz, exit_xyz = segment["entryxyz"], segment["exitxyz"]
path = segment["path"]
entry_wp, exit_wp = segment["entry"], segment["exit"]
intersection = entry_wp.is_junction
road_id, section_id, lane_id = (
entry_wp.road_id,
entry_wp.section_id,
entry_wp.lane_id,
)
for vertex in entry_xyz, exit_xyz:
# Adding unique nodes and populating id_map
if vertex not in self._id_map:
new_id = len(self._id_map)
self._id_map[vertex] = new_id
self._graph.add_node(new_id, vertex=vertex)
n1 = self._id_map[entry_xyz]
n2 = self._id_map[exit_xyz]
if road_id not in self._road_id_to_edge:
self._road_id_to_edge[road_id] = dict()
if section_id not in self._road_id_to_edge[road_id]:
self._road_id_to_edge[road_id][section_id] = dict()
self._road_id_to_edge[road_id][section_id][lane_id] = (n1, n2)
entry_carla_vector = entry_wp.transform.rotation.get_forward_vector()
exit_carla_vector = exit_wp.transform.rotation.get_forward_vector()
# Adding edge with attributes
self._graph.add_edge(
n1,
n2,
length=len(path) + 1,
path=path,
entry_waypoint=entry_wp,
exit_waypoint=exit_wp,
entry_vector=np.array(
[entry_carla_vector.x, entry_carla_vector.y, entry_carla_vector.z]
),
exit_vector=np.array(
[exit_carla_vector.x, exit_carla_vector.y, exit_carla_vector.z]
),
net_vector=vector(
entry_wp.transform.location, exit_wp.transform.location
),
intersection=intersection,
type=RoadOption.LANEFOLLOW,
)
def _find_loose_ends(self):
"""
This method finds road segments that have an unconnected end, and
adds them to the internal graph representation
"""
count_loose_ends = 0
hop_resolution = self._sampling_resolution
for segment in self._topology:
end_wp = segment["exit"]
exit_xyz = segment["exitxyz"]
road_id, section_id, lane_id = (
end_wp.road_id,
end_wp.section_id,
end_wp.lane_id,
)
if (
road_id in self._road_id_to_edge
and section_id in self._road_id_to_edge[road_id]
and lane_id in self._road_id_to_edge[road_id][section_id]
):
pass
else:
count_loose_ends += 1
if road_id not in self._road_id_to_edge:
self._road_id_to_edge[road_id] = dict()
if section_id not in self._road_id_to_edge[road_id]:
self._road_id_to_edge[road_id][section_id] = dict()
n1 = self._id_map[exit_xyz]
n2 = -1 * count_loose_ends
self._road_id_to_edge[road_id][section_id][lane_id] = (n1, n2)
next_wp = end_wp.next(hop_resolution)
path = []
while (
next_wp is not None
and next_wp
and next_wp[0].road_id == road_id
and next_wp[0].section_id == section_id
and next_wp[0].lane_id == lane_id
):
path.append(next_wp[0])
next_wp = next_wp[0].next(hop_resolution)
if path:
n2_xyz = (
path[-1].transform.location.x,
path[-1].transform.location.y,
path[-1].transform.location.z,
)
self._graph.add_node(n2, vertex=n2_xyz)
self._graph.add_edge(
n1,
n2,
length=len(path) + 1,
path=path,
entry_waypoint=end_wp,
exit_waypoint=path[-1],
entry_vector=None,
exit_vector=None,
net_vector=None,
intersection=end_wp.is_junction,
type=RoadOption.LANEFOLLOW,
)
def _lane_change_link(self):
"""
This method places zero cost links in the topology graph
representing availability of lane changes.
"""
for segment in self._topology:
left_found, right_found = False, False
for waypoint in segment["path"]:
if not segment["entry"].is_junction:
next_waypoint, next_road_option, next_segment = None, None, None
if (
waypoint.right_lane_marking
and waypoint.right_lane_marking.lane_change
& carla.LaneChange.Right
and not right_found
):
next_waypoint = waypoint.get_right_lane()
if (
next_waypoint is not None
and next_waypoint.lane_type == carla.LaneType.Driving
and waypoint.road_id == next_waypoint.road_id
):
next_road_option = RoadOption.CHANGELANERIGHT
next_segment = self._localize(
next_waypoint.transform.location
)
if next_segment is not None:
self._graph.add_edge(
self._id_map[segment["entryxyz"]],
next_segment[0],
entry_waypoint=waypoint,
exit_waypoint=next_waypoint,
intersection=False,
exit_vector=None,
path=[],
length=0,
type=next_road_option,
change_waypoint=next_waypoint,
)
right_found = True
if (
waypoint.left_lane_marking
and waypoint.left_lane_marking.lane_change
& carla.LaneChange.Left
and not left_found
):
next_waypoint = waypoint.get_left_lane()
if (
next_waypoint is not None
and next_waypoint.lane_type == carla.LaneType.Driving
and waypoint.road_id == next_waypoint.road_id
):
next_road_option = RoadOption.CHANGELANELEFT
next_segment = self._localize(
next_waypoint.transform.location
)
if next_segment is not None:
self._graph.add_edge(
self._id_map[segment["entryxyz"]],
next_segment[0],
entry_waypoint=waypoint,
exit_waypoint=next_waypoint,
intersection=False,
exit_vector=None,
path=[],
length=0,
type=next_road_option,
change_waypoint=next_waypoint,
)
left_found = True
if left_found and right_found:
break
def _localize(self, location):
"""
This function finds the road segment that a given location
is part of, returning the edge it belongs to
"""
waypoint = self._wmap.get_waypoint(location)
edge = None
try:
edge = self._road_id_to_edge[waypoint.road_id][waypoint.section_id][
waypoint.lane_id
]
except KeyError:
pass
return edge
def _distance_heuristic(self, n1, n2):
"""
Distance heuristic calculator for path searching
in self._graph
"""
l1 = np.array(self._graph.nodes[n1]["vertex"])
l2 = np.array(self._graph.nodes[n2]["vertex"])
return np.linalg.norm(l1 - l2)
def _path_search(self, origin, destination):
"""
This function finds the shortest path connecting origin and destination
using A* search with distance heuristic.
origin : carla.Location object of start position
destination : carla.Location object of of end position
return : path as list of node ids (as int) of the graph self._graph
connecting origin and destination
"""
start, end = self._localize(origin), self._localize(destination)
route = nx.astar_path(
self._graph,
source=start[0],
target=end[0],
heuristic=self._distance_heuristic,
weight="length",
)
route.append(end[1])
return route
def _successive_last_intersection_edge(self, index, route):
"""
This method returns the last successive intersection edge
from a starting index on the route.
This helps moving past tiny intersection edges to calculate
proper turn decisions.
"""
last_intersection_edge = None
last_node = None
for node1, node2 in [
(route[i], route[i + 1]) for i in range(index, len(route) - 1)
]:
candidate_edge = self._graph.edges[node1, node2]
if node1 == route[index]:
last_intersection_edge = candidate_edge
if (
candidate_edge["type"] == RoadOption.LANEFOLLOW
and candidate_edge["intersection"]
):
last_intersection_edge = candidate_edge
last_node = node2
else:
break
return last_node, last_intersection_edge
def _turn_decision(self, index, route, threshold=math.radians(35)):
"""
This method returns the turn decision (RoadOption) for pair of edges
around current index of route list
"""
decision = None
previous_node = route[index - 1]
current_node = route[index]
next_node = route[index + 1]
next_edge = self._graph.edges[current_node, next_node]
if index > 0:
if (
self._previous_decision != RoadOption.VOID
and self._intersection_end_node > 0
and self._intersection_end_node != previous_node
and next_edge["type"] == RoadOption.LANEFOLLOW
and next_edge["intersection"]
):
decision = self._previous_decision
else:
self._intersection_end_node = -1
current_edge = self._graph.edges[previous_node, current_node]
calculate_turn = (
current_edge["type"] == RoadOption.LANEFOLLOW
and not current_edge["intersection"]
and next_edge["type"] == RoadOption.LANEFOLLOW
and next_edge["intersection"]
)
if calculate_turn:
last_node, tail_edge = self._successive_last_intersection_edge(
index, route
)
self._intersection_end_node = last_node
if tail_edge is not None:
next_edge = tail_edge
cv, nv = current_edge["exit_vector"], next_edge["exit_vector"]
if cv is None or nv is None:
return next_edge["type"]
cross_list = []
for neighbor in self._graph.successors(current_node):
select_edge = self._graph.edges[current_node, neighbor]
if select_edge["type"] == RoadOption.LANEFOLLOW:
if neighbor != route[index + 1]:
sv = select_edge["net_vector"]
cross_list.append(np.cross(cv, sv)[2])
next_cross = np.cross(cv, nv)[2]
deviation = math.acos(
np.clip(
np.dot(cv, nv) / (np.linalg.norm(cv) * np.linalg.norm(nv)),
-1.0,
1.0,
)
)
if not cross_list:
cross_list.append(0)
if deviation < threshold:
decision = RoadOption.STRAIGHT
elif cross_list and next_cross < min(cross_list):
decision = RoadOption.LEFT
elif cross_list and next_cross > max(cross_list):
decision = RoadOption.RIGHT
elif next_cross < 0:
decision = RoadOption.LEFT
elif next_cross > 0:
decision = RoadOption.RIGHT
else:
decision = next_edge["type"]
else:
decision = next_edge["type"]
self._previous_decision = decision
return decision
def _find_closest_in_list(self, current_waypoint, waypoint_list):
min_distance = float("inf")
closest_index = -1
for i, waypoint in enumerate(waypoint_list):
distance = waypoint.transform.location.distance(
current_waypoint.transform.location
)
if distance < min_distance:
min_distance = distance
closest_index = i
return closest_index
================================================
FILE: carla_bridge/carla_api/local_planner.py
================================================
# Copyright (c) # Copyright (c) 2018-2020 CVC.
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
""" This module contains a local planner to perform low-level waypoint following based on PID controllers. """
import random
from collections import deque
from enum import Enum
import carla
from carla_api.controller import VehiclePIDController
from carla_api.misc import draw_waypoints, get_speed
class RoadOption(Enum):
"""
RoadOption represents the possible topological configurations when moving from a segment of lane to other.
"""
VOID = -1
LEFT = 1
RIGHT = 2
STRAIGHT = 3
LANEFOLLOW = 4
CHANGELANELEFT = 5
CHANGELANERIGHT = 6
class LocalPlanner(object):
"""
LocalPlanner implements the basic behavior of following a
trajectory of waypoints that is generated on-the-fly.
The low-level motion of the vehicle is computed by using two PID controllers,
one is used for the lateral control and the other for the longitudinal control (cruise speed).
When multiple paths are available (intersections) this local planner makes a random choice,
unless a given global plan has already been specified.
"""
def __init__(self, vehicle, opt_dict=None):
"""
:param vehicle: actor to apply to local planner logic onto
:param opt_dict: dictionary of arguments with different parameters:
dt: time between simulation steps
target_speed: desired cruise speed in Km/h
sampling_radius: distance between the waypoints part of the plan
lateral_control_dict: values of the lateral PID controller
longitudinal_control_dict: values of the longitudinal PID controller
max_throttle: maximum throttle applied to the vehicle
max_brake: maximum brake applied to the vehicle
max_steering: maximum steering applied to the vehicle
offset: distance between the route waypoints and the center of the lane
"""
self._vehicle = vehicle
self._world = self._vehicle.get_world()
self._map = self._world.get_map()
self._vehicle_controller = None
self.target_waypoint = None
self.target_road_option = None
self._waypoints_queue = deque(maxlen=10000)
self._min_waypoint_queue_length = 100
self._stop_waypoint_creation = False
# Base parameters
self._dt = 1.0 / 20.0
self._target_speed = 20.0 # Km/h
self._sampling_radius = 2.0
self._args_lateral_dict = {"K_P": 1.95, "K_I": 0.05, "K_D": 0.2, "dt": self._dt}
self._args_longitudinal_dict = {
"K_P": 1.0,
"K_I": 0.05,
"K_D": 0,
"dt": self._dt,
}
self._max_throt = 0.75
self._max_brake = 0.3
self._max_steer = 0.8
self._offset = 0
self._base_min_distance = 3.0
self._follow_speed_limits = False
if opt_dict is None:
opt_dict = {}
# Overload parameters
if opt_dict:
if "dt" in opt_dict:
self._dt = opt_dict["dt"]
if "target_speed" in opt_dict:
self._target_speed = opt_dict["target_speed"]
if "sampling_radius" in opt_dict:
self._sampling_radius = opt_dict["sampling_radius"]
if "lateral_control_dict" in opt_dict:
self._args_lateral_dict = opt_dict["lateral_control_dict"]
if "longitudinal_control_dict" in opt_dict:
self._args_longitudinal_dict = opt_dict["longitudinal_control_dict"]
if "max_throttle" in opt_dict:
self._max_throt = opt_dict["max_throttle"]
if "max_brake" in opt_dict:
self._max_brake = opt_dict["max_brake"]
if "max_steering" in opt_dict:
self._max_steer = opt_dict["max_steering"]
if "offset" in opt_dict:
self._offset = opt_dict["offset"]
if "base_min_distance" in opt_dict:
self._base_min_distance = opt_dict["base_min_distance"]
if "follow_speed_limits" in opt_dict:
self._follow_speed_limits = opt_dict["follow_speed_limits"]
# initializing controller
self._init_controller()
def reset_vehicle(self):
"""Reset the ego-vehicle"""
self._vehicle = None
def _init_controller(self):
"""Controller initialization"""
self._vehicle_controller = VehiclePIDController(
self._vehicle,
args_lateral=self._args_lateral_dict,
args_longitudinal=self._args_longitudinal_dict,
offset=self._offset,
max_throttle=self._max_throt,
max_brake=self._max_brake,
max_steering=self._max_steer,
)
# Compute the current vehicle waypoint
current_waypoint = self._map.get_waypoint(self._vehicle.get_location())
self.target_waypoint, self.target_road_option = (
current_waypoint,
RoadOption.LANEFOLLOW,
)
self._waypoints_queue.append((self.target_waypoint, self.target_road_option))
def set_speed(self, speed):
"""
Changes the target speed
:param speed: new target speed in Km/h
:return:
"""
if self._follow_speed_limits:
print(
"WARNING: The max speed is currently set to follow the speed limits. "
"Use 'follow_speed_limits' to deactivate this"
)
self._target_speed = speed
def follow_speed_limits(self, value=True):
"""
Activates a flag that makes the max speed dynamically vary according to the spped limits
:param value: bool
:return:
"""
self._follow_speed_limits = value
def _compute_next_waypoints(self, k=1):
"""
Add new waypoints to the trajectory queue.
:param k: how many waypoints to compute
:return:
"""
# check we do not overflow the queue
available_entries = self._waypoints_queue.maxlen - len(self._waypoints_queue)
k = min(available_entries, k)
for _ in range(k):
last_waypoint = self._waypoints_queue[-1][0]
next_waypoints = list(last_waypoint.next(self._sampling_radius))
if len(next_waypoints) == 0:
break
elif len(next_waypoints) == 1:
# only one option available ==> lanefollowing
next_waypoint = next_waypoints[0]
road_option = RoadOption.LANEFOLLOW
else:
# random choice between the possible options
road_options_list = _retrieve_options(next_waypoints, last_waypoint)
road_option = random.choice(road_options_list)
next_waypoint = next_waypoints[road_options_list.index(road_option)]
self._waypoints_queue.append((next_waypoint, road_option))
def set_global_plan(
self, current_plan, stop_waypoint_creation=True, clean_queue=True
):
"""
Adds a new plan to the local planner. A plan must be a list of [carla.Waypoint, RoadOption] pairs
The 'clean_queue` parameter erases the previous plan if True, otherwise, it adds it to the old one
The 'stop_waypoint_creation' flag stops the automatic creation of random waypoints
:param current_plan: list of (carla.Waypoint, RoadOption)
:param stop_waypoint_creation: bool
:param clean_queue: bool
:return:
"""
if clean_queue:
self._waypoints_queue.clear()
# Remake the waypoints queue if the new plan has a higher length than the queue
new_plan_length = len(current_plan) + len(self._waypoints_queue)
if new_plan_length > self._waypoints_queue.maxlen:
new_waypoint_queue = deque(maxlen=new_plan_length)
for wp in self._waypoints_queue:
new_waypoint_queue.append(wp)
self._waypoints_queue = new_waypoint_queue
for elem in current_plan:
self._waypoints_queue.append(elem)
self._stop_waypoint_creation = stop_waypoint_creation
def run_step(self, debug=False):
"""
Execute one step of local planning which involves running the longitudinal and lateral PID controllers to
follow the waypoints trajectory.
:param debug: boolean flag to activate waypoints debugging
:return: control to be applied
"""
if self._follow_speed_limits:
self._target_speed = self._vehicle.get_speed_limit()
# Add more waypoints too few in the horizon
if (
not self._stop_waypoint_creation
and len(self._waypoints_queue) < self._min_waypoint_queue_length
):
self._compute_next_waypoints(k=self._min_waypoint_queue_length)
# Purge the queue of obsolete waypoints
veh_location = self._vehicle.get_location()
vehicle_speed = get_speed(self._vehicle) / 3.6
self._min_distance = self._base_min_distance + 0.5 * vehicle_speed
num_waypoint_removed = 0
for waypoint, _ in self._waypoints_queue:
if len(self._waypoints_queue) - num_waypoint_removed == 1:
min_distance = 1 # Don't remove the last waypoint until very close by
else:
min_distance = self._min_distance
if veh_location.distance(waypoint.transform.location) < min_distance:
num_waypoint_removed += 1
else:
break
if num_waypoint_removed > 0:
for _ in range(num_waypoint_removed):
self._waypoints_queue.popleft()
# Get the target waypoint and move using the PID controllers. Stop if no target waypoint
if len(self._waypoints_queue) == 0:
control = carla.VehicleControl()
control.steer = 0.0
control.throttle = 0.0
control.brake = 1.0
control.hand_brake = False
control.manual_gear_shift = False
else:
self.target_waypoint, self.target_road_option = self._waypoints_queue[0]
control = self._vehicle_controller.run_step(
self._target_speed, self.target_waypoint
)
if debug:
draw_waypoints(self._vehicle.get_world(), [self.target_waypoint], 1.0)
return control
def get_incoming_waypoint_and_direction(self, steps=3):
"""
Returns direction and waypoint at a distance ahead defined by the user.
:param steps: number of steps to get the incoming waypoint.
"""
if len(self._waypoints_queue) > steps:
return self._waypoints_queue[steps]
else:
try:
wpt, direction = self._waypoints_queue[-1]
return wpt, direction
except IndexError:
return None, RoadOption.VOID
def get_plan(self):
"""Returns the current plan of the local planner"""
return self._waypoints_queue
def done(self):
"""
Returns whether or not the planner has finished
:return: boolean
"""
return len(self._waypoints_queue) == 0
def _retrieve_options(list_waypoints, current_waypoint):
"""
Compute the type of connection between the current active waypoint and the multiple waypoints present in
list_waypoints. The result is encoded as a list of RoadOption enums.
:param list_waypoints: list with the possible target waypoints in case of multiple options
:param current_waypoint: current active waypoint
:return: list of RoadOption enums representing the type of connection from the active waypoint to each
candidate in list_waypoints
"""
options = []
for next_waypoint in list_waypoints:
# this is needed because something we are linking to
# the beggining of an intersection, therefore the
# variation in angle is small
next_next_waypoint = next_waypoint.next(3.0)[0]
link = _compute_connection(current_waypoint, next_next_waypoint)
options.append(link)
return options
def _compute_connection(current_waypoint, next_waypoint, threshold=35):
"""
Compute the type of topological connection between an active waypoint (current_waypoint) and a target waypoint
(next_waypoint).
:param current_waypoint: active waypoint
:param next_waypoint: target waypoint
:return: the type of topological connection encoded as a RoadOption enum:
RoadOption.STRAIGHT
RoadOption.LEFT
RoadOption.RIGHT
"""
n = next_waypoint.transform.rotation.yaw
n = n % 360.0
c = current_waypoint.transform.rotation.yaw
c = c % 360.0
diff_angle = (n - c) % 180.0
if diff_angle < threshold or diff_angle > (180 - threshold):
return RoadOption.STRAIGHT
elif diff_angle > 90.0:
return RoadOption.LEFT
else:
return RoadOption.RIGHT
================================================
FILE: carla_bridge/carla_api/misc.py
================================================
#!/usr/bin/env python
# Copyright (c) 2018 Intel Labs.
# authors: German Ros (german.ros@intel.com)
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
""" Module with auxiliary functions. """
import math
import carla
import numpy as np
def draw_waypoints(world, waypoints, z=0.5):
"""
Draw a list of waypoints at a certain height given in z.
:param world: carla.world object
:param waypoints: list or iterable container with the waypoints to draw
:param z: height in meters
"""
for wpt in waypoints:
wpt_t = wpt.transform
begin = wpt_t.location + carla.Location(z=z)
angle = math.radians(wpt_t.rotation.yaw)
end = begin + carla.Location(x=math.cos(angle), y=math.sin(angle))
world.debug.draw_arrow(begin, end, arrow_size=0.3, life_time=1.0)
def get_speed(vehicle):
"""
Compute speed of a vehicle in Km/h.
:param vehicle: the vehicle for which speed is calculated
:return: speed as a float in Km/h
"""
vel = vehicle.get_velocity()
return 3.6 * math.sqrt(vel.x**2 + vel.y**2 + vel.z**2)
def get_trafficlight_trigger_location(traffic_light):
"""
Calculates the yaw of the waypoint that represents the trigger volume of the traffic light
"""
def rotate_point(point, radians):
"""
rotate a given point by a given angle
"""
rotated_x = math.cos(radians) * point.x - math.sin(radians) * point.y
rotated_y = math.sin(radians) * point.x - math.cos(radians) * point.y
return carla.Vector3D(rotated_x, rotated_y, point.z)
base_transform = traffic_light.get_transform()
base_rot = base_transform.rotation.yaw
area_loc = base_transform.transform(traffic_light.trigger_volume.location)
area_ext = traffic_light.trigger_volume.extent
point = rotate_point(carla.Vector3D(0, 0, area_ext.z), math.radians(base_rot))
point_location = area_loc + carla.Location(x=point.x, y=point.y)
return carla.Location(point_location.x, point_location.y, point_location.z)
def is_within_distance(
target_transform, reference_transform, max_distance, angle_interval=None
):
"""
Check if a location is both within a certain distance from a reference object.
By using 'angle_interval', the angle between the location and reference transform
will also be tkaen into account, being 0 a location in front and 180, one behind.
:param target_transform: location of the target object
:param reference_transform: location of the reference object
:param max_distance: maximum allowed distance
:param angle_interval: only locations between [min, max] angles will be considered. This isn't checked by default.
:return: boolean
"""
target_vector = np.array(
[
target_transform.location.x - reference_transform.location.x,
target_transform.location.y - reference_transform.location.y,
]
)
norm_target = np.linalg.norm(target_vector)
# If the vector is too short, we can simply stop here
if norm_target < 0.001:
return True
# Further than the max distance
if norm_target > max_distance:
return False
# We don't care about the angle, nothing else to check
if not angle_interval:
return True
min_angle = angle_interval[0]
max_angle = angle_interval[1]
fwd = reference_transform.get_forward_vector()
forward_vector = np.array([fwd.x, fwd.y])
angle = math.degrees(
math.acos(
np.clip(np.dot(forward_vector, target_vector) / norm_target, -1.0, 1.0)
)
)
return min_angle < angle < max_angle
def compute_magnitude_angle(target_location, current_location, orientation):
"""
Compute relative angle and distance between a target_location and a current_location
:param target_location: location of the target object
:param current_location: location of the reference object
:param orientation: orientation of the reference object
:return: a tuple composed by the distance to the object and the angle between both objects
"""
target_vector = np.array(
[target_location.x - current_location.x, target_location.y - current_location.y]
)
norm_target = np.linalg.norm(target_vector)
forward_vector = np.array(
[math.cos(math.radians(orientation)), math.sin(math.radians(orientation))]
)
d_angle = math.degrees(
math.acos(
np.clip(np.dot(forward_vector, target_vector) / norm_target, -1.0, 1.0)
)
)
return (norm_target, d_angle)
def distance_vehicle(waypoint, vehicle_transform):
"""
Returns the 2D distance from a waypoint to a vehicle
:param waypoint: actual waypoint
:param vehicle_transform: transform of the target vehicle
"""
loc = vehicle_transform.location
x = waypoint.transform.location.x - loc.x
y = waypoint.transform.location.y - loc.y
return math.sqrt(x * x + y * y)
def vector(location_1, location_2):
"""
Returns the unit vector from location_1 to location_2
:param location_1, location_2: carla.Location objects
"""
x = location_2.x - location_1.x
y = location_2.y - location_1.y
z = location_2.z - location_1.z
norm = np.linalg.norm([x, y, z]) + np.finfo(float).eps
return [x / norm, y / norm, z / norm]
def compute_distance(location_1, location_2):
"""
Euclidean distance between 3D points
:param location_1, location_2: 3D points
"""
x = location_2.x - location_1.x
y = location_2.y - location_1.y
z = location_2.z - location_1.z
norm = np.linalg.norm([x, y, z]) + np.finfo(float).eps
return norm
def positive(num):
"""
Return the given number if positive, else 0
:param num: value to check
"""
return num if num > 0.0 else 0.0
================================================
FILE: carla_bridge/config/objects.json
================================================
{
"objects":
[
{
"type": "sensor.pseudo.traffic_lights",
"id": "traffic_lights"
},
{
"type": "vehicle.lincoln.mkz_2017",
"id": "ego_vehicle",
"sensors":
[
{
"type": "sensor.camera.rgb",
"id": "front_6mm",
"spawn_point": {"x": 2.0, "y": 0.0, "z": 2.0, "roll": 0.0, "pitch": 0.0, "yaw": 0.0},
"image_size_x": 800,
"image_size_y": 600,
"fov": 90.0,
"fstop": 8.0
},
{
"type": "sensor.camera.rgb",
"id": "front_12mm",
"spawn_point": {"x": 2.5, "y": 0.0, "z": 2.8, "roll": 0.0, "pitch": 0.0, "yaw": 0.0},
"image_size_x": 800,
"image_size_y": 600,
"focal_distance": 2000,
"fov": 90.0,
"fstop": 8.0
},
{
"type": "sensor.lidar.ray_cast",
"id": "lidar128",
"spawn_point": {"x": 0.0, "y": 0.0, "z": 2.4, "roll": 0.0, "pitch": 0.0, "yaw": 0.0},
"range": 50,
"channels": 128,
"points_per_second": 320000,
"upper_fov": 2.0,
"lower_fov": -26.8,
"rotation_frequency": 20,
"noise_stddev": 0.0
},
{
"type": "sensor.other.radar",
"id": "radar/front",
"spawn_point": {"x": 2.0, "y": 0.0, "z": 2.0, "roll": 0.0, "pitch": 0.0, "yaw": 0.0},
"horizontal_fov": 30.0,
"vertical_fov": 10.0,
"points_per_second": 1500,
"range": 100.0
},
{
"type": "sensor.other.gnss",
"id": "gnss",
"spawn_point": {"x": 1.0, "y": 0.0, "z": 2.0},
"noise_alt_stddev": 0.0, "noise_lat_stddev": 0.0, "noise_lon_stddev": 0.0,
"noise_alt_bias": 0.0, "noise_lat_bias": 0.0, "noise_lon_bias": 0.0
},
{
"type": "sensor.other.imu",
"id": "gnss/imu",
"spawn_point": {"x": 2.0, "y": 0.0, "z": 2.0, "roll": 0.0, "pitch": 0.0, "yaw": 0.0},
"noise_accel_stddev_x": 0.0, "noise_accel_stddev_y": 0.0, "noise_accel_stddev_z": 0.0,
"noise_gyro_stddev_x": 0.0, "noise_gyro_stddev_y": 0.0, "noise_gyro_stddev_z": 0.0,
"noise_gyro_bias_x": 0.0, "noise_gyro_bias_y": 0.0, "noise_gyro_bias_z": 0.0
},
{
"type": "sensor.pseudo.objects",
"id": "obstacles"
}
]
}
]
}
================================================
FILE: carla_bridge/config/settings.yaml
================================================
carla:
host: '172.17.0.1'
port: 2000
timeout: 30
passive: False
synchronous_mode: True
synchronous_mode_wait_for_vehicle_control_command: False
fixed_delta_seconds: 0.05
register_all_sensors: True
town: 'Town01'
ego_vehicle:
role_name: ["hero", "ego_vehicle"]
================================================
FILE: carla_bridge/core/actor_factory.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2020 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
#
import itertools
from carla_bridge.actor.actor import Actor
from carla_bridge.actor.ego_vehicle import EgoVehicle
from carla_bridge.actor.pseudo_actor import PseudoActor
from carla_bridge.actor.spectator import Spectator
from carla_bridge.actor.static import Static
from carla_bridge.actor.traffic import TrafficLight, Traffic
from carla_bridge.actor.vehicle import Vehicle
from carla_bridge.actor.walker import Walker
from carla_bridge.sensor.camera import RgbCamera, DepthCamera, SemanticSegmentationCamera, DVSCamera, Camera
from carla_bridge.sensor.gnss import Gnss
from carla_bridge.sensor.imu import ImuSensor
from carla_bridge.sensor.lidar import Lidar, SemanticLidar
from carla_bridge.sensor.object_sensor import ObjectSensor
from carla_bridge.sensor.radar import Radar
from carla_bridge.sensor.sensor import Sensor
from carla_bridge.sensor.traffic_lights_sensor import TrafficLightsSensor
try:
import queue
except ImportError:
import Queue as queue
import time
from enum import Enum
from threading import Thread, Lock
import carla
import numpy as np
import carla_bridge.utils.transforms as trans
# to generate a random spawning position or vehicles
import random
secure_random = random.SystemRandom()
class ActorFactory(object):
TIME_BETWEEN_UPDATES = 0.1
class TaskType(Enum):
SPAWN_ACTOR = 0
SPAWN_PSEUDO_ACTOR = 1
DESTROY_ACTOR = 2
def __init__(self, node, world, log, sync_mode=False, ):
self.log = log
self.node = node
self.world = world
self.blueprint_lib = self.world.get_blueprint_library()
self.spawn_points = self.world.get_map().get_spawn_points()
self.sync_mode = sync_mode
self._previous_actor_ids = []
self.actors = {}
self._task_queue = queue.Queue()
self._known_actor_ids = [] # used to immediately reply to spawn_actor/destroy_actor calls
self.lock = Lock()
self.spawn_lock = Lock()
# id generator for pseudo sensors
self.id_gen = itertools.count(10000)
self.thread = Thread(target=self._update_thread)
def start(self):
# create initially existing actors
self.update_available_objects()
self.thread.start()
def _update_thread(self):
"""
execution loop for async mode actor discovery
"""
while not self.node.shutdown.is_set():
time.sleep(ActorFactory.TIME_BETWEEN_UPDATES)
self.world.wait_for_tick()
self.update_available_objects()
def update_available_objects(self):
"""
update the available actors
"""
# get only carla actors
previous_actors = self._previous_actor_ids
current_actors = [x.id for x in self.world.get_actors()]
self._previous_actor_ids = current_actors
new_actors = [x for x in current_actors if x not in previous_actors]
deleted_actors = [x for x in previous_actors if x not in current_actors]
# Actual creation/removal of objects
self.lock.acquire()
for actor_id in new_actors:
carla_actor = self.world.get_actor(actor_id)
if self.node.carla_parameters["register_all_sensors"] or not isinstance(carla_actor, carla.Sensor):
self._create_object_from_actor(carla_actor)
for actor_id in deleted_actors:
self._destroy_object(actor_id, delete_actor=False)
# update objects for pseudo actors here as they might have an carla actor as parent ######
with self.spawn_lock:
while not self._task_queue.empty():
task = self._task_queue.get()
if task[0] == ActorFactory.TaskType.SPAWN_ACTOR and not self.node.shutdown.is_set():
carla_actor = self.world.get_actor(task[1][0])
self._create_object_from_actor(carla_actor)
elif task[0] == ActorFactory.TaskType.SPAWN_PSEUDO_ACTOR and not self.node.shutdown.is_set():
pseudo_object = task[1]
self._create_object(pseudo_object[0], pseudo_object[1].type, pseudo_object[1].id,
pseudo_object[1].attach_to, pseudo_object[1].transform)
elif task[0] == ActorFactory.TaskType.DESTROY_ACTOR:
actor_id = task[1]
self._destroy_object(actor_id, delete_actor=True)
self.lock.release()
def update_actor_states(self, frame_id, timestamp):
"""
update the state of all known actors
"""
with self.lock:
for actor_id in self.actors:
try:
self.actors[actor_id].update(frame_id, timestamp)
except RuntimeError as e:
self.log.warn("Update actor {}({}) failed: {}".format(
self.actors[actor_id].__class__.__name__, actor_id, e))
continue
def clear(self):
for _, actor in self.actors.items():
actor.destroy()
self.actors.clear()
def spawn_actor(self, req):
"""
spawns an object
No object instances are created here. Instead carla-actors are created,
and pseudo objects are appended to a list to get created later.
"""
with self.spawn_lock:
if "pseudo" in str(req.type):
# only allow spawning pseudo objects if parent actor already exists in carla
if req.attach_to != 0:
carla_actor = self.world.get_actor(req.attach_to)
if carla_actor is None:
raise IndexError("Parent actor {} not found".format(req.attach_to))
id_ = next(self.id_gen)
self._task_queue.put((ActorFactory.TaskType.SPAWN_PSEUDO_ACTOR, (id_, req)))
else:
id_ = self._spawn_carla_actor(req)
self._task_queue.put((ActorFactory.TaskType.SPAWN_ACTOR, (id_, None)))
self._known_actor_ids.append(id_)
return id_
def destroy_actor(self, uid):
def get_objects_to_destroy(uid):
objects_to_destroy = []
if uid in self._known_actor_ids:
objects_to_destroy.append(uid)
self._known_actor_ids.remove(uid)
# remove actors that have the actor to be removed as parent.
for actor in list(self.actors.values()):
if actor.parent is not None and actor.parent.uid == uid:
objects_to_destroy.extend(get_objects_to_destroy(actor.uid))
return objects_to_destroy
with self.spawn_lock:
objects_to_destroy = set(get_objects_to_destroy(uid))
for obj in objects_to_destroy:
self._task_queue.put((ActorFactory.TaskType.DESTROY_ACTOR, obj))
return objects_to_destroy
def _spawn_carla_actor(self, req):
"""
spawns an actor in carla
"""
if "*" in str(req.type):
blueprint = secure_random.choice(
self.blueprint_lib.filter(str(req.type)))
else:
blueprint = self.blueprint_lib.find(str(req.type))
blueprint.set_attribute('role_name', str(req.id))
for attribute in req.attributes:
blueprint.set_attribute(str(attribute.key), str(attribute.value))
if req.random_pose is False:
transform = trans.cyber_pose_to_carla_transform(req.transform)
else:
# get a random pose
transform = secure_random.choice(
self.spawn_points) if self.spawn_points else carla.Transform()
attach_to = None
if req.attach_to != 0:
attach_to = self.world.get_actor(req.attach_to)
if attach_to is None:
raise IndexError("Parent actor {} not found".format(req.attach_to))
carla_actor = self.world.spawn_actor(blueprint, transform, attach_to)
return carla_actor.id
def _create_object_from_actor(self, carla_actor):
"""
create a object for a given carla actor
Creates also the object for its parent, if not yet existing
"""
parent = None
# the transform relative to the map
relative_transform = trans.carla_transform_to_cyber_pose(carla_actor.get_transform())
if carla_actor.parent:
if carla_actor.parent.id in self.actors:
parent = self.actors[carla_actor.parent.id]
else:
parent = self._create_object_from_actor(carla_actor.parent)
# calculate relative transform to the parent
actor_transform_matrix = trans.cyber_pose_to_transform_matrix(relative_transform)
parent_transform_matrix = trans.cyber_pose_to_transform_matrix(
trans.carla_transform_to_cyber_pose(carla_actor.parent.get_transform()))
relative_transform_matrix = np.matrix(
parent_transform_matrix).getI() * np.matrix(actor_transform_matrix)
relative_transform = trans.transform_matrix_to_cyber_pose(relative_transform_matrix)
parent_id = 0
if parent is not None:
parent_id = parent.uid
name = carla_actor.attributes.get("role_name", "")
if not name:
name = str(carla_actor.id)
obj = self._create_object(carla_actor.id, carla_actor.type_id, name,
parent_id, relative_transform, carla_actor)
return obj
def _destroy_object(self, actor_id, delete_actor):
if actor_id not in self.actors:
return
actor = self.actors[actor_id]
del self.actors[actor_id]
carla_actor = None
if isinstance(actor, Actor):
carla_actor = actor.carla_actor
actor.destroy()
if carla_actor and delete_actor:
carla_actor.destroy()
self.log.info("Removed {}(id={})".format(actor.__class__.__name__, actor.uid))
def get_pseudo_sensor_types(self):
pseudo_sensors = []
for cls in PseudoActor.__subclasses__():
if cls.__name__ != "Actor":
pseudo_sensors.append(cls.get_blueprint_name())
return pseudo_sensors
def _create_object(self, uid, type_id, name, attach_to, spawn_pose, carla_actor=None):
# check that the actor is not already created.
if carla_actor is not None and carla_actor.id in self.actors:
return None
if attach_to != 0:
if attach_to not in self.actors:
raise IndexError("Parent object {} not found".format(attach_to))
parent = self.actors[attach_to]
else:
parent = None
if type_id == ObjectSensor.get_blueprint_name():
actor = ObjectSensor(
uid=uid,
name=name,
parent=parent,
node=self.node,
actor_list=self.actors,
)
elif type_id == TrafficLightsSensor.get_blueprint_name():
actor = TrafficLightsSensor(
uid=uid,
name=name,
parent=parent,
node=self.node,
actor_list=self.actors,
log=self.log
)
elif carla_actor.type_id.startswith('traffic'):
if carla_actor.type_id == "traffic.traffic_light":
actor = TrafficLight(uid, name, parent, self.node, carla_actor)
else:
actor = Traffic(uid, name, parent, self.node, carla_actor)
elif carla_actor.type_id.startswith("vehicle"):
if carla_actor.attributes.get('role_name')\
in self.node.carla_parameters['ego_vehicle']['role_name']:
actor = EgoVehicle(
uid, name, parent, self.node, carla_actor, self.world)
else:
actor = Vehicle(uid, name, parent, self.node, carla_actor)
elif carla_actor.type_id.startswith("sensor"):
if carla_actor.type_id.startswith("sensor.camera"):
if carla_actor.type_id.startswith("sensor.camera.rgb"):
actor = RgbCamera(uid, name, parent, spawn_pose, self.node,
carla_actor, self.sync_mode)
elif carla_actor.type_id.startswith("sensor.camera.depth"):
actor = DepthCamera(uid, name, parent, spawn_pose,
self.node, carla_actor, self.sync_mode)
elif carla_actor.type_id.startswith(
"sensor.camera.semantic_segmentation"):
actor = SemanticSegmentationCamera(uid, name, parent,
spawn_pose, self.node,
carla_actor,
self.sync_mode)
elif carla_actor.type_id.startswith("sensor.camera.dvs"):
actor = DVSCamera(uid, name, parent, spawn_pose, self.node,
carla_actor, self.sync_mode)
else:
actor = Camera(uid, name, parent, spawn_pose, self.node,
carla_actor, self.sync_mode)
elif carla_actor.type_id.startswith("sensor.lidar"):
if carla_actor.type_id.endswith("sensor.lidar.ray_cast"):
actor = Lidar(uid, name, parent, spawn_pose, self.node,
carla_actor, self.sync_mode)
elif carla_actor.type_id.endswith(
"sensor.lidar.ray_cast_semantic"):
actor = SemanticLidar(uid, name, parent, spawn_pose,
self.node, carla_actor,
self.sync_mode)
elif carla_actor.type_id.startswith("sensor.other.radar"):
actor = Radar(uid, name, parent, spawn_pose, self.node,
carla_actor, self.sync_mode)
elif carla_actor.type_id.startswith("sensor.other.gnss"):
actor = Gnss(uid, name, parent, spawn_pose, self.node,
carla_actor, self.sync_mode)
elif carla_actor.type_id.startswith("sensor.other.imu"):
actor = ImuSensor(uid, name, parent, spawn_pose, self.node,
carla_actor, self.sync_mode)
else:
actor = Sensor(uid, name, parent, spawn_pose, self.node,
carla_actor, self.sync_mode)
elif carla_actor.type_id.startswith("spectator"):
actor = Spectator(uid, name, parent, self.node, carla_actor)
elif carla_actor.type_id.startswith("walker"):
actor = Walker(uid, name, parent, self.node, carla_actor)
elif carla_actor.type_id.startswith("static.prop"):
actor = Static(uid, name, parent, self.node, carla_actor)
else:
actor = Actor(uid, name, parent, self.node, carla_actor)
self.actors[actor.uid] = actor
self.log.info("Created {}(id={})".format(actor.__class__.__name__, actor.uid))
return actor
================================================
FILE: carla_bridge/core/carla_spawn_objects.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2019-2020 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""
base class for spawning objects (carla actors and pseudo_actors) in Cyber
Gets config file from ros parameter ~objects_definition_file and spawns corresponding objects
through Cyber service /carla/spawn_object.
Looks for an initial spawn point first in the launchfile, then in the config file, and
finally ask for a random one to the spawn service.
"""
import sys
from carla_bridge.actor.ego_vehicle import EgoVehicle
from carla_bridge.core.spawn_object_param import SpawnObjectParam, KeyValue
sys.path.append("../")
import json
import math
import os
from transforms3d.euler import euler2quat
from modules.common_msgs.localization_msgs.pose_pb2 import Pose
class CarlaSpawnObjects:
"""
Handles the spawning of the ego vehicle and its sensors
Derive from this class and implement method sensors()
"""
def __init__(self, bridge_node):
self.bridge_node = bridge_node
self.log = bridge_node.log
self.actor_factory = bridge_node.actor_factory
self.objects_definition_file = (
os.path.dirname(os.path.dirname(__file__)) + "/config/objects.json"
)
self.players = []
self.vehicles_sensors = []
self.global_sensors = []
def spawn_objects(self):
"""
Spawns the objects
Either at a given spawnpoint or at a random Carla spawnpoint
:return:
"""
# Read sensors from file
if not self.objects_definition_file or not os.path.exists(self.objects_definition_file):
raise RuntimeError(
f"Could not read object definitions from {self.objects_definition_file}")
with open(self.objects_definition_file) as handle:
json_actors = json.loads(handle.read())
global_sensors = []
vehicles = []
for actor in json_actors["objects"]:
actor_type = actor["type"].split('.')[0]
if actor["type"] == "sensor.pseudo.actor_list":
global_sensors.append(actor)
elif actor_type == "sensor":
global_sensors.append(actor)
elif actor_type == "vehicle" or actor_type == "walker":
vehicles.append(actor)
else:
self.log.warn(
"Object with type {} is not a vehicle, a walker or a sensor, ignoring".format(actor["type"]))
self.setup_sensors(global_sensors)
self.setup_vehicles(vehicles)
self.log.info("All objects spawned.")
def setup_vehicles(self, vehicles):
for vehicle in vehicles:
spawn_object_param = SpawnObjectParam()
spawn_object_param.type = vehicle["type"]
spawn_object_param.id = vehicle["id"]
spawn_object_param.attach_to = 0
spawn_object_param.random_pose = False
spawn_point = None
if "spawn_point" in vehicle:
# get spawn point from config file
try:
spawn_point = self.create_spawn_point(
vehicle["spawn_point"]["x"],
vehicle["spawn_point"]["y"],
vehicle["spawn_point"]["z"],
vehicle["spawn_point"]["roll"],
vehicle["spawn_point"]["pitch"],
vehicle["spawn_point"]["yaw"]
)
self.log.info("Spawn point from configuration file")
except KeyError as e:
self.log.error("{}: Could not use the spawn point from config file, ".format(vehicle["id"]) +
"the mandatory attribute {} is missing, a random spawn point will be used".format(e))
if spawn_point is None:
# pose not specified, ask for a random one in the service call
self.log.info("Spawn point selected at random")
spawn_point = Pose() # empty pose
spawn_object_param.random_pose = True
spawn_object_param.transform.CopyFrom(spawn_point)
self.bridge_node.spawn_object(spawn_object_param)
ego_vehicle_spawned = False
while not ego_vehicle_spawned:
actors = self.actor_factory.actors.copy()
for uid, act in actors.items():
if isinstance(act, EgoVehicle):
ego_vehicle_spawned = True
self.setup_sensors(vehicle["sensors"], uid)
break
def setup_sensors(self, sensors, attached_vehicle_id=None):
"""
Create the sensors defined by the user and attach them to the vehicle
(or not if global sensor)
:param sensors: list of sensors
:param attached_vehicle_id: id of vehicle to attach the sensors to
:return actors: list of ids of objects created
"""
sensor_names = []
for sensor_spec in sensors:
self.log.debug(f"sensor: {sensor_spec}, attach: {attached_vehicle_id}")
if not self.bridge_node.ok():
break
try:
sensor_type = str(sensor_spec.pop("type"))
sensor_id = str(sensor_spec.pop("id"))
sensor_name = sensor_type + "/" + sensor_id
if sensor_name in sensor_names:
raise NameError
sensor_names.append(sensor_name)
if attached_vehicle_id is None and "pseudo" not in sensor_type:
spawn_point = sensor_spec.pop("spawn_point")
sensor_transform = self.create_spawn_point(
spawn_point.pop("x"),
spawn_point.pop("y"),
spawn_point.pop("z"),
spawn_point.pop("roll", 0.0),
spawn_point.pop("pitch", 0.0),
spawn_point.pop("yaw", 0.0))
else:
# if sensor attached to a vehicle, or is a 'pseudo_actor', allow default pose
spawn_point = sensor_spec.pop("spawn_point", 0)
if spawn_point == 0:
sensor_transform = self.create_spawn_point(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
else:
sensor_transform = self.create_spawn_point(
spawn_point.pop("x", 0.0),
spawn_point.pop("y", 0.0),
spawn_point.pop("z", 0.0),
spawn_point.pop("roll", 0.0),
spawn_point.pop("pitch", 0.0),
spawn_point.pop("yaw", 0.0))
spawn_object_param = SpawnObjectParam()
spawn_object_param.type = sensor_type
spawn_object_param.id = sensor_id
spawn_object_param.attach_to = attached_vehicle_id if attached_vehicle_id is not None else 0
spawn_object_param.transform.CopyFrom(sensor_transform)
spawn_object_param.random_pose = False # never set a random pose for a sensor
attached_objects = []
for attribute, value in sensor_spec.items():
if attribute == "attached_objects":
for attached_object in sensor_spec["attached_objects"]:
attached_objects.append(attached_object)
continue
spawn_object_param.attributes.append(
KeyValue(key=str(attribute), value=str(value)))
response_id = self.bridge_node.spawn_object(spawn_object_param)
if attached_objects:
# spawn the attached objects
self.setup_sensors(attached_objects, response_id)
if attached_vehicle_id is None:
self.global_sensors.append(response_id)
else:
self.vehicles_sensors.append(response_id)
except KeyError as e:
self.log.error(
"Sensor {} will not be spawned, the mandatory attribute {} is missing".format(sensor_name, e))
continue
except RuntimeError as e:
self.log.error(
"Sensor {} will not be spawned: {}".format(sensor_name, e))
continue
except NameError:
self.log.error("Sensor rolename '{}' is only allowed to be used once. The second one will be ignored.".format(
sensor_id))
continue
def create_spawn_point(self, x, y, z, roll, pitch, yaw):
spawn_point = Pose()
spawn_point.position.x = x
spawn_point.position.y = y
spawn_point.position.z = z
quat = euler2quat(math.radians(roll), math.radians(pitch), math.radians(yaw))
spawn_point.orientation.qx = quat[1]
spawn_point.orientation.qy = quat[2]
spawn_point.orientation.qz = quat[3]
spawn_point.orientation.qw = quat[0]
return spawn_point
def destroy(self):
"""
destroy all the players and sensors
"""
self.log.info("Destroying spawned objects...")
# destroy vehicles sensors
for actor_id in self.vehicles_sensors:
if self.bridge_node.destroy_object(actor_id):
self.log.info("Object {} successfully destroyed.".format(actor_id))
self.vehicles_sensors = []
# destroy global sensors
for actor_id in self.global_sensors:
if self.bridge_node.destroy_object(actor_id):
self.log.info("Object {} successfully destroyed.".format(actor_id))
self.global_sensors = []
# destroy player
for player_id in self.players:
if self.bridge_node.destroy_object(player_id):
self.log.info("Object {} successfully destroyed.".format(player_id))
self.players = []
================================================
FILE: carla_bridge/core/carmera_info.py
================================================
class CameraInfo:
def __init__(self):
self.height = 0
self.width = 0
self.distortion_model = ''
self.D = []
self.K = []
self.R = []
self.P = []
self.binning_x = 0
self.binning_y = 0
================================================
FILE: carla_bridge/core/geometry.py
================================================
from modules.data.proto.frame_pb2 import Vector3
class Twist:
def __init__(self):
self.linear = Vector3()
self.angular = Vector3()
class Accel:
def __init__(self):
self.linear = Vector3()
self.angular = Vector3()
================================================
FILE: carla_bridge/core/node.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2021 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
#
"""cyber node wraper"""
from cyber_py3 import cyber, cyber_time, cyber_timer, parameter
class CyberNode(object):
"""Cyber Node"""
def __init__(self, name, **kwargs):
self.kwargs = kwargs
self.cyber = cyber
self.cyber.init(name)
self.node = self.cyber.Node(name)
self.cyber_time = cyber_time
self.cyber_timer = cyber_timer
self.cyber_parameter = parameter
def get_param(self, name, alternative_value=None):
return self.cyber_parameter.Parameter(name, alternative_value)
def get_time(self):
return self.cyber_time.Time.now().to_sec()
def new_writer(self, name, data_type, qos_depth=1):
return self.node.create_writer(name, data_type, qos_depth)
def new_reader(self, name, data_type, callback, args=None):
return self.node.create_reader(name, data_type, callback, args)
def new_rate(self, frequency):
return self.cyber_time.Rate(frequency)
def new_timer(self, timer_period_sec, callback, oneshot=0):
return self.cyber_timer.Timer(timer_period_sec * 1000, callback, oneshot) # ms
def new_service(
self,
name: object,
req_type: object,
res_type: object,
callback: object,
args: object = None,
) -> object:
return self.node.create_service(name, req_type, res_type, callback, args)
def new_client(self, name, req_type, res_type):
return self.node.create_client(name, req_type, res_type)
def call_service(self, client, req):
response = client.send_request(req)
return response
def spin(self):
self.node.spin()
def destroy(self):
# del self.node
# self.shutdown()
pass
def ok(self):
return not self.cyber.is_shutdown()
def shutdown(self):
self.cyber.shutdown()
def wait_for_shutdown(self):
self.cyber.waitforshutdown()
def get_timestamp(self, sec=0, nsec=0, from_sec=False):
total = 0
if from_sec:
total = self.cyber_time.Time(float(sec)).to_nsec()
else:
total = self.cyber_time.Time(sec * 1000000000 + nsec)
secs = total / 1000000000
nsecs = total - secs * 1000000000
return {"secs": secs, "nsecs": nsecs}
================================================
FILE: carla_bridge/core/spawn_object_param.py
================================================
from modules.common_msgs.localization_msgs.pose_pb2 import Pose
class SpawnObjectParam:
def __init__(self):
self.type = None
self.id = None
self.attach_to = None
self.random_pose = None
self.transform = Pose()
self.attributes = []
class KeyValue:
def __init__(self, key, value):
self.key = key
self.value = value
================================================
FILE: carla_bridge/install.sh
================================================
#!/bin/bash
# Copy map files to /apollo/modules/map/data
cp -r map/. /apollo/modules/map/data
# Install requirements
pip3 install -r requirements.txt
# Set environment variables
if [ -f ~/.bashrc ] && ! grep -q 'export PYTHONPATH=$PYTHONPATH:/apollo/cyber' ~/.bashrc; then
echo 'export PYTHONPATH=$PYTHONPATH:/apollo/cyber' >> ~/.bashrc
echo 'export PYTHONPATH=$PYTHONPATH:/apollo/cyber/python' >> ~/.bashrc
echo 'export PYTHONPATH=$PYTHONPATH:/apollo' >> ~/.bashrc
echo 'export PYTHONPATH=$PYTHONPATH:/apollo/modules' >> ~/.bashrc
echo 'export PYTHONPATH=$PYTHONPATH:/apollo/modules/carla_bridge/carla_api/carla-0.9.14-py3.7-linux-x86_64.egg' >> ~/.bashrc
echo 'export PYTHONPATH=$PYTHONPATH:/apollo/bazel-bin' >> ~/.bashrc
fi
source ~/.bashrc
================================================
FILE: carla_bridge/main.py
================================================
#!/usr/bin/env python
#
# Copyright (c) 2023 synkrotron.ai
#
import os
import sys
import threading
from threading import Event, Thread
import carla
import yaml
from cyber.proto.clock_pb2 import Clock
from carla_bridge.core.actor_factory import ActorFactory
from carla_bridge.core.carla_spawn_objects import CarlaSpawnObjects
from carla_bridge.core.node import CyberNode
from carla_bridge.utils.logurus import init_log
sys.path.append("../")
class CarlaCyberBridge(CyberNode):
# in synchronous mode, if synchronous_mode_wait_for_vehicle_control_command is True,
# wait for this time until a next tick is triggered.
VEHICLE_CONTROL_TIMEOUT = 1.0
def __init__(self):
super().__init__("cyber_bridge_node")
self.spawn_objects_node = None
self.timestamp = None
self._registered_actors = None
self.on_tick_id = None
self.synchronous_mode_update_thread = None
self.clock_writer = None
self.actor_factory = None
self.sync_mode = None
self.carla_settings = None
self.shutdown = None
self.carla_world = None
self.carla_parameters = None
self.log = None
def initialize_bridge(self, carla_world, params, log):
"""
Initialize the bridge
"""
self.log = log
self.carla_parameters = params["carla"]
self.carla_world = carla_world
self.synchronous_mode_update_thread = None
self.shutdown = Event()
self.carla_settings = carla_world.get_settings()
if not self.carla_parameters["passive"]:
# workaround: settings can only applied within non-sync mode
if self.carla_settings.synchronous_mode:
self.carla_settings.synchronous_mode = False
carla_world.apply_settings(self.carla_settings)
self.carla_settings.synchronous_mode = self.carla_parameters[
"synchronous_mode"
]
self.carla_settings.fixed_delta_seconds = self.carla_parameters[
"fixed_delta_seconds"
]
carla_world.apply_settings(self.carla_settings)
self.sync_mode = (
self.carla_settings.synchronous_mode
and not self.carla_parameters["passive"]
)
# actor factory
self.actor_factory = ActorFactory(self, carla_world, self.log, self.sync_mode)
# Communication topics
self.clock_writer = self.new_writer("/clock", Clock, 10)
if self.sync_mode:
self.synchronous_mode_update_thread = Thread(
target=self._synchronous_mode_update
)
self.synchronous_mode_update_thread.daemo = True
self.synchronous_mode_update_thread.start()
self._registered_actors = []
carla_spawn_objects_thread = threading.Thread(
target=self.carla_spawn_objects
)
carla_spawn_objects_thread.daemo = True
carla_spawn_objects_thread.start()
self.spin()
def carla_spawn_objects(self):
self.spawn_objects_node = CarlaSpawnObjects(self)
self.spawn_objects_node.spawn_objects()
self.spawn_objects_node.bridge_node.spin()
def spawn_object(self, req):
if not self.shutdown.is_set():
id_ = self.actor_factory.spawn_actor(req)
self._registered_actors.append(id_)
def destroy_object(self, id_):
destroyed_actors = self.actor_factory.destroy_actor(id_)
success = bool(destroyed_actors)
for actor in destroyed_actors:
if actor in self._registered_actors:
self._registered_actors.remove(actor)
return success
def _synchronous_mode_update(self):
"""
execution loop for synchronous mode
"""
while not self.shutdown.is_set():
frame = self.carla_world.tick()
world_snapshot = self.carla_world.get_snapshot()
self.update_clock(world_snapshot.timestamp)
self._update(frame, world_snapshot.timestamp.elapsed_seconds)
self.actor_factory.update_available_objects()
def _update(self, frame_id, timestamp):
"""
update all actors
:return:
"""
self.actor_factory.update_actor_states(frame_id, timestamp)
def update_clock(self, carla_timestamp):
"""
perform the update of the clock
:param carla_timestamp: the current carla time
:type carla_timestamp: carla.Timestamp
:return:
"""
if self.ok():
self.timestamp = self.get_timestamp(
carla_timestamp.elapsed_seconds, from_sec=True
)
self.clock_writer.write(
Clock(clock=int(self.timestamp["secs"]))
)
def destroy(self):
"""
Function to destroy this object.
:return:
"""
self.log.info("Shutting down...")
if not self.sync_mode:
if self.on_tick_id:
self.carla_world.remove_on_tick(self.on_tick_id)
else:
self.synchronous_mode_update_thread.join()
self.log.info("Object update finished.")
for uid in self._registered_actors:
self.actor_factory.destroy_actor(uid)
self.actor_factory.update_available_objects()
self.actor_factory.clear()
super().destroy()
def main():
"""
main function for carla simulator Cyber bridge
maintaining the communication client and the CarlaBridge object
"""
log = init_log("bridge.log")
carla_client = None
carla_bridge = CarlaCyberBridge()
config_file = os.path.dirname(os.path.abspath(__file__)) + "/config/settings.yaml"
with open(config_file, encoding="utf-8") as f:
parameters = yaml.safe_load(f)
carla_parameters = parameters["carla"]
log.info(
f"Trying to connect to {carla_parameters['host']}:{carla_parameters['port']}"
)
try:
carla_client = carla.Client(
host=carla_parameters["host"], port=carla_parameters["port"]
)
carla_client.set_timeout(carla_parameters["timeout"])
carla_client.load_world(carla_parameters["town"])
carla_world = carla_client.get_world()
log.info(f"Connect to {carla_parameters['host']}:{carla_parameters['port']} successfully.")
carla_bridge.initialize_bridge(carla_world, parameters, log)
except (IOError, RuntimeError) as e:
log.error(f"Error: {e}")
except KeyboardInterrupt as e:
log.error(f"Error: {e}")
except Exception as e: # pylint: disable=W0718
log.error(e)
finally:
carla_world = carla_client.get_world()
settings = carla_world.get_settings()
settings.synchronous_mode = False
settings.fixed_delta_seconds = None
carla_world.apply_settings(settings)
log.warning("Shutting down.")
if carla_bridge.shutdown :
carla_bridge.shutdown.set()
carla_bridge.destroy()
del carla_world
del carla_client
if __name__ == "__main__":
main()
================================================
FILE: carla_bridge/map/carla_town01/base_map.txt
================================================
header {
version: "1"
date: "2020-07-29T12:17:19"
projection {
proj: "+proj=utm +zone=31 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"
}
rev_major: "1"
rev_minor: "4"
left: -28.359911988457576
top: 28.349990637833574
right: 422.68105762411665
bottom: -356.9099853515625
vendor: "VectorZero"
}
junction {
id {
id: "26"
}
polygon {
point {
x: 325.625595393236
y: -8.288677114909262
z: 0.0
}
point {
x: 328.5934056513511
y: -10.784984721874324
z: 0.0
}
point {
x: 345.1934026232685
y: -10.795011303203207
z: 0.0
}
point {
x: 348.2255922042358
y: -8.300683063420895
z: 0.0
}
point {
x: 348.23441073278866
y: 8.299314594216115
z: 0.0
}
point {
x: 325.63441392178885
y: 8.31132054272775
z: 0.0
}
}
}
junction {
id {
id: "54"
}
polygon {
point {
x: 144.95912459148906
y: -8.254469779052732
z: 0.0
}
point {
x: 147.76654828852003
y: -11.00990922391913
z: 0.0
}
point {
x: 164.3665360404592
y: -11.030074428339717
z: 0.0
}
point {
x: 168.0791244598076
y: -8.25693735964214
z: 0.0
}
point {
x: 168.08089616559408
y: 8.343062545811433
z: 0.0
}
point {
x: 144.96089629727555
y: 8.345530126400842
z: 0.0
}
}
}
junction {
id {
id: "87"
}
polygon {
point {
x: 79.63554392822466
y: -336.8772776243899
z: 0.0
}
point {
x: 101.6155407743753
y: -336.8890523094397
z: 0.0
}
point {
x: 101.6244333936577
y: -320.28905469132764
z: 0.0
}
point {
x: 98.71823624782861
y: -317.2987346310305
z: 0.0
}
point {
x: 82.11823643962383
y: -317.30125804165147
z: 0.0
}
point {
x: 79.64443654750706
y: -320.2772800062778
z: 0.0
}
}
}
junction {
id {
id: "110"
}
polygon {
point {
x: 79.3773068868187
y: 8.34227549917772
z: 0.0
}
point {
x: 79.38271698960446
y: -8.257723619219483
z: 0.0
}
point {
x: 82.07171143633269
y: -11.241261577846839
z: 0.0
}
point {
x: 98.67171124453748
y: -11.238738167225936
z: 0.0
}
point {
x: 102.69271575164295
y: -8.250126661633015
z: 0.0
}
point {
x: 102.68730564885719
y: 8.349872456764187
z: 0.0
}
}
}
junction {
id {
id: "143"
}
polygon {
point {
x: 325.71998576749917
y: -336.9099853515625
z: 0.0
}
point {
x: 347.7299857674992
y: -336.9099853515625
z: 0.0
}
point {
x: 347.7299857674992
y: -320.3099853515625
z: 0.0
}
point {
x: 345.0081766334904
y: -317.4549553639375
z: 0.0
}
point {
x: 328.40817966157294
y: -317.44492878260866
z: 0.0
}
point {
x: 325.71998576749917
y: -320.3099853515625
z: 0.0
}
}
}
junction {
id {
id: "171"
}
polygon {
point {
x: 82.07701819927098
y: -46.151261174499176
z: 0.0
}
point {
x: 82.08036247840712
y: -68.15126092031275
z: 0.0
}
point {
x: 98.68036228661191
y: -68.14873750969187
z: 0.0
}
point {
x: 101.39100732931327
y: -65.79866199480242
z: 0.0
}
point {
x: 101.38898457308427
y: -49.198662118041646
z: 0.0
}
point {
x: 98.67701800747577
y: -46.148737763878295
z: 0.0
}
}
}
junction {
id {
id: "194"
}
polygon {
point {
x: 325.6693259906662
y: -205.45911158707884
z: 0.0
}
point {
x: 328.47358800447086
y: -209.15494853628726
z: 0.0
}
point {
x: 345.0735849763883
y: -209.16497511761614
z: 0.0
}
point {
x: 345.0877852731981
y: -185.65497940618374
z: 0.0
}
point {
x: 328.48778830128066
y: -185.64495282485487
z: 0.0
}
point {
x: 325.67067489769096
y: -188.85911164188457
z: 0.0
}
}
}
junction {
id {
id: "222"
}
polygon {
point {
x: 325.15898291180446
y: -49.171395120369176
z: 0.0
}
point {
x: 325.1610056680335
y: -65.77139499712995
z: 0.0
}
point {
x: 328.5582280551707
y: -69.02497409804717
z: 0.0
}
point {
x: 345.1582250270881
y: -69.03500067937607
z: 0.0
}
point {
x: 345.17188171406684
y: -46.42500480377049
z: 0.0
}
point {
x: 328.5718847421494
y: -46.414978222441604
z: 0.0
}
}
}
junction {
id {
id: "255"
}
polygon {
point {
x: 82.09832733787567
y: -186.33125955486946
z: 0.0
}
point {
x: 82.1016716170118
y: -208.33125930068297
z: 0.0
}
point {
x: 98.70167142521659
y: -208.3287358900621
z: 0.0
}
point {
x: 101.41932673103875
y: -205.44088915332517
z: 0.0
}
point {
x: 101.42067563806356
y: -188.8408892081309
z: 0.0
}
point {
x: 98.69832714608046
y: -186.32873614424858
z: 0.0
}
}
}
junction {
id {
id: "278"
}
polygon {
point {
x: 325.636265085955
y: -139.81508423613286
z: 0.0
}
point {
x: 328.5131446798461
y: -143.66496048262036
z: 0.0
}
point {
x: 345.11314165176356
y: -143.67498706394923
z: 0.0
}
point {
x: 345.12708826398546
y: -120.58499127590271
z: 0.0
}
point {
x: 328.527091292068
y: -120.57496469457381
z: 0.0
}
point {
x: 325.6436818608219
y: -123.21508589301696
z: 0.0
}
}
}
junction {
id {
id: "306"
}
polygon {
point {
x: 82.08822001425015
y: -119.84126032309018
z: 0.0
}
point {
x: 82.09156429338628
y: -141.84126006890372
z: 0.0
}
point {
x: 98.69156410159107
y: -141.83873665828284
z: 0.0
}
point {
x: 101.41628746586791
y: -139.71490416019074
z: 0.0
}
point {
x: 101.42370424073472
y: -123.11490581707484
z: 0.0
}
point {
x: 98.68821982245494
y: -119.8387369124693
z: 0.0
}
}
}
junction {
id {
id: "332"
}
polygon {
point {
x: 144.98898424939568
y: -49.193349336620905
z: 0.0
}
point {
x: 144.99100700562468
y: -65.79334921338167
z: 0.0
}
point {
x: 167.17100684095922
y: -65.79064651861304
z: 0.0
}
point {
x: 167.16898408473023
y: -49.190646641852275
z: 0.0
}
point {
x: 164.32380038434377
y: -46.21004847130479
z: 0.0
}
point {
x: 147.7238126324046
y: -46.18988326688421
z: 0.0
}
}
}
lane {
id {
id: "road_0_lane_0_3"
}
central_curve {
segment {
line_segment {
point {
x: 348.2266546775554
y: -6.300683345633304
}
point {
x: 348.5866546267572
y: -6.3008745908308335
}
point {
x: 349.58665448565097
y: -6.30140582749064
}
point {
x: 350.58665434454474
y: -6.301937064150447
}
point {
x: 351.58665420343857
y: -6.302468300810254
}
point {
x: 352.58665406233234
y: -6.302999537470061
}
point {
x: 353.5866539212261
y: -6.303530774129868
}
point {
x: 354.58665378011995
y: -6.304062010789674
}
point {
x: 355.5866536390137
y: -6.304593247449481
}
point {
x: 356.58665349790755
y: -6.305124484109288
}
point {
x: 357.5866533568013
y: -6.305655720769095
}
point {
x: 358.58665321569515
y: -6.306186957428902
}
point {
x: 359.5866530745889
y: -6.306718194088709
}
point {
x: 360.5866529334827
y: -6.307249430748515
}
point {
x: 361.5866527923765
y: -6.307780667408322
}
point {
x: 362.5866526512703
y: -6.308311904068129
}
point {
x: 363.58665251016413
y: -6.3088431407279355
}
point {
x: 364.5866523690579
y: -6.309374377387742
}
point {
x: 365.5866522279517
y: -6.309905614047549
}
point {
x: 366.5866520868455
y: -6.310436850707356
}
point {
x: 367.5866519457393
y: -6.310968087367162
}
point {
x: 368.5866518046331
y: -6.311499324026969
}
point {
x: 369.5866516635269
y: -6.312030560686776
}
point {
x: 370.58665152242065
y: -6.312561797346583
}
point {
x: 371.5866513813145
y: -6.31309303400639
}
point {
x: 372.58665124020825
y: -6.313624270666197
}
point {
x: 373.5866510991021
y: -6.314155507326004
}
point {
x: 374.58665095799586
y: -6.31468674398581
}
point {
x: 375.58665081688963
y: -6.315217980645617
}
point {
x: 376.58665067578346
y: -6.315749217305424
}
point {
x: 377.58665053467723
y: -6.316280453965231
}
point {
x: 378.58665039357106
y: -6.316811690625038
}
point {
x: 379.58665025246484
y: -6.3173429272848445
}
point {
x: 380.5866501113586
y: -6.317874163944651
}
point {
x: 381.58664997025244
y: -6.318405400604457
}
point {
x: 382.5866498291462
y: -6.318936637264264
}
point {
x: 383.58664968804004
y: -6.319467873924071
}
point {
x: 384.5866495469338
y: -6.319999110583878
}
}
s: 0.0
start_position {
x: 348.2266546775554
y: -6.300683345633304
z: 0.0
}
length: 36.359999999999985
}
}
left_boundary {
curve {
segment {
line_segment {
point {
x: 348.22771715087504
y: -4.300683627845712
}
point {
x: 348.5877171000768
y: -4.300874873043242
}
point {
x: 349.5877169589706
y: -4.3014061097030485
}
point {
x: 350.58771681786436
y: -4.301937346362855
}
point {
x: 351.5877166767582
y: -4.302468583022662
}
point {
x: 352.58771653565196
y: -4.302999819682469
}
point {
x: 353.58771639454574
y: -4.303531056342276
}
point {
x: 354.58771625343957
y: -4.304062293002082
}
point {
x: 355.58771611233334
y: -4.304593529661889
}
point {
x: 356.58771597122717
y: -4.305124766321696
}
point {
x: 357.58771583012094
y: -4.305656002981503
}
point {
x: 358.5877156890148
y: -4.30618723964131
}
point {
x: 359.58771554790854
y: -4.306718476301117
}
point {
x: 360.5877154068023
y: -4.307249712960923
}
point {
x: 361.58771526569615
y: -4.30778094962073
}
point {
x: 362.5877151245899
y: -4.308312186280537
}
point {
x: 363.58771498348375
y: -4.308843422940344
}
point {
x: 364.5877148423775
y: -4.3093746596001505
}
point {
x: 365.5877147012713
y: -4.3099058962599575
}
point {
x: 366.5877145601651
y: -4.310437132919764
}
point {
x: 367.5877144190589
y: -4.31096836957957
}
point {
x: 368.5877142779527
y: -4.311499606239377
}
point {
x: 369.5877141368465
y: -4.312030842899184
}
point {
x: 370.5877139957403
y: -4.312562079558991
}
point {
x: 371.5877138546341
y: -4.313093316218798
}
point {
x: 372.5877137135279
y: -4.313624552878605
}
point {
x: 373.5877135724217
y: -4.314155789538412
}
point {
x: 374.5877134313155
y: -4.314687026198218
}
point {
x: 375.58771329020925
y: -4.315218262858025
}
point {
x: 376.5877131491031
y: -4.315749499517832
}
point {
x: 377.58771300799685
y: -4.316280736177639
}
point {
x: 378.5877128668907
y: -4.316811972837446
}
point {
x: 379.58771272578446
y: -4.317343209497253
}
point {
x: 380.58771258467823
y: -4.3178744461570595
}
point {
x: 381.58771244357206
y: -4.3184056828168655
}
point {
x: 382.58771230246583
y: -4.3189369194766725
}
point {
x: 383.58771216135966
y: -4.319468156136479
}
point {
x: 384.58771202025343
y: -4.319999392796286
}
}
s: 0.0
start_position {
x: 348.22771715087504
y: -4.300683627845712
z: 0.0
}
length: 36.359999999999985
}
}
length: 36.359999999999985
boundary_type {
s: 0.0
types: UNKNOWN
}
}
right_boundary {
curve {
segment {
line_segment {
point {
x: 348.2255922042358
y: -8.300683063420895
}
point {
x: 348.5855921534376
y: -8.300874308618425
}
point {
x: 349.58559201233135
y: -8.301405545278232
}
point {
x: 350.5855918712251
y: -8.30193678193804
}
point {
x: 351.58559173011895
y: -8.302468018597846
}
point {
x: 352.5855915890127
y: -8.302999255257653
}
point {
x: 353.5855914479065
y: -8.30353049191746
}
point {
x: 354.5855913068003
y: -8.304061728577267
}
point {
x: 355.5855911656941
y: -8.304592965237074
}
point {
x: 356.5855910245879
y: -8.30512420189688
}
point {
x: 357.5855908834817
y: -8.305655438556688
}
point {
x: 358.58559074237553
y: -8.306186675216495
}
point {
x: 359.5855906012693
y: -8.306717911876301
}
point {
x: 360.5855904601631
y: -8.307249148536107
}
point {
x: 361.5855903190569
y: -8.307780385195914
}
point {
x: 362.5855901779507
y: -8.30831162185572
}
point {
x: 363.5855900368445
y: -8.308842858515527
}
point {
x: 364.5855898957383
y: -8.309374095175334
}
point {
x: 365.58558975463205
y: -8.309905331835141
}
point {
x: 366.5855896135259
y: -8.310436568494948
}
point {
x: 367.58558947241966
y: -8.310967805154753
}
point {
x: 368.5855893313135
y: -8.31149904181456
}
point {
x: 369.58558919020726
y: -8.312030278474367
}
point {
x: 370.58558904910103
y: -8.312561515134174
}
point {
x: 371.58558890799486
y: -8.313092751793981
}
point {
x: 372.58558876688863
y: -8.313623988453788
}
point {
x: 373.58558862578246
y: -8.314155225113595
}
point {
x: 374.58558848467624
y: -8.314686461773402
}
point {
x: 375.58558834357
y: -8.315217698433209
}
point {
x: 376.58558820246384
y: -8.315748935093016
}
point {
x: 377.5855880613576
y: -8.316280171752823
}
point {
x: 378.58558792025144
y: -8.31681140841263
}
point {
x: 379.5855877791452
y: -8.317342645072436
}
point {
x: 380.585587638039
y: -8.317873881732243
}
point {
x: 381.5855874969328
y: -8.31840511839205
}
point {
x: 382.5855873558266
y: -8.318936355051857
}
point {
x: 383.5855872147204
y: -8.319467591711664
}
point {
x: 384.5855870736142
y: -8.319998828371471
}
}
s: 0.0
start_position {
x: 348.2255922042358
y: -8.300683063420895
z: 0.0
}
length: 36.359999999999985
}
}
length: 36.359999999999985
boundary_type {
s: 0.0
types: UNKNOWN
}
}
length: 36.359999999999985
speed_limit: 11.176
successor_id {
id: "road_11_lane_0_-3"
}
type: SIDEWALK
left_sample {
s: 0.0
width: 2.0000000000000004
}
left_sample {
s: 0.36000000000000654
width: 2.0000000000000004
}
left_sample {
s: 1.3600000000000065
width: 2.0000000000000004
}
left_sample {
s: 2.3600000000000065
width: 2.0000000000000004
}
left_sample {
s: 3.3600000000000065
width: 2.0000000000000004
}
left_sample {
s: 4.3600000000000065
width: 2.0000000000000004
}
left_sample {
s: 5.3600000000000065
width: 2.0000000000000004
}
left_sample {
s: 6.3600000000000065
width: 2.0000000000000004
}
left_sample {
s: 7.3600000000000065
width: 2.0000000000000004
}
left_sample {
s: 8.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 9.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 10.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 11.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 12.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 13.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 14.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 15.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 16.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 17.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 18.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 19.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 20.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 21.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 22.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 23.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 24.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 25.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 26.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 27.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 28.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 29.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 30.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 31.360000000000007
width: 2.0000000000000004
}
left_sample {
s: 32.36000000000001
width: 2.0000000000000004
}
left_sample {
s: 33.36000000000001
width: 2.0000000000000004
}
left_sample {
s: 34.36000000000001
width: 2.0000000000000004
}
left_sample {
s: 35.36000000000001
width: 2.0000000000000004
}
left_sample {
s: 36.36000000000001
width: 2.0000000000000004
}
right_sample {
s: 0.0
width: 2.0000000000000004
}
right_sample {
s: 0.36000000000000654
width: 2.0000000000000004
}
right_sample {
s: 1.3600000000000065
width: 2.0000000000000004
}
right_sample {
s: 2.3600000000000065
width: 2.0000000000000004
}
right_sample {
s: 3.3600000000000065
width: 2.0000000000000004
}
right_sample {
s: 4.3600000000000065
width: 2.0000000000000004
}
right_sample {
s: 5.3600000000000065
width: 2.0000000000000004
}
right_sample {
s: 6.3600000000000065
width: 2.0000000000000004
}
right_sample {
s: 7.3600000000000065
width: 2.0000000000000004
}
right_sample {
s: 8.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 9.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 10.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 11.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 12.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 13.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 14.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 15.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 16.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 17.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 18.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 19.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 20.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 21.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 22.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 23.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 24.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 25.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 26.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 27.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 28.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 29.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 30.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 31.360000000000007
width: 2.0000000000000004
}
right_sample {
s: 32.36000000000001
width: 2.0000000000000004
}
right_sample {
s: 33.36000000000001
width: 2.0000000000000004
}
right_sample {
s: 34.36000000000001
width: 2.0000000000000004
}
right_sample {
s: 35.36000000000001
width: 2.0000000000000004
}
right_sample {
s: 36.36000000000001
width: 2.0000000000000004
}
direction: FORWARD
}
lane {
id {
id: "road_0_lane_0_2"
}
central_curve {
segment {
line_segment {
point {
x: 348.227796836374
y: -4.1506836490116426
}
point {
x: 348.5877967855758
y: -4.150874894209172
}
point {
x: 349.58779664446956
y: -4.151406130868979
}
point {
x: 350.58779650336334
y: -4.151937367528786
}
point {
x: 351.58779636225717
y: -4.152468604188593
}
point {
x: 352.58779622115094
y: -4.1529998408484
}
point {
x: 353.5877960800447
y: -4.153531077508207
}
point {
x: 354.58779593893854
y: -4.154062314168013
}
point {
x: 355.5877957978323
y: -4.15459355082782
}
point {
x: 356.58779565672614
y: -4.155124787487627
}
point {
x: 357.5877955156199
y: -4.155656024147434
}
point {
x: 358.58779537451375
y: -4.156187260807241
}
point {
x: 359.5877952334075
y: -4.156718497467048
}
point {
x: 360.5877950923013
y: -4.157249734126854
}
point {
x: 361.5877949511951
y: -4.157780970786661
}
point {
x: 362.5877948100889
y: -4.158312207446468
}
point {
x: 363.5877946689827
y: -4.1588434441062745
}
point {
x: 364.5877945278765
y: -4.159374680766081
}
point {
x: 365.58779438677027
y: -4.159905917425888
}
point {
x: 366.5877942456641
y: -4.160437154085695
}
point {
x: 367.5877941045579
y: -4.160968390745501
}
point {
x: 368.5877939634517
y: -4.161499627405308
}
point {
x: 369.5877938223455
y: -4.162030864065115
}
point {
x: 370.58779368123925
y: -4.162562100724922
}
point {
x: 371.5877935401331
y: -4.163093337384729
}
point {
x: 372.58779339902685
y: -4.163624574044536
}
point {
x: 373.5877932579207
y: -4.164155810704343
}
point {
x: 374.58779311681445
y: -4.164687047364149
}
point {
x: 375.5877929757082
y: -4.165218284023956
}
point {
x: 376.58779283460206
y: -4.165749520683763
}
point {
x: 377.5877926934958
y: -4.16628075734357
}
point {
x: 378.58779255238966
y: -4.1668119940033765
}
point {
x: 379.58779241128343
y: -4.1673432306631835
}
point {
x: 380.5877922701772
y: -4.16787446732299
}
point {
x: 381.58779212907103
y: -4.168405703982796
}
point {
x: 382.5877919879648
y: -4.168936940642603
}
point {
x: 383.58779184685864
y: -4.16946817730241
}
point {
x: 384.5877917057524
y: -4.169999413962217
}
}
s: 0.0
start_position {
x: 348.227796836374
y: -4.1506836490116426
z: 0.0
}
length: 36.359999999999985
}
}
left_boundary {
curve {
segment {
line_segment {
point {
x: 348.227876521873
y: -4.000683670177573
}
point {
x: 348.58787647107476
y: -4.000874915375103
}
point {
x: 349.58787632996854
y: -4.00140615203491
}
point {
x: 350.5878761888623
y: -4.001937388694717
}
point {
x: 351.58787604775614
y: -4.002468625354524
}
point {
x: 352.5878759066499
y: -4.002999862014331
}
point {
x: 353.5878757655437
y: -4.003531098674138
}
point {
x: 354.5878756244375
y: -4.004062335333944
}
point {
x: 355.5878754833313
y: -4.004593571993751
}
point {
x: 356.5878753422251
y: -4.005124808653558
}
point {
x: 357.5878752011189
y: -4.005656045313365
}
point {
x: 358.5878750600127
y: -4.006187281973172
}
point {
x: 359.5878749189065
y: -4.006718518632979
}
point {
x: 360.58787477780027
y: -4.007249755292785
}
point {
x: 361.5878746366941
y: -4.0077809919525915
}
point {
x: 362.58787449558787
y: -4.008312228612398
}
point {
x: 363.5878743544817
y: -4.008843465272205
}
point {
x: 364.58787421337547
y: -4.009374701932012
}
point {
x: 365.58787407226924
y: -4.009905938591819
}
point {
x: 366.5878739311631
y: -4.010437175251626
}
point {
x: 367.58787379005685
y: -4.010968411911432
}
point {
x: 368.5878736489507
y: -4.011499648571239
}
point {
x: 369.58787350784445
y: -4.012030885231046
}
point {
x: 370.5878733667382
y: -4.012562121890853
}
point {
x: 371.58787322563205
y: -4.01309335855066
}
point {
x: 372.5878730845258
y: -4.013624595210467
}
point {
x: 373.58787294341965
y: -4.014155831870274
}
point {
x: 374.5878728023134
y: -4.0146870685
gitextract_4hezuig_/
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── discussion.md
│ │ ├── feature_request.md
│ │ ├── proposal.md
│ │ └── question.md
│ ├── pull_request_template.md
│ ├── scripts/
│ │ └── automerge.py
│ └── workflows/
│ └── issue_bot.yaml
├── .gitignore
├── .pre-commit-config.yaml
├── .pylintrc
├── LICENSE
├── README.md
├── carla_bridge/
│ ├── __init__.py
│ ├── actor/
│ │ ├── actor.py
│ │ ├── ego_vehicle.py
│ │ ├── pseudo_actor.py
│ │ ├── spectator.py
│ │ ├── static.py
│ │ ├── traffic.py
│ │ ├── traffic_participant.py
│ │ ├── vehicle.py
│ │ └── walker.py
│ ├── carla_api/
│ │ ├── carla-0.9.14-py3.7-linux-x86_64.egg
│ │ ├── controller.py
│ │ ├── global_route_planner.py
│ │ ├── local_planner.py
│ │ └── misc.py
│ ├── config/
│ │ ├── objects.json
│ │ └── settings.yaml
│ ├── core/
│ │ ├── actor_factory.py
│ │ ├── carla_spawn_objects.py
│ │ ├── carmera_info.py
│ │ ├── geometry.py
│ │ ├── node.py
│ │ └── spawn_object_param.py
│ ├── install.sh
│ ├── main.py
│ ├── map/
│ │ ├── carla_town01/
│ │ │ ├── base_map.txt
│ │ │ ├── routing_map.txt
│ │ │ └── sim_map.txt
│ │ ├── carla_town02/
│ │ │ ├── base_map.txt
│ │ │ ├── routing_map.txt
│ │ │ └── sim_map.txt
│ │ ├── carla_town04/
│ │ │ ├── base_map.txt
│ │ │ ├── routing_map.txt
│ │ │ └── sim_map.txt
│ │ ├── carla_town07/
│ │ │ ├── base_map.txt
│ │ │ ├── routing_map.txt
│ │ │ └── sim_map.txt
│ │ └── carla_town10hd/
│ │ ├── base_map.txt
│ │ ├── routing_map.txt
│ │ └── sim_map.txt
│ ├── refined_controller/
│ │ ├── control_conf.pb.txt
│ │ ├── mpc_controller.cc
│ │ └── mpc_controller.h
│ ├── requirements.txt
│ ├── sensor/
│ │ ├── camera.py
│ │ ├── gnss.py
│ │ ├── imu.py
│ │ ├── lidar.py
│ │ ├── object_sensor.py
│ │ ├── radar.py
│ │ ├── sensor.py
│ │ └── traffic_lights_sensor.py
│ └── utils/
│ ├── logurus.py
│ └── transforms.py
├── carla_scripts/
│ ├── carla-compose.yml
│ ├── docker_run_carla.sh
│ └── stop_carla.sh
└── docs/
├── GettingStarted.md
├── RefinedController.md
└── deployment_introduction.md
SYMBOL INDEX (271 symbols across 33 files)
FILE: .github/scripts/automerge.py
function fetch_pulls (line 25) | def fetch_pulls(mergeable_state, labels = {'automerge'}):
function is_approved (line 30) | def is_approved(pr):
FILE: carla_bridge/actor/actor.py
class Actor (line 16) | class Actor(PseudoActor):
method __init__ (line 21) | def __init__(self, uid, name, parent, node, carla_actor):
method destroy (line 40) | def destroy(self):
method get_current_cyber_pose (line 49) | def get_current_cyber_pose(self):
method get_current_cyber_transform (line 58) | def get_current_cyber_transform(self):
method get_current_cyber_twist_rotated (line 69) | def get_current_cyber_twist_rotated(self):
method get_current_cyber_twist (line 81) | def get_current_cyber_twist(self):
method get_current_cyber_accel (line 91) | def get_current_cyber_accel(self):
method get_id (line 101) | def get_id(self):
method set_carla_actor (line 109) | def set_carla_actor(self, carla_actor):
FILE: carla_bridge/actor/ego_vehicle.py
class EgoVehicle (line 27) | class EgoVehicle(Vehicle):
method __init__ (line 32) | def __init__(self, uid, name, parent, node, carla_actor, world):
method get_tf_msg (line 79) | def get_tf_msg(self):
method send_vehicle_msgs (line 98) | def send_vehicle_msgs(self):
method write_localization (line 129) | def write_localization(self):
method update (line 206) | def update(self, frame, timestamp):
method destroy (line 217) | def destroy(self):
method control_command_override (line 228) | def control_command_override(self, enable):
method control_command_updated (line 234) | def control_command_updated(self, cyber_vehicle_control, manual_overri...
method enable_autopilot_updated (line 267) | def enable_autopilot_updated(self, enable_auto_pilot):
method get_vector_length_squared (line 278) | def get_vector_length_squared(carla_vector):
method get_vehicle_speed_squared (line 291) | def get_vehicle_speed_squared(carla_vehicle):
method get_vehicle_speed_abs (line 302) | def get_vehicle_speed_abs(carla_vehicle):
FILE: carla_bridge/actor/pseudo_actor.py
class PseudoActor (line 16) | class PseudoActor(object):
method __init__ (line 21) | def __init__(self, uid, name, parent, node):
method destroy (line 49) | def destroy(self):
method get_blueprint_name (line 57) | def get_blueprint_name():
method get_msg_header (line 64) | def get_msg_header(self, frame_id=None, timestamp=None):
method get_prefix (line 81) | def get_prefix(self):
method get_topic_prefix (line 92) | def get_topic_prefix(self):
method update (line 101) | def update(self, frame, timestamp):
FILE: carla_bridge/actor/spectator.py
class Spectator (line 15) | class Spectator(Actor):
method __init__ (line 21) | def __init__(self, uid, name, parent, node, carla_actor):
FILE: carla_bridge/actor/static.py
class Static (line 20) | class Static(TrafficParticipant):
method __init__ (line 25) | def __init__(self, uid, name, parent, node, carla_actor):
method get_classification (line 45) | def get_classification(self):
FILE: carla_bridge/actor/traffic.py
class Traffic (line 21) | class Traffic(Actor):
method __init__ (line 26) | def __init__(self, uid, name, parent, node, carla_actor):
class TrafficLight (line 46) | class TrafficLight(Actor):
method __init__ (line 51) | def __init__(self, uid, name, parent, node, carla_actor):
method get_status (line 70) | def get_status(self):
method get_id (line 86) | def get_id(self):
FILE: carla_bridge/actor/traffic_participant.py
class TrafficParticipant (line 23) | class TrafficParticipant(Actor):
method __init__ (line 28) | def __init__(self, uid, name, parent, node, carla_actor):
method update (line 48) | def update(self, frame, timestamp):
method get_object_info (line 62) | def get_object_info(self):
method get_classification (line 101) | def get_classification(self): # pylint: disable=no-self-use
method get_marker_pose (line 107) | def get_marker_pose(self):
FILE: carla_bridge/actor/vehicle.py
class Vehicle (line 20) | class Vehicle(TrafficParticipant):
method __init__ (line 25) | def __init__(self, uid, name, parent, node, carla_actor):
method get_classification (line 57) | def get_classification(self):
FILE: carla_bridge/actor/walker.py
class Walker (line 20) | class Walker(TrafficParticipant):
method __init__ (line 25) | def __init__(self, uid, name, parent, node, carla_actor):
method get_classification (line 50) | def get_classification(self):
FILE: carla_bridge/carla_api/controller.py
class VehiclePIDController (line 18) | class VehiclePIDController:
method __init__ (line 25) | def __init__(
method run_step (line 68) | def run_step(self, target_speed, waypoint):
method change_longitudinal_pid (line 108) | def change_longitudinal_pid(self, args_longitudinal):
method change_lateral_pid (line 112) | def change_lateral_pid(self, args_lateral):
class PIDLongitudinalController (line 117) | class PIDLongitudinalController:
method __init__ (line 122) | def __init__(self, vehicle, K_P=1.0, K_I=0.0, K_D=0.0, dt=0.03):
method run_step (line 139) | def run_step(self, target_speed, debug=False):
method _pid_control (line 154) | def _pid_control(self, target_speed, current_speed):
method change_parameters (line 177) | def change_parameters(self, K_P, K_I, K_D, dt):
class PIDLateralController (line 185) | class PIDLateralController:
method __init__ (line 190) | def __init__(self, vehicle, offset=0, K_P=1.0, K_I=0.0, K_D=0.0, dt=0....
method run_step (line 210) | def run_step(self, waypoint):
method _pid_control (line 222) | def _pid_control(self, waypoint, vehicle_transform):
method change_parameters (line 269) | def change_parameters(self, K_P, K_I, K_D, dt):
FILE: carla_bridge/carla_api/global_route_planner.py
class GlobalRoutePlanner (line 21) | class GlobalRoutePlanner(object):
method __init__ (line 26) | def __init__(self, wmap, sampling_resolution):
method trace_route (line 43) | def trace_route(self, origin, destination):
method _build_topology (line 110) | def _build_topology(self):
method _build_graph (line 144) | def _build_graph(self):
method _find_loose_ends (line 214) | def _find_loose_ends(self):
method _lane_change_link (line 276) | def _lane_change_link(self):
method _localize (line 352) | def _localize(self, location):
method _distance_heuristic (line 367) | def _distance_heuristic(self, n1, n2):
method _path_search (line 376) | def _path_search(self, origin, destination):
method _successive_last_intersection_edge (line 397) | def _successive_last_intersection_edge(self, index, route):
method _turn_decision (line 424) | def _turn_decision(self, index, route, threshold=math.radians(35)):
method _find_closest_in_list (line 499) | def _find_closest_in_list(self, current_waypoint, waypoint_list):
FILE: carla_bridge/carla_api/local_planner.py
class RoadOption (line 18) | class RoadOption(Enum):
class LocalPlanner (line 33) | class LocalPlanner(object):
method __init__ (line 45) | def __init__(self, vehicle, opt_dict=None):
method reset_vehicle (line 118) | def reset_vehicle(self):
method _init_controller (line 122) | def _init_controller(self):
method set_speed (line 142) | def set_speed(self, speed):
method follow_speed_limits (line 156) | def follow_speed_limits(self, value=True):
method _compute_next_waypoints (line 165) | def _compute_next_waypoints(self, k=1):
method set_global_plan (line 194) | def set_global_plan(
method run_step (line 223) | def run_step(self, debug=False):
method get_incoming_waypoint_and_direction (line 281) | def get_incoming_waypoint_and_direction(self, steps=3):
method get_plan (line 297) | def get_plan(self):
method done (line 301) | def done(self):
function _retrieve_options (line 310) | def _retrieve_options(list_waypoints, current_waypoint):
function _compute_connection (line 332) | def _compute_connection(current_waypoint, next_waypoint, threshold=35):
FILE: carla_bridge/carla_api/misc.py
function draw_waypoints (line 17) | def draw_waypoints(world, waypoints, z=0.5):
function get_speed (line 33) | def get_speed(vehicle):
function get_trafficlight_trigger_location (line 45) | def get_trafficlight_trigger_location(traffic_light):
function is_within_distance (line 70) | def is_within_distance(
function compute_magnitude_angle (line 118) | def compute_magnitude_angle(target_location, current_location, orientati...
function distance_vehicle (line 144) | def distance_vehicle(waypoint, vehicle_transform):
function vector (line 158) | def vector(location_1, location_2):
function compute_distance (line 172) | def compute_distance(location_1, location_2):
function positive (line 185) | def positive(num):
FILE: carla_bridge/core/actor_factory.py
class ActorFactory (line 46) | class ActorFactory(object):
class TaskType (line 50) | class TaskType(Enum):
method __init__ (line 55) | def __init__(self, node, world, log, sync_mode=False, ):
method start (line 77) | def start(self):
method _update_thread (line 82) | def _update_thread(self):
method update_available_objects (line 91) | def update_available_objects(self):
method update_actor_states (line 129) | def update_actor_states(self, frame_id, timestamp):
method clear (line 142) | def clear(self):
method spawn_actor (line 147) | def spawn_actor(self, req):
method destroy_actor (line 169) | def destroy_actor(self, uid):
method _spawn_carla_actor (line 190) | def _spawn_carla_actor(self, req):
method _create_object_from_actor (line 218) | def _create_object_from_actor(self, carla_actor):
method _destroy_object (line 250) | def _destroy_object(self, actor_id, delete_actor):
method get_pseudo_sensor_types (line 263) | def get_pseudo_sensor_types(self):
method _create_object (line 270) | def _create_object(self, uid, type_id, name, attach_to, spawn_pose, ca...
FILE: carla_bridge/core/carla_spawn_objects.py
class CarlaSpawnObjects (line 34) | class CarlaSpawnObjects:
method __init__ (line 42) | def __init__(self, bridge_node):
method spawn_objects (line 55) | def spawn_objects(self):
method setup_vehicles (line 90) | def setup_vehicles(self, vehicles):
method setup_sensors (line 134) | def setup_sensors(self, sensors, attached_vehicle_id=None):
method create_spawn_point (line 221) | def create_spawn_point(self, x, y, z, roll, pitch, yaw):
method destroy (line 234) | def destroy(self):
FILE: carla_bridge/core/carmera_info.py
class CameraInfo (line 1) | class CameraInfo:
method __init__ (line 2) | def __init__(self):
FILE: carla_bridge/core/geometry.py
class Twist (line 4) | class Twist:
method __init__ (line 5) | def __init__(self):
class Accel (line 10) | class Accel:
method __init__ (line 11) | def __init__(self):
FILE: carla_bridge/core/node.py
class CyberNode (line 13) | class CyberNode(object):
method __init__ (line 16) | def __init__(self, name, **kwargs):
method get_param (line 26) | def get_param(self, name, alternative_value=None):
method get_time (line 29) | def get_time(self):
method new_writer (line 32) | def new_writer(self, name, data_type, qos_depth=1):
method new_reader (line 35) | def new_reader(self, name, data_type, callback, args=None):
method new_rate (line 38) | def new_rate(self, frequency):
method new_timer (line 41) | def new_timer(self, timer_period_sec, callback, oneshot=0):
method new_service (line 44) | def new_service(
method new_client (line 54) | def new_client(self, name, req_type, res_type):
method call_service (line 57) | def call_service(self, client, req):
method spin (line 61) | def spin(self):
method destroy (line 64) | def destroy(self):
method ok (line 69) | def ok(self):
method shutdown (line 72) | def shutdown(self):
method wait_for_shutdown (line 75) | def wait_for_shutdown(self):
method get_timestamp (line 78) | def get_timestamp(self, sec=0, nsec=0, from_sec=False):
FILE: carla_bridge/core/spawn_object_param.py
class SpawnObjectParam (line 4) | class SpawnObjectParam:
method __init__ (line 5) | def __init__(self):
class KeyValue (line 14) | class KeyValue:
method __init__ (line 15) | def __init__(self, key, value):
FILE: carla_bridge/main.py
class CarlaCyberBridge (line 23) | class CarlaCyberBridge(CyberNode):
method __init__ (line 29) | def __init__(self):
method initialize_bridge (line 45) | def initialize_bridge(self, carla_world, params, log):
method carla_spawn_objects (line 98) | def carla_spawn_objects(self):
method spawn_object (line 103) | def spawn_object(self, req):
method destroy_object (line 108) | def destroy_object(self, id_):
method _synchronous_mode_update (line 116) | def _synchronous_mode_update(self):
method _update (line 129) | def _update(self, frame_id, timestamp):
method update_clock (line 136) | def update_clock(self, carla_timestamp):
method destroy (line 152) | def destroy(self):
function main (line 172) | def main():
FILE: carla_bridge/refined_controller/mpc_controller.cc
type apollo (line 45) | namespace apollo {
type control (line 46) | namespace control {
function GetLogFileName (line 57) | std::string GetLogFileName() {
function WriteHeaders (line 69) | void WriteHeaders(std::ofstream &file_stream) {}
function Status (line 182) | Status MPCController::Init(std::shared_ptr<DependencyInjector> injec...
function Status (line 311) | Status MPCController::ComputeControlCommand(
function Status (line 579) | Status MPCController::Reset() {
FILE: carla_bridge/refined_controller/mpc_controller.h
function namespace (line 43) | namespace apollo {
FILE: carla_bridge/sensor/camera.py
class Camera (line 30) | class Camera(Sensor):
method __init__ (line 36) | def __init__(self, uid, name, parent, relative_spawn_pose, node, carla...
method destroy (line 76) | def destroy(self):
method get_topic_prefix (line 79) | def get_topic_prefix(self):
method _build_camera_info (line 88) | def _build_camera_info(self):
method sensor_data_updated (line 111) | def sensor_data_updated(self, carla_camera_data):
method get_cyber_transform (line 139) | def get_cyber_transform(self, pose, timestamp):
method get_image_data_array (line 164) | def get_image_data_array(self, carla_camera_data):
method get_carla_image_data_array (line 178) | def get_carla_image_data_array(self, carla_camera_data):
class RgbCamera (line 189) | class RgbCamera(Camera):
method __init__ (line 195) | def __init__(self, uid, name, parent, relative_spawn_pose, node, carla...
method get_carla_image_data_array (line 223) | def get_carla_image_data_array(self, carla_image):
class DepthCamera (line 242) | class DepthCamera(Camera):
method __init__ (line 248) | def __init__(self, uid, name, parent, relative_spawn_pose, node, carla...
method get_carla_image_data_array (line 276) | def get_carla_image_data_array(self, carla_image):
class SemanticSegmentationCamera (line 317) | class SemanticSegmentationCamera(Camera):
method __init__ (line 323) | def __init__(self, uid, name, parent, relative_spawn_pose, node, carla...
method get_carla_image_data_array (line 352) | def get_carla_image_data_array(self, carla_image):
class DVSCamera (line 372) | class DVSCamera(Camera):
method __init__ (line 378) | def __init__(self, uid, name, parent, relative_spawn_pose, node, carla...
method destroy (line 412) | def destroy(self):
method sensor_data_updated (line 415) | def sensor_data_updated(self, carla_dvs_event_array):
method get_carla_image_data_array (line 435) | def get_carla_image_data_array(self, carla_dvs_event_array):
FILE: carla_bridge/sensor/gnss.py
class Gnss (line 23) | class Gnss(Sensor):
method __init__ (line 29) | def __init__(
method get_topic_prefix (line 83) | def get_topic_prefix(self):
method sensor_data_updated (line 92) | def sensor_data_updated(self, carla_gnss_measurement): # pylint: disa...
FILE: carla_bridge/sensor/imu.py
class ImuSensor (line 17) | class ImuSensor(Sensor):
method __init__ (line 23) | def __init__(
method get_topic_prefix (line 66) | def get_topic_prefix(self):
method sensor_data_updated (line 76) | def sensor_data_updated(self, carla_imu_measurement):
FILE: carla_bridge/sensor/lidar.py
class Lidar (line 20) | class Lidar(Sensor):
method __init__ (line 26) | def __init__(self, uid, name, parent, relative_spawn_pose, node, carla...
method destroy (line 57) | def destroy(self):
method get_topic_prefix (line 60) | def get_topic_prefix(self):
method sensor_data_updated (line 70) | def sensor_data_updated(self, carla_lidar_measurement):
class SemanticLidar (line 112) | class SemanticLidar(Sensor):
method __init__ (line 118) | def __init__(self, uid, name, parent, relative_spawn_pose, node, carla...
method destroy (line 150) | def destroy(self):
method sensor_data_updated (line 154) | def sensor_data_updated(self, carla_lidar_measurement):
FILE: carla_bridge/sensor/object_sensor.py
class ObjectSensor (line 22) | class ObjectSensor(PseudoActor):
method __init__ (line 27) | def __init__(self, uid, name, parent, node, actor_list):
method destroy (line 49) | def destroy(self):
method get_topic_prefix (line 57) | def get_topic_prefix(self):
method get_blueprint_name (line 67) | def get_blueprint_name():
method update (line 74) | def update(self, frame, timestamp): # pylint: disable=W0613
FILE: carla_bridge/sensor/radar.py
class Radar (line 19) | class Radar(Sensor):
method __init__ (line 25) | def __init__(self, uid, name, parent, relative_spawn_pose, node, carla...
method destroy (line 54) | def destroy(self):
method get_topic_prefix (line 57) | def get_topic_prefix(self):
method sensor_data_updated (line 66) | def sensor_data_updated(self, carla_radar_measurement):
FILE: carla_bridge/sensor/sensor.py
class Sensor (line 30) | class Sensor(Actor):
method __init__ (line 35) | def __init__(
method get_cyber_transform (line 87) | def get_cyber_transform(self, pose, timestamp): # pylint: disable=W0613
method write_tf (line 121) | def write_tf(self, pose, timestamp):
method listen (line 125) | def listen(self):
method destroy (line 128) | def destroy(self):
method _callback_sensor_data (line 142) | def _callback_sensor_data(self, carla_sensor_data):
method sensor_data_updated (line 169) | def sensor_data_updated(self, carla_sensor_data):
method _update_synchronous_event_sensor (line 181) | def _update_synchronous_event_sensor(
method _update_synchronous_sensor (line 200) | def _update_synchronous_sensor(self, frame, timestamp):
method update (line 232) | def update(self, frame, timestamp):
function create_cloud (line 245) | def create_cloud(header, points):
function create_radar (line 270) | def create_radar(header, contiobs):
FILE: carla_bridge/sensor/traffic_lights_sensor.py
class TrafficLightsSensor (line 20) | class TrafficLightsSensor(PseudoActor):
method __init__ (line 25) | def __init__(self, uid, name, parent, node, actor_list, log):
method destroy (line 48) | def destroy(self):
method get_topic_prefix (line 56) | def get_topic_prefix(self):
method get_blueprint_name (line 66) | def get_blueprint_name():
method update (line 73) | def update(self, frame, timestamp): # pylint: disable=W0613
FILE: carla_bridge/utils/logurus.py
function init_log (line 13) | def init_log(
function demo (line 27) | def demo():
FILE: carla_bridge/utils/transforms.py
function carla_location_to_numpy_vector (line 27) | def carla_location_to_numpy_vector(carla_location):
function carla_location_to_cyber_vector3 (line 42) | def carla_location_to_cyber_vector3(carla_location):
function carla_location_to_cyber_point3d (line 62) | def carla_location_to_cyber_point3d(carla_location):
function carla_location_to_cyber_point (line 82) | def carla_location_to_cyber_point(carla_location):
function carla_rotation_to_rpy (line 102) | def carla_rotation_to_rpy(carla_rotation):
function carla_rotation_to_cyber_quaternion (line 122) | def carla_rotation_to_cyber_quaternion(carla_rotation):
function carla_rotation_to_numpy_rotation_matrix (line 141) | def carla_rotation_to_numpy_rotation_matrix(carla_rotation):
function carla_rotation_to_directional_numpy_vector (line 160) | def carla_rotation_to_directional_numpy_vector(carla_rotation):
function carla_vector_to_cyber_vector_rotated (line 177) | def carla_vector_to_cyber_vector_rotated(carla_vector, carla_rotation):
function carla_velocity_to_cyber_twist (line 199) | def carla_velocity_to_cyber_twist(
function carla_velocity_to_numpy_vector (line 228) | def carla_velocity_to_numpy_vector(carla_velocity):
function carla_acceleration_to_cyber_accel (line 243) | def carla_acceleration_to_cyber_accel(carla_acceleration):
function carla_transform_to_cyber_transform (line 264) | def carla_transform_to_cyber_transform(carla_transform):
function carla_transform_to_cyber_pose (line 287) | def carla_transform_to_cyber_pose(carla_transform):
function carla_location_to_pose (line 310) | def carla_location_to_pose(carla_location):
function cyber_point_to_carla_location (line 328) | def cyber_point_to_carla_location(cyber_point):
function rpy_to_carla_rotation (line 334) | def rpy_to_carla_rotation(roll, pitch, yaw):
function cyber_quaternion_to_carla_rotation (line 340) | def cyber_quaternion_to_carla_rotation(cyber_quaternion):
function cyber_pose_to_carla_transform (line 352) | def cyber_pose_to_carla_transform(cyber_pose):
function transform_matrix_to_cyber_pose (line 362) | def transform_matrix_to_cyber_pose(mat):
function cyber_pose_to_transform_matrix (line 373) | def cyber_pose_to_transform_matrix(msg):
function cyber_quaternion_to_cyber_euler (line 385) | def cyber_quaternion_to_cyber_euler(cyber_quaternion):
function n2b (line 397) | def n2b(x_radius, y_radius, z_radius, b):
Copy disabled (too large)
Download .json
Condensed preview — 74 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (59,722K chars).
[
{
"path": ".gitattributes",
"chars": 84,
"preview": "*.whl filter=lfs diff=lfs merge=lfs -text\n*.egg filter=lfs diff=lfs merge=lfs -text\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 1886,
"preview": "---\nname: Bug report\nabout: Report a bug in carla_apollo_bridge\ntitle: ''\nlabels: kind/bug\nassignees: ''\n\n---\n\n## Descri"
},
{
"path": ".github/ISSUE_TEMPLATE/discussion.md",
"chars": 255,
"preview": "---\nname: Discussion\nabout: Start a discussion for carla_apollo_bridge\ntitle: ''\nlabels: kind/discussion\nassignees: ''\n-"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 797,
"preview": "---\nname: Feature Request\nabout: Create a Feature Request for carla_apollo_bridge\ntitle: ''\nlabels: kind/enhancement\nass"
},
{
"path": ".github/ISSUE_TEMPLATE/proposal.md",
"chars": 587,
"preview": "---\nname: Proposal\nabout: Create a technical proposal for carla_apollo_bridge\ntitle: ''\nlabels: kind/proposal\nassignees:"
},
{
"path": ".github/ISSUE_TEMPLATE/question.md",
"chars": 483,
"preview": "---\nname: Question\nabout: Ask a question about carla_apollo_bridge\ntitle: ''\nlabels: kind/question\nassignees: ''\n\n---\n\n*"
},
{
"path": ".github/pull_request_template.md",
"chars": 972,
"preview": "# Description\n\n<!--\nPlease explain the changes you've made.\n-->\n\n## Issue reference\n\n<!--\nWe strive to have all PR being"
},
{
"path": ".github/scripts/automerge.py",
"chars": 2496,
"preview": "#\n# Copyright 2021 The carla_apollo_bridge Authors\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": ".github/workflows/issue_bot.yaml",
"chars": 704,
"preview": "name: Close inactive issues\non:\n schedule:\n - cron: \"30 1 * * *\"\n\njobs:\n close-issues:\n runs-on: ubuntu-latest\n "
},
{
"path": ".gitignore",
"chars": 1845,
"preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# log\n*.log.*\n\n# C extensions\n#*.so\n\n# Distri"
},
{
"path": ".pre-commit-config.yaml",
"chars": 548,
"preview": "repos:\n - repo: https://kgithub.com/PyCQA/isort.git\n rev: 5.12.0 # Use the revision sha / tag you want to point at\n "
},
{
"path": ".pylintrc",
"chars": 13992,
"preview": "# This Pylint rcfile contains a best-effort configuration to uphold the\n# best-practices and style described in the Goog"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 6304,
"preview": "<a name=\"readme-top\"></a>\n\n\n<!-- PROJECT LOGO -->\n<br />\n<div align=\"center\">\n <!-- <a href=\"https://github.com/othneil"
},
{
"path": "carla_bridge/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "carla_bridge/actor/actor.py",
"chars": 3142,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2018-2019 Intel Corporation\n#\n# This work is licensed under the terms of the MI"
},
{
"path": "carla_bridge/actor/ego_vehicle.py",
"chars": 12525,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2018-2020 Intel Corporation\n#\n# This work is licensed under the terms of the MI"
},
{
"path": "carla_bridge/actor/pseudo_actor.py",
"chars": 2832,
"preview": "#!/usr/bin/env python\n#\n# Copyright (c) 2019 Intel Corporation\n#\n# This work is licensed under the terms of the MIT lice"
},
{
"path": "carla_bridge/actor/spectator.py",
"chars": 1094,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2018-2019 Intel Corporation\n#\n# This work is licensed under the terms of the MI"
},
{
"path": "carla_bridge/actor/static.py",
"chars": 1365,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2018-2019 Intel Corporation\n#\n# This work is licensed under the terms of the MI"
},
{
"path": "carla_bridge/actor/traffic.py",
"chars": 2719,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2018-2019 Intel Corporation\n#\n# This work is licensed under the terms of the MI"
},
{
"path": "carla_bridge/actor/traffic_participant.py",
"chars": 3464,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2019 Intel Corporation\n#\n# This work is licensed under the terms of the MIT lic"
},
{
"path": "carla_bridge/actor/vehicle.py",
"chars": 2071,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2018-2019 Intel Corporation\n#\n# This work is licensed under the terms of the MI"
},
{
"path": "carla_bridge/actor/walker.py",
"chars": 1389,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2018-2019 Intel Corporation\n#\n# This work is licensed under the terms of the MI"
},
{
"path": "carla_bridge/carla_api/controller.py",
"chars": 9298,
"preview": "# Copyright (c) # Copyright (c) 2018-2020 CVC.\n#\n# This work is licensed under the terms of the MIT license.\n# For a cop"
},
{
"path": "carla_bridge/carla_api/global_route_planner.py",
"chars": 21444,
"preview": "# Copyright (c) # Copyright (c) 2018-2020 CVC.\n#\n# This work is licensed under the terms of the MIT license.\n# For a cop"
},
{
"path": "carla_bridge/carla_api/local_planner.py",
"chars": 13240,
"preview": "# Copyright (c) # Copyright (c) 2018-2020 CVC.\n#\n# This work is licensed under the terms of the MIT license.\n# For a cop"
},
{
"path": "carla_bridge/carla_api/misc.py",
"chars": 5971,
"preview": "#!/usr/bin/env python\n\n# Copyright (c) 2018 Intel Labs.\n# authors: German Ros (german.ros@intel.com)\n#\n# This work is li"
},
{
"path": "carla_bridge/config/objects.json",
"chars": 3047,
"preview": "{\n \"objects\":\n [\n {\n \"type\": \"sensor.pseudo.traffic_lights\",\n \"id\": \"traffic_lights\"\n"
},
{
"path": "carla_bridge/config/settings.yaml",
"chars": 284,
"preview": "carla:\n host: '172.17.0.1'\n port: 2000\n timeout: 30\n passive: False\n synchronous_mode: True\n synchronous_mode_wait"
},
{
"path": "carla_bridge/core/actor_factory.py",
"chars": 15537,
"preview": "#!/usr/bin/env python\n#\n# Copyright (c) 2020 Intel Corporation\n#\n# This work is licensed under the terms of the MIT lice"
},
{
"path": "carla_bridge/core/carla_spawn_objects.py",
"chars": 10236,
"preview": "#!/usr/bin/env python\n#\n# Copyright (c) 2019-2020 Intel Corporation\n#\n# This work is licensed under the terms of the MIT"
},
{
"path": "carla_bridge/core/carmera_info.py",
"chars": 203,
"preview": "class CameraInfo:\n\tdef __init__(self):\n\t\tself.height = 0\n\t\tself.width = 0\n\t\tself.distortion_model = ''\n\t\tself.D = []\n\t\ts"
},
{
"path": "carla_bridge/core/geometry.py",
"chars": 229,
"preview": "from modules.data.proto.frame_pb2 import Vector3\n\n\nclass Twist:\n\tdef __init__(self):\n\t\tself.linear = Vector3()\n\t\tself.an"
},
{
"path": "carla_bridge/core/node.py",
"chars": 2487,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2021 Intel Corporation\n#\n# This work is licensed under the terms of the MIT lic"
},
{
"path": "carla_bridge/core/spawn_object_param.py",
"chars": 341,
"preview": "from modules.common_msgs.localization_msgs.pose_pb2 import Pose\n\n\nclass SpawnObjectParam:\n\tdef __init__(self):\n\t\tself.ty"
},
{
"path": "carla_bridge/install.sh",
"chars": 771,
"preview": "#!/bin/bash\n\n# Copy map files to /apollo/modules/map/data\ncp -r map/. /apollo/modules/map/data\n\n# Install requirements\np"
},
{
"path": "carla_bridge/main.py",
"chars": 7153,
"preview": "#!/usr/bin/env python\n#\n# Copyright (c) 2023 synkrotron.ai\n#\n\nimport os\nimport sys\nimport threading\nfrom threading impor"
},
{
"path": "carla_bridge/map/carla_town01/base_map.txt",
"chars": 9423265,
"preview": "header {\n version: \"1\"\n date: \"2020-07-29T12:17:19\"\n projection {\n proj: \"+proj=utm +zone=31 +ellps=WGS84 +datum=W"
},
{
"path": "carla_bridge/map/carla_town01/routing_map.txt",
"chars": 703912,
"preview": "hdmap_version: \"1\"\nhdmap_district: \"\"\nnode {\n lane_id: \"road_0_lane_0_1\"\n length: 36.359999999999985\n left_out {\n "
},
{
"path": "carla_bridge/map/carla_town01/sim_map.txt",
"chars": 2047726,
"preview": "header {\n version: \"1\"\n date: \"2020-07-29T12:17:19\"\n projection {\n proj: \"+proj=utm +zone=31 +ellps=WGS84 +datum=W"
},
{
"path": "carla_bridge/map/carla_town02/base_map.txt",
"chars": 4745814,
"preview": "header {\n version: \"1\"\n date: \"2020-07-29T11:48:28\"\n projection {\n proj: \"+proj=utm +zone=31 +ellps=WGS84 +datum=W"
},
{
"path": "carla_bridge/map/carla_town02/routing_map.txt",
"chars": 379914,
"preview": "hdmap_version: \"1\"\nhdmap_district: \"\"\nnode {\n lane_id: \"road_0_lane_0_1\"\n length: 95.4627025723642\n left_out {\n st"
},
{
"path": "carla_bridge/map/carla_town02/sim_map.txt",
"chars": 1282969,
"preview": "header {\n version: \"1\"\n date: \"2020-07-29T11:48:28\"\n projection {\n proj: \"+proj=utm +zone=31 +ellps=WGS84 +datum=W"
},
{
"path": "carla_bridge/map/carla_town04/routing_map.txt",
"chars": 3562350,
"preview": "hdmap_version: \"1\"\nhdmap_district: \"\"\nnode {\n lane_id: \"road_0_lane_0_1\"\n length: 34.809999999999995\n cost: 12.313844"
},
{
"path": "carla_bridge/map/carla_town04/sim_map.txt",
"chars": 7949690,
"preview": "header {\n version: \"1\"\n date: \"2020-07-31T15:50:54\"\n projection {\n proj: \"+proj=utm +zone=31 +ellps=WGS84 +datum=W"
},
{
"path": "carla_bridge/map/carla_town07/base_map.txt",
"chars": 10371201,
"preview": "header {\n version: \"1\"\n date: \"2020-07-27T18:56:40\"\n projection {\n proj: \"+proj=utm +zone=31 +ellps=WGS84 +datum=W"
},
{
"path": "carla_bridge/map/carla_town07/routing_map.txt",
"chars": 932447,
"preview": "hdmap_version: \"1\"\nhdmap_district: \"\"\nnode {\n lane_id: \"road_0_lane_0_1\"\n length: 33.800000000000018\n cost: 11.956562"
},
{
"path": "carla_bridge/map/carla_town07/sim_map.txt",
"chars": 3822346,
"preview": "header {\n version: \"1\"\n date: \"2020-07-27T18:56:40\"\n projection {\n proj: \"+proj=utm +zone=31 +ellps=WGS84 +datum=W"
},
{
"path": "carla_bridge/map/carla_town10hd/base_map.txt",
"chars": 7940085,
"preview": "header {\n version: \"1\"\n date: \"2020-07-28T22:34:58\"\n projection {\n proj: \"+proj=utm +zone=31 +ellps=WGS84 +datum=W"
},
{
"path": "carla_bridge/map/carla_town10hd/routing_map.txt",
"chars": 753116,
"preview": "hdmap_version: \"1\"\nhdmap_district: \"\"\nnode {\n lane_id: \"road_0_lane_0_2\"\n length: 13.35169493020487\n left_out {\n s"
},
{
"path": "carla_bridge/map/carla_town10hd/sim_map.txt",
"chars": 2541999,
"preview": "header {\n version: \"1\"\n date: \"2020-07-28T22:34:58\"\n projection {\n proj: \"+proj=utm +zone=31 +ellps=WGS84 +datum=W"
},
{
"path": "carla_bridge/refined_controller/control_conf.pb.txt",
"chars": 320854,
"preview": "control_test_duration: -1\nenable_csv_debug: false\nenable_speed_station_preview: false\nis_control_test_mode: false\nuse_pr"
},
{
"path": "carla_bridge/refined_controller/mpc_controller.cc",
"chars": 31457,
"preview": "/******************************************************************************\n * Copyright 2017 The Apollo Authors. Al"
},
{
"path": "carla_bridge/refined_controller/mpc_controller.h",
"chars": 9571,
"preview": "/******************************************************************************\n * Copyright 2017 The Apollo Authors. Al"
},
{
"path": "carla_bridge/requirements.txt",
"chars": 97,
"preview": "--index-url https://pypi.tuna.tsinghua.edu.cn/simple\n\nloguru==0.7.0\nnetworkx\ntransforms3d==0.4.1\n"
},
{
"path": "carla_bridge/sensor/camera.py",
"chars": 18551,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2018-2019 Intel Corporation\n#\n# This work is licensed under the terms of the MI"
},
{
"path": "carla_bridge/sensor/gnss.py",
"chars": 4844,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2018-2019 Intel Corporation\n#\n# This work is licensed under the terms of the MI"
},
{
"path": "carla_bridge/sensor/imu.py",
"chars": 3535,
"preview": "#!usr/bin/env python\n#\n# This work is licensed under the terms of the MIT license.\n# For a copy, see <https://opensource"
},
{
"path": "carla_bridge/sensor/lidar.py",
"chars": 7125,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2018, Willow Garage, Inc.\n# Copyright (c) 2018-2019 Intel Corporation\n#\n# This "
},
{
"path": "carla_bridge/sensor/object_sensor.py",
"chars": 3173,
"preview": "#!/usr/bin/env python\n#\n# Copyright (c) 2019 Intel Corporation\n#\n# This work is licensed under the terms of the MIT lice"
},
{
"path": "carla_bridge/sensor/radar.py",
"chars": 3992,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2019-2020 Intel Corporation\n#\n# This work is licensed under the terms of the MI"
},
{
"path": "carla_bridge/sensor/sensor.py",
"chars": 9563,
"preview": "#!/usr/bin/env python\n#\n# Copyright (c) 2018-2019 Intel Corporation\n#\n# This work is licensed under the terms of the MIT"
},
{
"path": "carla_bridge/sensor/traffic_lights_sensor.py",
"chars": 2602,
"preview": "#!/usr/bin/env python\n#\n# Copyright (c) 2020 Intel Corporation\n#\n# This work is licensed under the terms of the MIT lice"
},
{
"path": "carla_bridge/utils/logurus.py",
"chars": 1139,
"preview": "#!/usr/bin/env python\n\"\"\"\n/*******************************************************************************\n * SYNKROTRON"
},
{
"path": "carla_bridge/utils/transforms.py",
"chars": 12868,
"preview": "#!/usr/bin/env python\n\n#\n# Copyright (c) 2018-2019 Intel Corporation\n#\n# This work is licensed under the terms of the MI"
},
{
"path": "carla_scripts/carla-compose.yml",
"chars": 827,
"preview": "version: '3.7'\nservices:\n simulator:\n image: carlasim/carla:0.9.14\n logging:\n options:\n "
},
{
"path": "carla_scripts/docker_run_carla.sh",
"chars": 53,
"preview": "docker-compose -f carla-compose.yml -p carla up -d\n"
},
{
"path": "carla_scripts/stop_carla.sh",
"chars": 50,
"preview": "docker-compose -f carla-compose.yml -p carla down\n"
},
{
"path": "docs/GettingStarted.md",
"chars": 5382,
"preview": "\n<!-- GETTING STARTED -->\n## Getting Started\n\n### Prerequisites\n\nWe will run Carla and Apollo in docker. Furthermore, NV"
},
{
"path": "docs/RefinedController.md",
"chars": 5313,
"preview": "## Demo Video\n\nFollowings are the demo videos showing the performance of improved controller.\n\nDemo: turn left - 90-degr"
},
{
"path": "docs/deployment_introduction.md",
"chars": 2146,
"preview": "# Deployment Introduction\n\nTo make the Carla Apollo Bridge work properly, you need to start the following three containe"
}
]
// ... and 2 more files (download for full content)
About this extraction
This page contains the full source code of the guardstrikelab/carla_apollo_bridge GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 74 files (111.0 MB), approximately 14.3M tokens, and a symbol index with 271 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.