Updating Docker pipeline to rebuild pedestrian binary for navigation

This commit is contained in:
bernatx 2019-12-03 18:27:11 +01:00 committed by bernat
parent 039e6be501
commit 00b901c9e2
12 changed files with 590 additions and 1 deletions

View File

@ -0,0 +1,32 @@
echo "Building FBX2OBJ"
echo "----------------"
FBXSDK_URL=https://www.autodesk.com/content/dam/autodesk/www/adn/fbx/2020-0-1/fbx202001_fbxsdk_linux.tar.gz
cd Util/DockerUtils
mkdir dist
cp . dist/ -r
cd dist
cd fbx
echo "Download FBX SDK 2020"
wget -c ${FBXSDK_URL} -O fbx202001_fbxsdk_linux.tar.gz
echo "Unpacking"
tar -xvzf fbx202001_fbxsdk_linux.tar.gz
rm fbx202001_fbxsdk_linux.tar.gz
echo "Installing"
printf "y\nyes\nn\n" | ./fbx202001_fbxsdk_linux
rm fbx202001_fbxsdk_linux
echo "Compiling FBX2OBJ..."
mkdir build
cd build
cmake ..
make
echo "Copy binary FBX2OBJ"
mv FBX2OBJ ../..
cd ../..
rm -Rf build

View File

@ -235,6 +235,9 @@ def import_assets_from_json_list(json_list):
# segmentation
move_assets_commandlet(package_name, maps)
# we need to build the binary file for navigation of pedestrians
build_binary_for_navigation(package_name, dirname, maps)
# We prepare only the maps for cooking after moving them. Props cooking will be done from Package.sh script.
prepare_maps_commandlet_for_cooking(package_name, only_prepare_maps=True)
@ -257,6 +260,67 @@ def move_assets_commandlet(package_name, maps):
invoke_commandlet(commandlet_name, commandlet_arguments)
# build the binary file for navigation of pedestrians for that map
def build_binary_for_navigation(package_name, dirname, maps):
folder = os.path.join(CARLA_ROOT_PATH, "Util", "DockerUtils", "dist")
# process each map
for umap in maps:
# get source and target names (package name only)
head, tail = os.path.split(umap["source"])
source_name = tail.replace(".fbx", "")
target_name = umap["name"]
# copy the XODR file into docker utils folder
if "xodr" in umap and umap["xodr"] and os.path.isfile(os.path.join(dirname, umap["xodr"])):
# Make sure the `.xodr` file have the same name than the `.umap`
xodr_path_source = os.path.abspath(os.path.join(dirname, umap["xodr"]))
xodr_name = '.'.join([target_name, "xodr"])
xodr_path_target = os.path.join(folder, xodr_name)
# copy
print('Copying "' + xodr_path_source + '" to "' + xodr_path_target + '"')
shutil.copy2(xodr_path_source, xodr_path_target)
# copy the FBX file into docker utils folder
if "source" in umap and umap["source"] and os.path.isfile(os.path.join(dirname, umap["source"])):
# Make sure the `.fbx` file have the same name than the `.umap`
fbx_path_source = os.path.abspath(os.path.join(dirname, umap["source"]))
fbx_name = '.'.join([target_name, "fbx"])
fbx_path_target = os.path.join(folder, fbx_name)
# copy
print('Copying "' + fbx_path_source + '" to "' + fbx_path_target + '"')
shutil.copy2(fbx_path_source, fbx_path_target)
# make the conversion
if os.name == "nt":
subprocess.call(["%s\\build.bat" % folder, target_name], cwd=folder, shell=True)
else:
subprocess.call(["chmod +x %s/build.sh" % folder], cwd=folder, shell=True)
subprocess.call(["%s/build.sh" % folder, target_name], cwd=folder, shell=True)
# copy the binary file
nav_folder_target = os.path.join(
CARLA_ROOT_PATH,
"Unreal",
"CarlaUE4",
"Content",
package_name,
"Maps",
target_name,
"Nav")
if not os.path.exists(nav_folder_target):
os.makedirs(nav_folder_target)
nav_path_source = os.path.join(folder, "%s.bin" % target_name)
nav_path_target = os.path.join(nav_folder_target, "%s.bin" % target_name)
print('Copying "' + nav_path_source + '" to "' + nav_path_target + '"')
shutil.copy2(nav_path_source, nav_path_target)
# remove files
os.remove(fbx_path_target)
os.remove(xodr_path_target)
def main():
import_folder = os.path.join(CARLA_ROOT_PATH, "Import")

View File

@ -139,3 +139,7 @@ deploy:
pretty:
@${CARLA_BUILD_TOOLS_FOLDER}/Prettify.sh $(ARGS)
build.utils:
@chmod +x ${CARLA_BUILD_TOOLS_FOLDER}/BuildUtilsDocker.sh
@${CARLA_BUILD_TOOLS_FOLDER}/BuildUtilsDocker.sh

View File

@ -10,6 +10,8 @@ RUN cd /home/ue4 && \
cd /home/ue4/carla && \
./Update.sh && \
make CarlaUE4Editor && \
make PythonAPI && \
make build.utils && \
make package && \
rm -r /home/ue4/carla/Dist

View File

@ -33,6 +33,7 @@ RUN apt-get update ; \
autoconf \
libtool \
rsync \
libxml2-dev \
aria2 && \
pip2 install setuptools && \
pip3 install setuptools && \

View File

@ -1 +1 @@
RecastBuilder*
dist

View File

@ -0,0 +1,85 @@
import sys
import re
# check parameters
if (len(sys.argv) < 3):
print("Usage: result.obj to_add.obj [material_id]")
sys.exit(1)
#----------------------------------
# read total of vertex already used
#----------------------------------
totalVertex = 0
try:
f = open(sys.argv[1], "rt")
lines = f.readlines()
for line in lines:
if (line[:2] == "v "):
totalVertex += 1
except:
f = open(sys.argv[1], "wt")
f.close()
#--------------------------------------
# read the min face index of the source
#--------------------------------------
minIndex = 10000000
try:
f = open(sys.argv[2], "rt")
lines = f.readlines()
for line in lines:
if (line[:2] == "f "):
# get the indexes (index[/uv/normal] index[/uv/normal] index[/uv/normal])
res = re.match(r"f (\d+).*? (\d+).*? (\d+)", line)
if (not res):
print("Problem parsing face indexes '%s'" % line)
sys.exit(1)
else:
# get the min index
if (minIndex > int(res.groups(0)[0])):
minIndex = int(res.groups(0)[0])
if (minIndex > int(res.groups(0)[1])):
minIndex = int(res.groups(0)[1])
if (minIndex > int(res.groups(0)[2])):
minIndex = int(res.groups(0)[2])
except:
minIndex = 0
f.close()
#----------------
# read obj to add
#----------------
f = open(sys.argv[2], "rt")
if (not f):
print("Could not open %s file" % sys.argv2[2])
sys.exit(1)
lines = f.readlines()
f.close()
d = open(sys.argv[1], "at")
for line in lines:
# object
if (line[:2] == "o "):
d.write(line)
# group
elif (line[:2] == "g "):
d.write(line)
# vertex
elif (line[:2] == "v "):
d.write(line)
# material
elif (line[:2] == "us"):
if (len(sys.argv) > 3):
d.write("usemtl %s\n" % sys.argv[3])
else:
d.write(line)
# face
elif (line[:2] == "f "):
# get the indexes (index[/uv/normal] index[/uv/normal] index[/uv/normal])
res = re.match(r"f (\d+).*? (\d+).*? (\d+)", line)
if (not res):
print("Problem parsing face indexes '%s'" % line)
sys.exit(1)
d.write("f %d %d %d\n" % (totalVertex + int(res.groups(0)[0]) - minIndex + 1,
totalVertex + int(res.groups(0)[1]) - minIndex + 1,
totalVertex + int(res.groups(0)[2]) - minIndex + 1))
d.close()

View File

@ -0,0 +1,11 @@
@rem convert FBX to OBJ
FBX2OBJ.exe %1.fbx %1.obj
@rem parse openDRIVE crosswalks (generate crosswalks.obj)
python get_xodr_crosswalks.py -f %1.xodr
@rem join both OBJ
python addOBJ.py %1.obj crosswalks.obj
@rem calculate the BIN file (result is same name .BIN)
RecastBuilder.exe %1.obj

13
Util/DockerUtils/build.sh Normal file
View File

@ -0,0 +1,13 @@
# convert FBX to OBJ
chmod +x FBX2OBJ
./FBX2OBJ "$1.fbx" "$1.obj"
# parse openDRIVE crosswalks (generate crosswalks.obj)
python get_xodr_crosswalks.py -f "$1.xodr"
# join both OBJ
python addOBJ.py "$1.obj" crosswalks.obj
# calculate the BIN file (result is same name .BIN)
chmod +x RecastBuilder
./RecastBuilder "$1.obj"

View File

@ -0,0 +1,28 @@
# use: ./build/cmake .. -A x64
# Download from: https://www.autodesk.com/content/dam/autodesk/www/adn/fbx/2020-0-1/fbx202001_fbxsdk_linux.tar.gz
# Dependencies:
# sudo apt-get install libxml2-dev
cmake_minimum_required(VERSION 2.8.9)
project(FBX2OBJ)
set(CMAKE_GENERATOR_PLATFORM x64)
#find_package(LibXml2 REQUIRED)
# include folders
include_directories(src)
include_directories(include)
# library folders
link_directories(lib/gcc/x64/release)
# sources
file(GLOB SOURCES "src/*.cpp")
add_executable(FBX2OBJ ${SOURCES})
# libraries to link
target_link_libraries(FBX2OBJ libfbxsdk.so)
target_link_libraries(FBX2OBJ dl)
target_link_libraries(FBX2OBJ z)
target_link_libraries(FBX2OBJ xml2)

View File

@ -0,0 +1,273 @@
/****************************************************************************************
Copyright (C) 2015 Autodesk, Inc.
All rights reserved.
Use of this software is subject to the terms of the Autodesk license agreement
provided at the time of installation or download, or which otherwise accompanies
this software in either electronic or hard copy form.
****************************************************************************************/
#include <fbxsdk.h>
// declare global
FbxManager* gSdkManager = NULL;
// materials
FbxSurfacePhong* gMatRoad;
FbxSurfacePhong* gMatSidewalk;
FbxSurfacePhong* gMatCross;
FbxSurfacePhong* gMatGrass;
FbxSurfacePhong* gMatBlock;
#ifdef IOS_REF
#undef IOS_REF
#define IOS_REF (*(gSdkManager->GetIOSettings()))
#endif
// Create a material that will be applied to a polygon
FbxSurfacePhong* CreateMaterial(FbxScene* pScene, char *name)
{
// Create material
FbxSurfacePhong* lMaterial = FbxSurfacePhong::Create(pScene, name);
return lMaterial;
}
bool StartsWith(const char *name, const char *str)
{
size_t lenName = strlen(name);
size_t lenStr = strlen(str);
if (lenName == 0 || lenStr == 0 || lenStr != lenName) return false;
return (memcmp(name, str, lenStr) == 0);
}
void SetMaterials(FbxNode* pNode)
{
if (!pNode) return;
FbxSurfacePhong* mat = gMatBlock;
// only for mesh nodes
FbxMesh* lMesh = pNode->GetMesh();
if(lMesh)
{
// remove
pNode->RemoveAllMaterials();
// check nomenclature
const char *name = pNode->GetName();
if (StartsWith(name, "Road_Road"))
mat = gMatRoad;
else if (StartsWith(name, "Road_Marking"))
mat = gMatRoad;
else if (StartsWith(name, "Road_Curb"))
mat = gMatRoad;
else if (StartsWith(name, "Road_Gutter"))
mat = gMatRoad;
else if (StartsWith(name, "Road_Sidewalk"))
mat = gMatSidewalk;
else if (StartsWith(name, "Road_Crosswalk"))
mat = gMatCross;
else if (StartsWith(name, "Road_Grass"))
mat = gMatGrass;
printf("Node %s : %s\n", name, mat->GetName());
pNode->AddMaterial(mat);
}
//recursively traverse each node in the scene
int i, lCount = pNode->GetChildCount();
for (i = 0; i < lCount; i++)
{
SetMaterials(pNode->GetChild(i));
}
}
// Creates an importer object, and uses it to
// import a file into a scene.
bool LoadScene(
FbxManager* pSdkManager, // Use this memory manager...
FbxScene* pScene, // to import into this scene
const char* pFilename // the data from this file.
)
{
int lFileMajor, lFileMinor, lFileRevision;
int lSDKMajor, lSDKMinor, lSDKRevision;
//int i, lAnimStackCount;
bool lStatus;
//char lPassword[1024];
// Get the version number of the FBX files generated by the
// version of FBX SDK that you are using.
FbxManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision);
// Create an importer.
FbxImporter* lImporter = FbxImporter::Create(pSdkManager,"");
// Initialize the importer by providing a filename.
const bool lImportStatus = lImporter->Initialize(pFilename, -1, pSdkManager->GetIOSettings() );
// Get the version number of the FBX file format.
lImporter->GetFileVersion(lFileMajor, lFileMinor, lFileRevision);
if( !lImportStatus ) // Problem with the file to be imported
{
FbxString error = lImporter->GetStatus().GetErrorString();
printf("Call to FbxImporter::Initialize() failed.");
printf("Error returned: %s", error.Buffer());
if (lImporter->GetStatus().GetCode() == FbxStatus::eInvalidFileVersion)
{
printf("FBX version number for this FBX SDK is %d.%d.%d",
lSDKMajor, lSDKMinor, lSDKRevision);
printf("FBX version number for file %s is %d.%d.%d",
pFilename, lFileMajor, lFileMinor, lFileRevision);
}
return false;
}
// printf("FBX version number for this FBX SDK is %d.%d.%d",lSDKMajor, lSDKMinor, lSDKRevision);
if (lImporter->IsFBX())
{
IOS_REF.SetBoolProp(IMP_FBX_MATERIAL, false);
IOS_REF.SetBoolProp(IMP_FBX_TEXTURE, false);
IOS_REF.SetBoolProp(IMP_FBX_LINK, false);
IOS_REF.SetBoolProp(IMP_FBX_SHAPE, false);
IOS_REF.SetBoolProp(IMP_FBX_GOBO, false);
IOS_REF.SetBoolProp(IMP_FBX_ANIMATION, false);
IOS_REF.SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, false);
}
// Import the scene.
lStatus = lImporter->Import(pScene);
// Destroy the importer
lImporter->Destroy();
return lStatus;
}
// Exports a scene to a file
bool SaveScene(
FbxManager* pSdkManager,
FbxScene* pScene,
const char* pFilename,
int pFileFormat,
bool pEmbedMedia
)
{
//int lMajor, lMinor, lRevision;
bool lStatus = true;
// Create an exporter.
FbxExporter* lExporter = FbxExporter::Create(pSdkManager, "");
// show file formats available
// {
// //Try to export in ASCII if possible
// int lFormatIndex, lFormatCount = pSdkManager->GetIOPluginRegistry()->GetWriterFormatCount();
// for (lFormatIndex=0; lFormatIndex<lFormatCount; lFormatIndex++)
// {
// // if (pSdkManager->GetIOPluginRegistry()->WriterIsFBX(lFormatIndex))
// {
// FbxString lDesc = pSdkManager->GetIOPluginRegistry()->GetWriterFormatDescription(lFormatIndex);
// printf("\n%d) %s", lFormatIndex, lDesc);
// }
// }
// printf("\n");
// }
pFileFormat = pSdkManager->GetIOPluginRegistry()->FindWriterIDByDescription("Alias OBJ (*.obj)");
// Initialize the exporter by providing a filename.
if(lExporter->Initialize(pFilename, pFileFormat, pSdkManager->GetIOSettings()) == false)
{
printf("Call to FbxExporter::Initialize() failed.");
printf("Error returned: %s", lExporter->GetStatus().GetErrorString());
return false;
}
// FbxManager::GetFileFormatVersion(lMajor, lMinor, lRevision);
// printf("FBX version number for this FBX SDK is %d.%d.%d",lMajor, lMinor, lRevision);
if (pSdkManager->GetIOPluginRegistry()->WriterIsFBX(pFileFormat))
{
// Export options determine what kind of data is to be imported.
// The default (except for the option eEXPORT_TEXTURE_AS_EMBEDDED)
// is true, but here we set the options explicitly.
IOS_REF.SetBoolProp(EXP_FBX_MATERIAL, true);
IOS_REF.SetBoolProp(EXP_FBX_TEXTURE, true);
IOS_REF.SetBoolProp(EXP_FBX_EMBEDDED, pEmbedMedia);
IOS_REF.SetBoolProp(EXP_FBX_SHAPE, true);
IOS_REF.SetBoolProp(EXP_FBX_GOBO, true);
IOS_REF.SetBoolProp(EXP_FBX_ANIMATION, true);
IOS_REF.SetBoolProp(EXP_FBX_GLOBAL_SETTINGS, true);
}
// get root node of the fbx scene
FbxNode* lRootNode = pScene->GetRootNode();
// rotate
lRootNode->LclRotation.Set(FbxVector4(-90.0, 0.0, 0.0));
// set materials following nomenclature of RoadRunner
SetMaterials(lRootNode);
// Export the scene.
lStatus = lExporter->Export(pScene);
// Destroy the exporter.
lExporter->Destroy();
return lStatus;
}
int main(int argc, char **argv)
{
// Creates an instance of the SDK manager.
gSdkManager = FbxManager::Create();
// create an IOSettings object
FbxIOSettings * ios = FbxIOSettings::Create(gSdkManager, IOSROOT );
gSdkManager->SetIOSettings(ios);
// ImportExport(argv[1], argv[2], -1);
// Create a scene
FbxScene* lScene = FbxScene::Create(gSdkManager,"");
// import
bool r = LoadScene(gSdkManager, lScene, argv[1]);
if(!r)
{
printf("------- Import failed ----------------------------");
// Destroy the scene
lScene->Destroy();
return 0;
}
gMatRoad = CreateMaterial(lScene, "road");
gMatSidewalk = CreateMaterial(lScene, "sidewalk");
gMatCross = CreateMaterial(lScene, "crosswalk");
gMatGrass = CreateMaterial(lScene, "grass");
gMatBlock = CreateMaterial(lScene, "block");
// export
r = SaveScene(gSdkManager, lScene, argv[2], -1, false);
if(!r)
printf("------- Export failed ----------------------------");
// destroy the scene
lScene->Destroy();
// Destroys an instance of the SDK manager
if (gSdkManager) gSdkManager->Destroy();
return 1;
}

View File

@ -0,0 +1,76 @@
#!/usr/bin/env python
# Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
import glob
import os
import sys
try:
sys.path.append(glob.glob('../../../PythonAPI/carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
import carla
import argparse
argparser = argparse.ArgumentParser()
argparser.add_argument(
'-f', '--file',
metavar='F',
default="",
type=str,
help='OpenDRIVE file')
args = argparser.parse_args()
# read the OpenDRIVE
try:
f = open(args.file, "rt")
except:
print("OpenDRIVE file not found!")
exit(1)
data = f.read()
f.close()
# create the map with the OpenDRIVE content
m = carla.Map("t", data)
points = m.get_crosswalks()
for i in range(len(points)):
print(points[i])
# generate the .OBJ file
f = open("crosswalks.obj", "wt")
faceIndex = 0
vertexIndex = 0
i = 0
totalCrosswalks = 0
totalPoints = 0
while (i < len(points)):
totalCrosswalks += 1
# object
f.write("o crosswalk_%d\n" % totalCrosswalks)
a = i # get the starting point index for this object
startPoint = totalPoints
while (i < len(points)):
# vertex
f.write("v %f %f %f\n" % (points[i].x, points[i].z, points[i].y))
i +=1
totalPoints += 1
if (points[i].x == points[a].x and points[i].y == points[a].y and points[i].z == points[a].z):
i +=1
break
# material (type)
f.write("usemtl crosswalk\n")
# faces
for j in range(startPoint+2, totalPoints):
f.write("f %d %d %d\n" % (startPoint+1, j-1+1, j+1))
f.close()