Эх сурвалжийг харах

Merge branch 'master' of http://111.33.136.149:3000/adc_pilot/modularization

fujiankuan 4 жил өмнө
parent
commit
1afd8a4c29
30 өөрчлөгдсөн 2161 нэмэгдсэн , 154 устгасан
  1. 1 1
      include/ivversion.h
  2. 146 0
      sh/tagv1.1/autodeploy.sh
  3. 58 0
      sh/tagv1.1/autodeploylib.sh
  4. 10 0
      sh/tagv1.1/autogen.bat
  5. 309 0
      sh/tagv1.1/autogen.sh
  6. 23 0
      sh/tagv1.1/gen.bat
  7. 25 0
      sh/tagv1.1/genlib.bat
  8. 13 0
      sh/tagv1.1/windowsdus.txt
  9. 115 111
      src/detection/detection_mobileye/main.cpp
  10. 54 38
      src/detection/detection_radar_delphi_esr_send/main.cpp
  11. 270 0
      src/tool/map_lanetoxodr/dialogroadmerge.cpp
  12. 35 0
      src/tool/map_lanetoxodr/dialogroadmerge.h
  13. 78 0
      src/tool/map_lanetoxodr/dialogroadmerge.ui
  14. 146 0
      src/tool/map_lanetoxodr/dialogroadmirror.cpp
  15. 32 0
      src/tool/map_lanetoxodr/dialogroadmirror.h
  16. 101 0
      src/tool/map_lanetoxodr/dialogroadmirror.ui
  17. 102 0
      src/tool/map_lanetoxodr/dialogroadmove.cpp
  18. 32 0
      src/tool/map_lanetoxodr/dialogroadmove.h
  19. 78 0
      src/tool/map_lanetoxodr/dialogroadmove.ui
  20. 117 0
      src/tool/map_lanetoxodr/dialogroadrotate.cpp
  21. 32 0
      src/tool/map_lanetoxodr/dialogroadrotate.h
  22. 55 0
      src/tool/map_lanetoxodr/dialogroadrotate.ui
  23. 4 1
      src/tool/map_lanetoxodr/dialogroadsplit.cpp
  24. 2 2
      src/tool/map_lanetoxodr/mainwindow.cpp
  25. 12 0
      src/tool/map_lanetoxodr/map_lanetoxodr.pro
  26. 90 0
      src/tool/map_lanetoxodr/roadeditdialog.cpp
  27. 12 0
      src/tool/map_lanetoxodr/roadeditdialog.h
  28. 53 1
      src/tool/map_lanetoxodr/roadeditdialog.ui
  29. 145 0
      src/tool/map_lanetoxodr/xodrfunc.cpp
  30. 11 0
      src/tool/map_lanetoxodr/xodrfunc.h

+ 1 - 1
include/ivversion.h

@@ -1,5 +1,5 @@
 
-#define VERSION "1.0.0-develop"
+#define VERSION "1.1.0-develop"
 
 
 #include <iostream>

+ 146 - 0
sh/tagv1.1/autodeploy.sh

@@ -0,0 +1,146 @@
+PRO_DIR=`pwd`
+CONFIG_IVSysMan="IVSysMan.xml"
+
+
+cd ../../ 
+
+app_name=(
+controller_bus
+controller_jinlong_peisong
+controller_midcar
+controller_problue
+controller_ge3
+controller_vv7
+controller_tju_vv7
+decition_brain
+driver_camera_usb
+driver_can_kvaser
+driver_can_vci
+driver_can_nvidia_agx
+driver_cloud_grpc_client_stream
+driver_grpc_server
+driver_gps_ins550d
+driver_gps_hcp2
+driver_lidar_bk16
+driver_lidar_hesai40line
+driver_lidar_hesai40p
+driver_lidar_hesaipandar64
+driver_lidar_rs16
+driver_lidar_rs32
+driver_lidar_vlp16
+driver_lidar_vlp32c
+driver_lidar_vtdpoint
+driver_map_trace
+driver_map_xodrload
+driver_piccompress
+driver_radio_p900
+driver_rpc_client
+driver_rpc_server
+driver_vbox_gaohong
+driver_ota_client
+driver_ota_server
+detection_chassis
+detection_gps_hcp2
+detection_gps_vtd
+#detection_lidar_cnn_segmentation
+detection_lidar_cnntogrid
+detection_lidar_grid
+detection_lidar_ukf_pda
+detection_mobileye
+#detection_ndt_matching_gpu_multi
+detection_radar_delphi_esr
+detection_state_delphi_ins500d
+fusion_gpsndt
+fusion_pointcloud_bus
+adciv_record
+adciv_replay
+adcndtmultimapping
+bqev_lidar_cnn_detect_view
+bqev_multilidarcalib
+bqev_pcdview
+ivmapmake
+ivmapmake_sharemem
+IVSysMan
+map_lanetoxodr
+map_mobieye
+PerceptionShow
+picview
+pointcloudviewer
+RemoteCtrl
+tool_calcmd5
+tool_querymsg
+tool_xodrobj
+view_gps
+view_ivlog
+view_pcdmap
+view_radar
+view_rawcan
+ui_ads_hmi
+tool_configivsysman
+RemoteCtrl_Stream
+)
+
+for x in ${app_name[@]}
+do
+	echo "deploy $x"
+	cp ./bin/${x} ./
+	./deploywithfind.sh $x
+	rm ${x}
+done
+
+#cp ./thirdpartylib/QtWebApp/lib/*.s* ./bin
+#patchelf --set-rpath '$ORIGIN' ./bin/libQtWebAppGlobal.so
+#patchelf --set-rpath '$ORIGIN' ./bin/llibQtWebAppHttpServer.so
+
+#cp ./bin/libQtWebApp*  ./deploy/app/lib/
+
+
+
+
+lib_name=(
+	libmodulecomm.so
+	libndt_cpu.so
+#	libndt_gpu.so
+	libxmlparam.so
+	libivfault.so
+	libivlog.so
+	libivbacktrace.so
+	libivexit.so
+)
+
+
+
+for x in ${lib_name[@]}
+do
+#	echo "link lib $x"
+#	patchelf --set-rpath '$ORIGIN' ./bin/$x
+	echo "deploylib $x"
+	cp ./bin/${x} ./
+	./deploylib.sh $x
+	rm ${x}
+done
+
+
+xlib=`ls ./deploy/app/lib/lib*`  
+for fileName in $xlib
+  do
+     patchelf --set-rpath '$ORIGIN' $fileName
+  done
+
+   
+
+#echo "creat IVSysMan.xml"
+#cp ./sh/tju64/xml/$CONFIG_IVSysMan ./deploy/app/IVSysMan.xml
+#cp ./other/ADS_decision.xml ./deploy/app/ADS_decision.xml
+#sed -i "s|xxxxxx|$PRO_DIR/|g" ./deploy/app/IVSysMan.xml
+
+#cp ./bin/*.so ./deploy/app/lib/
+
+#cp ./sh/tju64/xml/*  ./deploy/app/
+
+
+
+echo ""
+echo "***************"
+echo "***  done!  ***"
+echo "***************"

+ 58 - 0
sh/tagv1.1/autodeploylib.sh

@@ -0,0 +1,58 @@
+PRO_DIR=`pwd`
+CONFIG_IVSysMan="IVSysMan.xml"
+
+
+cd ../../ 
+
+
+
+
+
+
+lib_name=(
+	libmodulecomm.so
+	libndt_cpu.so
+#	libndt_gpu.so
+	libxmlparam.so
+	libivfault.so
+	libivlog.so
+	libivbacktrace.so
+	libivexit.so
+)
+
+
+
+for x in ${lib_name[@]}
+do
+#	echo "link lib $x"
+#	patchelf --set-rpath '$ORIGIN' ./bin/$x
+	echo "deploylib $x"
+	cp ./bin/${x} ./
+	./deploylib.sh $x
+	rm ${x}
+done
+
+
+xlib=`ls ./deploy/app/lib/lib*`  
+for fileName in $xlib
+  do
+     patchelf --set-rpath '$ORIGIN' $fileName
+  done
+
+   
+
+#echo "creat IVSysMan.xml"
+#cp ./sh/tju64/xml/$CONFIG_IVSysMan ./deploy/app/IVSysMan.xml
+#cp ./other/ADS_decision.xml ./deploy/app/ADS_decision.xml
+#sed -i "s|xxxxxx|$PRO_DIR/|g" ./deploy/app/IVSysMan.xml
+
+#cp ./bin/*.so ./deploy/app/lib/
+
+#cp ./sh/tju64/xml/*  ./deploy/app/
+
+
+
+echo ""
+echo "***************"
+echo "***  done!  ***"
+echo "***************"

+ 10 - 0
sh/tagv1.1/autogen.bat

@@ -0,0 +1,10 @@
+
+call genlib.bat src\common modulecomm 
+call genlib.bat src\common xmlparam
+call genlib.bat src\common ivbacktrace
+call genlib.bat src\common ivfault
+call genlib.bat src\common ivexit
+call genlib.bat src\common ivlog
+call genlib.bat src\common ivsyschange
+
+call gen.bat src\driver driver_gps_hcp2

+ 309 - 0
sh/tagv1.1/autogen.sh

@@ -0,0 +1,309 @@
+
+#qtmake="/opt/qt/5.10.1/gcc_64/bin/qmake"
+
+qtmake=" "
+
+if [ ${#qtmake} -lt 5 ]; then
+  echo "now need find qmake "
+  optfiles=`find /opt -name 'qmake'` 
+  for entry in $optfiles
+  do
+     x=${entry:0-17:17}
+     if [ "$x" == "/gcc_64/bin/qmake" ];  then
+        qtmake="$entry"
+	echo "  -----find qmake"
+	echo "$qtmake"
+     fi
+  done
+fi
+
+if [ ${#qtmake} -lt 5 ]; then
+  echo "maybe agx,find qmake in usr folder "
+  optfiles=`find /usr -name 'qmake'` 
+  for entry in $optfiles
+  do
+     x=${entry:0-14:14}
+     if [ "$x" == "/qt5/bin/qmake" ];  then
+        qtmake="$entry"
+	echo "  -----find qmake"
+	echo "$qtmake"
+     fi
+  done
+fi
+
+
+MAKEOPT=-j2
+
+cd ../../
+
+mkdir bin
+
+cd src/include/proto
+sh ./protomake.sh
+cd ../../../
+
+cd src/include/proto3
+sh ./protomake.sh
+cd ../../../
+
+cd src/common/modulecomm/
+$qtmake modulecomm.pro
+make $MAKEOPT
+make clean
+cp libmodulecomm.so ./../../../bin/
+rm Makefile
+rm .qmake.stash
+cd ../../../
+
+cd src/common/xmlparam/
+$qtmake xmlparam.pro
+make $MAKEOPT
+make clean
+cp libxmlparam.so ./../../../bin/
+rm Makefile
+rm .qmake.stash
+cd ../../../
+
+cd src/common/ndt_cpu/
+$qtmake ndt_cpu.pro
+make $MAKEOPT
+make clean
+cp libndt_cpu.so ./../../../bin/
+rm Makefile
+rm .qmake.stash
+cd ../../../
+
+#cd src/common/ndt_gpu/
+#$qtmake ndt_gpu.pro
+#make $MAKEOPT
+#make clean
+#cp libndt_gpu.so ./../../../bin/
+#rm Makefile
+#rm .qmake.stash
+#cd ../../../
+
+cd src/common/ivlog/
+$qtmake ivlog.pro
+make $MAKEOPT
+make clean
+cp libivlog.so ./../../../bin/
+rm Makefile
+rm .qmake.stash
+cd ../../../
+
+cd src/common/ivfault/
+$qtmake ivfault.pro
+make $MAKEOPT
+make clean
+cp libivfault.so ./../../../bin/
+rm Makefile
+rm .qmake.stash
+cd ../../../
+
+
+cd src/common/ivbacktrace/
+$qtmake ivbacktrace.pro
+make $MAKEOPT
+make clean
+cp libivbacktrace.so ./../../../bin/
+rm Makefile
+rm .qmake.stash
+cd ../../../
+
+cd src/common/ivexit/
+$qtmake ivexit.pro
+make $MAKEOPT
+make clean
+cp libivexit.so ./../../../bin/
+rm Makefile
+rm .qmake.stash
+cd ../../../
+
+controller_app_name=(
+controller_bus
+controller_jinlong_peisong
+controller_midcar
+controller_problue
+controller_ge3
+controller_vv7
+controller_tju_vv7
+)
+
+for x in ${controller_app_name[@]}
+do
+cd src/controller/${x}/
+$qtmake ${x}.pro
+make $MAKEOPT
+make clean
+cp ${x} ./../../../bin/
+rm Makefile
+rm .qmake.stash
+rm ${x}
+cd ../../../
+done
+
+decition_app_name=(
+decition_brain
+)
+
+for x in ${decition_app_name[@]}
+do
+cd src/decition/${x}/
+$qtmake ${x}.pro
+make $MAKEOPT
+make clean
+cp ${x} ./../../../bin/
+rm Makefile
+rm .qmake.stash
+rm ${x}
+cd ../../../
+done
+
+driver_app_name=(
+driver_camera_usb
+driver_can_kvaser
+driver_can_vci
+driver_can_nvidia_agx
+#driver_cloud_grpc_client
+#driver_cloud_grpc_pc
+#driver_cloud_grpc_server
+driver_gps_ins550d
+driver_gps_hcp2
+driver_lidar_bk16
+driver_lidar_hesai40line
+driver_lidar_hesai40p
+driver_lidar_hesaipandar64
+driver_lidar_rs16
+driver_lidar_rs32
+driver_lidar_vlp16
+driver_lidar_vlp32c
+driver_lidar_vtdpoint
+driver_map_trace
+driver_map_xodrload
+driver_piccompress
+driver_radio_p900
+#driver_rpc_client
+#driver_rpc_server
+driver_vbox_gaohong
+)
+
+for x in ${driver_app_name[@]}
+do
+cd src/driver/${x}/
+$qtmake ${x}.pro
+make $MAKEOPT
+make clean
+cp ${x} ./../../../bin/
+rm Makefile
+rm .qmake.stash
+rm ${x}
+cd ../../../
+done
+
+detect_app_name=(
+detection_chassis
+detection_gps_hcp2
+detection_gps_vtd
+#detection_lidar_cnn_segmentation
+detection_lidar_cnntogrid
+detection_lidar_grid
+detection_lidar_ukf_pda
+detection_mobileye
+#detection_ndt_matching_gpu_multi
+detection_radar_delphi_esr
+detection_state_delphi_ins500d
+
+)
+
+for x in ${detect_app_name[@]}
+do
+cd src/detection/${x}/
+$qtmake ${x}.pro
+make $MAKEOPT
+make clean
+cp ${x} ./../../../bin/
+rm Makefile
+rm .qmake.stash
+rm ${x}
+cd ../../../
+done
+
+fusion_app_name=(
+fusion_gpsndt
+fusion_pointcloud_bus
+)
+
+for x in ${fusion_app_name[@]}
+do
+cd src/fusion/${x}/
+$qtmake ${x}.pro
+make $MAKEOPT
+make clean
+cp ${x} ./../../../bin/
+rm Makefile
+rm .qmake.stash
+rm ${x}
+cd ../../../
+done
+
+tool_app_name=(
+adciv_record
+adciv_replay
+adcndtmultimapping
+bqev_lidar_cnn_detect_view
+bqev_multilidarcalib
+bqev_pcdview
+ivmapmake
+ivmapmake_sharemem
+IVSysMan
+map_lanetoxodr
+map_mobieye
+PerceptionShow
+picview
+pointcloudviewer
+#RemoteCtrl
+tool_calcmd5
+tool_querymsg
+tool_xodrobj
+view_gps
+view_ivlog
+view_pcdmap
+view_radar
+view_rawcan
+tool_configivsysman
+)
+
+for x in ${tool_app_name[@]}
+do
+cd src/tool/${x}/
+$qtmake ${x}.pro
+make $MAKEOPT
+make clean
+cp ${x} ./../../../bin/
+rm Makefile
+rm .qmake.stash
+rm ${x}
+cd ../../../
+done
+
+ui_app_name=(
+ui_ads_hmi
+)
+
+for x in ${ui_app_name[@]}
+do
+cd src/ui/${x}/
+$qtmake ${x}.pro
+make $MAKEOPT
+make clean
+cp ${x} ./../../../bin/
+rm Makefile
+rm .qmake.stash
+rm ${x}
+cd ../../../
+done
+
+
+
+
+

+ 23 - 0
sh/tagv1.1/gen.bat

@@ -0,0 +1,23 @@
+set qmake=C:\Qt\Qt5.13.2\5.13.2\mingw73_64\bin\qmake.exe
+set make=C:/Qt/Qt5.13.2/Tools/mingw730_64/bin/mingw32-make
+set shdir=%cd%
+cd ..
+cd ..
+set modulename=%2
+set rootdir=%cd%
+set prodir=%rootdir%\%1\%2
+cd %prodir%
+set profile=%2.pro
+%qmake% %profile%
+%make% -f Makefile.Release -j8
+cd release
+copy %modulename%.exe %rootdir%\bin
+cd ..
+del .qmake.stash
+del Makefile
+del Makefile.Debug
+del Makefile.Release
+del %2%_resource.rc
+rd debug
+rd /s /q release
+cd %shdir%

+ 25 - 0
sh/tagv1.1/genlib.bat

@@ -0,0 +1,25 @@
+set qmake=C:\Qt\Qt5.13.2\5.13.2\mingw73_64\bin\qmake.exe
+set make=C:/Qt/Qt5.13.2/Tools/mingw730_64/bin/mingw32-make
+set shdir=%cd%
+cd ..
+cd ..
+set modulename=%2
+set rootdir=%cd%
+set prodir=%rootdir%\%1\%2
+cd %prodir%
+set profile=%2.pro
+echo %profile%
+%qmake% %profile%
+%make% -f Makefile.Release -j8
+cd release
+copy lib%modulename%.a %rootdir%\bin
+copy %modulename%.dll %rootdir%\bin
+cd ..
+del .qmake.stash
+del Makefile
+del Makefile.Debug
+del Makefile.Release
+del %2%_resource.rc
+rd debug
+rd /s /q release
+cd %shdir%

+ 13 - 0
sh/tagv1.1/windowsdus.txt

@@ -0,0 +1,13 @@
+https://github.com/WangTingMan/WinDbusBinary
+
+在Windows上面使用DBUS
+DBUS是一种进程间远程调用的机制。 官方网站是: https://www.freedesktop.org/wiki/Software/dbus/ 通过这里提供的DBUS Windows移植版本,你可以在windows上面开发dbus程序啦!
+
+如何使用
+复制dbus-1.dll到你的计算机的系统目录中,以便使用DBUS的程序可以找到它并且加载它。部分DBUS程序是动态从系统中加载该dll 的,因此请需要注意系统加载dll的搜索路径。
+在桌面上创建dbus-daemon.exe的快捷方式
+修改步骤2创建的快捷方式,在该快捷方式上右键,在“目标”栏位中填写:xxx\dbus-daemon.exe --config-file=system.conf 注意,xxx指的是dbus-daemon.exe所在的文件夹。
+开始运行dbus-daemon.exe吧!
+在QT中测试
+QT中有很多DBUS的示例程序,可以使用它们来测试DBUS通信。 不过使用qdbusviewer.exe,你会发现浏览org.freedesktop.DBUs的DBUS接口时,会报一部分错误,不过这并不影响你实际的DBUS通信 开发哦!
+

+ 115 - 111
src/detection/detection_mobileye/main.cpp

@@ -2,7 +2,7 @@
 
 #include <iostream>
 #include <QDateTime>
-
+#include <QDebug>
 #include "modulecomm.h"
 #include "xmlparam.h"
 #include "ivversion.h"
@@ -74,11 +74,11 @@ void ProcCANMsg(iv::can::canraw xmsg)
         double curv, head, yaw, pitch;
         int ldw_left, ldw_right;
         short ihead;
-        for(int i = 0; i< 8; i++)
-        {
+//        for(int i = 0; i< 8; i++)
+//        {
 
-            gMobEyeIvlog->verbose("mobileye","i:%d %x %d\n ",i, xdata[i], xdata[i]);
-        }
+//            gMobEyeIvlog->verbose("mobileye","i:%d %x %d\n ",i, xdata[i], xdata[i]);
+//        }
         tmp = 0;
         //lane curv
         tmp = (xdata[1] << 8) | xdata[0];
@@ -199,47 +199,51 @@ void ProcCANMsg(iv::can::canraw xmsg)
      *  is_obstacle_brake_lights bool                  /             0,1            0 object's brake light off or not identified, 1 object's brake light on
      *  obstacle_valid           int/enum              /            [1:2]           1 new valid(detected this frame), 2 older valid
      *************************************************************************************************************************************************************/
-    else if((xmsg.id()-0x739)/3 == 0)
+    else if(xmsg.id() > 0x738 && xmsg.id() < 0x766)
     {
-        //obstacle id
-        gobs.set_id(xdata[0]);
+        if((xmsg.id()-0x739)%3 == 0)
+        {
+            //obstacle id
+            gobs.set_id(xdata[0]);
 
-        //obstacle pos x
-        tmp = ((xdata[2] & 0xf) << 8) | xdata[1];
-        gobs.set_pos_x(tmp * 0.0625);
-        tmp = 0;
+            //obstacle pos x
+            tmp = ((xdata[2] & 0xf) << 8) | xdata[1];
+            gobs.set_pos_x(tmp * 0.0625);
+            tmp = 0;
 
-        //obstacle pos y
-        tmp = ((xdata[4] & 0x3) << 8) | xdata[3];
-        tmp <<= 22;
-        tmp >>= 22;
-        gobs.set_pos_y(tmp * 0.0625);
+            //obstacle pos y
+            tmp = ((xdata[4] & 0x3) << 8) | xdata[3];
+            tmp <<= 22;
+            tmp >>= 22;
+            gobs.set_pos_y(tmp * 0.0625);
 
-        //blinker info
-        gobs.set_blinkerinfo((xdata[4] >> 2) & 0x7);
+            //blinker info
+            gobs.set_blinkerinfo((xdata[4] >> 2) & 0x7);
 
-        //cut in and out
-        gobs.set_cutstate(iv::mobileye::obs_CUTSTATE(xdata[4] >> 5));
+            //cut in and out
+            gobs.set_cutstate(iv::mobileye::obs_CUTSTATE(xdata[4] >> 5));
+            //        gobs.set_cutstate(xdata[4] >> 5);
 
-        //obstacle rel vel x
-        tmp = ((xdata[6] & 0xf) << 8) | xdata[5];
-        tmp <<= 20;
-        tmp >>= 20;
-        gobs.set_obs_rel_vel_x(tmp * 0.0625);
+            //obstacle rel vel x
+            tmp = ((xdata[6] & 0xf) << 8) | xdata[5];
+            tmp <<= 20;
+            tmp >>= 20;
+            gobs.set_obs_rel_vel_x(tmp * 0.0625);
 
-        //obstacle type
-        gobs.set_obstype(iv::mobileye::obs_OBSTYPE((xdata[6] >> 4) & 0x7));
+            //obstacle type
+            gobs.set_obstype(iv::mobileye::obs_OBSTYPE((xdata[6] >> 4) & 0x7));
 
-        //obstacle status
-        gobs.set_obssatus(iv::mobileye::obs_OBSSTATE(xdata[7] & 0x7));
+            //obstacle status
+            gobs.set_obssatus(iv::mobileye::obs_OBSSTATE(xdata[7] & 0x7));
 
-        //obstacle brake lights
-        gobs.set_obsbrakelights((xdata[7] >> 3) & 0x1);
+            //obstacle brake lights
+            gobs.set_obsbrakelights((xdata[7] >> 3) & 0x1);
 
-        //obstacle valid
-        gobs.set_obsvalid((xdata[7] >> 6) & 0x7);
-    }
-    /****************************************************  mobileye obstacle data b  ****************************************************************************
+            //obstacle valid
+            gobs.set_obsvalid((xdata[7] >> 6) & 0x7);
+
+        }
+        /****************************************************  mobileye obstacle data b  ****************************************************************************
      *  message ID:0x73a
      *  member:                  type           physical unit       range               note
      *  obstacle_length          double                m           [0,31]           length of the obstacle(longitude axis)
@@ -256,50 +260,50 @@ void ProcCANMsg(iv::can::canraw xmsg)
      *                                                                              vision and radar measurements higher->smaller error, 5 high confidence match
      *  matched_radar_id         int                   /           [0:127]          ID of Primary radar target matched to the vision target if applicable
      *************************************************************************************************************************************************************/
-    else if((xmsg.id()-0x73a)/3 == 0)
-    {
-        //obstacle length
-        tmp = xdata[0];
-        gobs.set_obslen(tmp * 0.5);
-        tmp = 0;
+        else if((xmsg.id()-0x73a)%3 == 0)
+        {
+            //obstacle length
+            tmp = xdata[0];
+            gobs.set_obslen(tmp * 0.5);
+            tmp = 0;
 
-        //obstacle width
-        tmp = xdata[1];
-        gobs.set_obswidth(tmp * 0.05);
+            //obstacle width
+            tmp = xdata[1];
+            gobs.set_obswidth(tmp * 0.05);
 
-        tmp = 0;
+            tmp = 0;
 
-        //obstacle age
-        gobs.set_obsage(xdata[2]);
+            //obstacle age
+            gobs.set_obsage(xdata[2]);
 
-        //obstacle lane
-        gobs.set_obslane(xdata[3] & 0x3);
+            //obstacle lane
+            gobs.set_obslane(xdata[3] & 0x3);
 
-        //is cipv flag
-        gobs.set_cipvflag((xdata[3] >> 2) & 0x1);
+            //is cipv flag
+            gobs.set_cipvflag((xdata[3] >> 2) & 0x1);
 
-        //radar pos x
-        tmp = (xdata[4] << 4) | (xdata[3] >> 4);
-        gobs.set_radarposx(tmp * 0.0625);
+            //radar pos x
+            tmp = (xdata[4] << 4) | (xdata[3] >> 4);
+            gobs.set_radarposx(tmp * 0.0625);
 
-        tmp = 0;
+            tmp = 0;
 
-        //radar vel x
-        tmp = ((xdata[6] & 0xf) << 8) | xdata[5];
-        tmp <<= 20;
-        tmp >>= 20;
-        gobs.set_radarvelx(tmp * 0.0625);
+            //radar vel x
+            tmp = ((xdata[6] & 0xf) << 8) | xdata[5];
+            tmp <<= 20;
+            tmp >>= 20;
+            gobs.set_radarvelx(tmp * 0.0625);
 
-        tmp = 0;
+            tmp = 0;
 
-        //radar match confidence
-        gobs.set_radarmatchconfi((xdata[6] >> 4) & 0x7);
+            //radar match confidence
+            gobs.set_radarmatchconfi((xdata[6] >> 4) & 0x7);
 
-        //matched radar ID
-        gobs.set_matchedradarid(xdata[7] & 0x7f);
+            //matched radar ID
+            gobs.set_matchedradarid(xdata[7] & 0x7f);
 
-    }
-    /****************************************************  mobileye obstacle data c  ****************************************************************************
+        }
+        /****************************************************  mobileye obstacle data c  ****************************************************************************
      *  message ID:0x73b
      *  member:                  type           physical unit       range               note
      *  obstacle_angle_rate      double           degree/s     [-327.68, 327.68]    Angle rate of Center of Obstacle, negative->moved to left
@@ -309,48 +313,48 @@ void ProcCANMsg(iv::can::canraw xmsg)
      *  obstacle_angle           double           degree        [-327.68,327.68]    Angle to Center of Obstacle in degrees, 0 indicates that the obstacle is in
      *                                                                              exactly in front of us, a positive angle indicates that theobstacle is to the right
      *************************************************************************************************************************************************************/
-    else if((xmsg.id()-0x73b)/3 == 0)
-    {
-        //obstacle angle rate
-        tmp = (xdata[1] << 8) | xdata[0];
-        tmp <<= 16;
-        tmp >>= 16;
-        gobs.set_obsangrate(tmp * 0.01);
-
-        tmp = 0;
-
-        //obstacle scale change
-        tmp = (xdata[3] << 8) | xdata[2];
-        tmp <<= 16;
-        tmp >>= 16;
-        gobs.set_obsscalechange(tmp * 0.0002);
-
-        tmp = 0;
-
-        //object accel x
-        tmp = ((xdata[5] & 0x3) << 8) | xdata[4];
-        tmp <<= 22;
-        tmp >>= 22;
-        gobs.set_accelx(tmp * 0.03);
-
-        tmp = 0;
-
-        //obstacle replaced
-        gobs.set_obsreplaced((xdata[5] >> 4) & 0x1);
-
-        //obstacle angle
-        tmp = (xdata[7] << 8) | xdata[6];
-        tmp <<= 16;
-        tmp >>= 16;
-        gobs.set_obsang(tmp * 0.01);
-
-        iv::mobileye::obs * pxobs = gmobileye.add_xobj();
-        pxobs->CopyFrom(gobs);
-        gobs_count++;
-        gMobEyeIvlog->verbose("mobileyeobs", "nums:%d cur_count:%d, obs_id:%d, pos_x:%f, pos_y:%f \n",\
-                              gnum_obstacles, gobs_count, gobs.id(), gobs.pos_x(), gobs.pos_y());
+        else if((xmsg.id()-0x73b)%3 == 0)
+        {
+            //obstacle angle rate
+            tmp = (xdata[1] << 8) | xdata[0];
+            tmp <<= 16;
+            tmp >>= 16;
+            gobs.set_obsangrate(tmp * 0.01);
+
+            tmp = 0;
+
+            //obstacle scale change
+            tmp = (xdata[3] << 8) | xdata[2];
+            tmp <<= 16;
+            tmp >>= 16;
+            gobs.set_obsscalechange(tmp * 0.0002);
+
+            tmp = 0;
+
+            //object accel x
+            tmp = ((xdata[5] & 0x3) << 8) | xdata[4];
+            tmp <<= 22;
+            tmp >>= 22;
+            gobs.set_accelx(tmp * 0.03);
+
+            tmp = 0;
+
+            //obstacle replaced
+            gobs.set_obsreplaced((xdata[5] >> 4) & 0x1);
+
+            //obstacle angle
+            tmp = (xdata[7] << 8) | xdata[6];
+            tmp <<= 16;
+            tmp >>= 16;
+            gobs.set_obsang(tmp * 0.01);
+
+            iv::mobileye::obs * pxobs = gmobileye.add_xobj();
+            pxobs->CopyFrom(gobs);
+            gobs_count++;
+            gMobEyeIvlog->verbose("mobileyeobs", "nums:%d cur_count:%d, obs_id:%d, pos_x:%f, pos_y:%f \n",\
+                                  gnum_obstacles, gobs_count, gobs.id(), gobs.pos_x(), gobs.pos_y());
+        }
     }
-
     /****************************************************  mobileye aftermarket lane  ****************************************************************************
      *  message ID:0x669
      *  member:                  type           physical unit       range               note
@@ -495,8 +499,8 @@ int main(int argc, char *argv[])
 
     iv::xmlparam::Xmlparam xp(strpath.toStdString());
 
-    std::string strmemcan = xp.GetParam("canrecv","canrecv0");
-    std::string strmemsend = xp.GetParam("cansend","cansend0");
+    std::string strmemcan = xp.GetParam("canrecv","canrecv1");
+    std::string strmemsend = xp.GetParam("cansend","cansend1");
     std::string strmemmobileye = xp.GetParam("mobileye","mobileye");
 
     gTime.start();

+ 54 - 38
src/detection/detection_radar_delphi_esr_send/main.cpp

@@ -5,6 +5,7 @@
 #include <math.h>
 #include <thread>
 #include <QDebug>
+#include <QReadWriteLock>
 
 #include <signal.h>
 #include <stdlib.h>
@@ -40,12 +41,12 @@ static uint16_t Radar_to_Rear_Axle = 370;//< 0-710 cm
 static uint16_t Car_Wheel_Base = 270;//< 0-710 cm
 static uint8_t Car_Steering_Gear_Ratio = 18;//< 0-31.875
 /******************************************/
-
+QReadWriteLock *wrLock = new QReadWriteLock();
 canSend4F0 canData4f0;
 canSend4F1 canData4f1;
 canSend5F2 canData5f2;
 canSend5F4 canData5f4;
-
+int canChannel = 0;
 /******************************************/
 
 iv::Ivlog * givlog;
@@ -69,7 +70,6 @@ void ExecSend()
 {
     iv::can::canmsg xmsg;
     iv::can::canraw xraw;
-qDebug()<<QTime::currentTime();
     xraw.set_id(0x4F0);
     xraw.set_data(canData4f0.byte,8);
     xraw.set_bext(false);
@@ -136,8 +136,10 @@ void Listengpsimu(const char * strdata,const unsigned int nSize,const unsigned i
         givlog->warn("detection_radar_delphi_esr_send--Listengpsimu parse errror. nSize is %d",nSize);
         return;
     }
+    wrLock->lockForWrite();
     Vehicle_Yaw_Rate = xgpsimu.gyro_z() * -1;
     Vehicle_Speed = sqrt(xgpsimu.vn()*xgpsimu.vn() + xgpsimu.ve()*xgpsimu.ve() + xgpsimu.vd()*xgpsimu.vd());
+    wrLock->unlock();
 }
 
 void Listencancar(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
@@ -158,10 +160,12 @@ void Listencancar(const char * strdata,const unsigned int nSize,const unsigned i
 
 /****************timer*********************/
 
-void signalHandler(int num)
+void signalHandler()
 {
+    wrLock->lockForRead();
     unsigned int speed = (unsigned int)(Vehicle_Speed / 0.0625);
     int yawRate = (int)(Vehicle_Yaw_Rate / 0.0625);
+    wrLock->unlock();
 
     canData4f0.bit.canVehicleSpeedH = speed >> 8;
     canData4f0.bit.canVehicleSpeedL = speed & 0xFF;
@@ -489,7 +493,7 @@ void threadstate()
 {
     while(1)
     {
-        std::this_thread::sleep_for(std::chrono::milliseconds(10));
+        std::this_thread::sleep_for(std::chrono::milliseconds(20));
         if(gnRadarState > -100)gnRadarState--;
         if(gnRadarState > 0)
         {
@@ -506,7 +510,8 @@ void threadstate()
                 givfault->SetFaultState(2,2,"无CAN数据");
             }
         }
-
+        signalHandler();
+        qDebug()<<QTime::currentTime();
     }
 }
 
@@ -514,6 +519,42 @@ int main(int argc, char *argv[])
 {
     QCoreApplication a(argc, argv);
 
+    QString strpath = QCoreApplication::applicationDirPath();
+    if(argc < 2)
+        strpath = strpath + "/detection_radar_esr.xml";
+    else
+        strpath = argv[1];
+    std::cout<<strpath.toStdString()<<std::endl;
+
+    iv::xmlparam::Xmlparam xp(strpath.toStdString());
+
+    std::string strmemcan = xp.GetParam("canrecv","canrecv1");
+    std::string strmemsend = xp.GetParam("cansend","cansend1");
+    std::string strmemradar = xp.GetParam("radar","radar");
+    std::string strmodulename = xp.GetParam("modulename","detection_radar_delphi_esr");
+#ifdef fujiankuan
+    gstrmemgpsimu = xp.GetParam("gpsimu_name","hcp2_gpsimu");
+    gstrmemcancar = xp.GetParam("cancar","can_car");
+#endif
+    givlog = new iv::Ivlog(strmodulename.data());
+    givfault = new iv::Ivfault(strmodulename.data());
+
+    givfault->SetFaultState(1,1,"初始化");
+    givlog->info("Initialized");
+
+    if(strmemsend.compare("cansend0") == 0){
+        canChannel = 0;
+        givlog->info("ESR","set ESR can send channel to 0");
+    }
+    if(strmemsend.compare("cansend1") == 0){
+        canChannel = 1;
+        givlog->info("ESR","set ESR can send channel to 1");
+}
+    else {
+        givlog->info("ESR","Not agx can,set default ESR can send channel to 0");
+        canChannel = 0;
+    }
+
     iv::radar::radarobjectarray x;
     x.set_mstime(0);
     int i;
@@ -542,31 +583,6 @@ int main(int argc, char *argv[])
     memset(canData5f2.byte,0,8);
     memset(canData5f4.byte,0,8);
 
-    QString strpath = QCoreApplication::applicationDirPath();
-    if(argc < 2)
-        strpath = strpath + "/detection_radar_esr.xml";
-    else
-        strpath = argv[1];
-    std::cout<<strpath.toStdString()<<std::endl;
-
-    iv::xmlparam::Xmlparam xp(strpath.toStdString());
-
-    std::string strmemcan = xp.GetParam("canrecv","canrecv1");
-    std::string strmemsend = xp.GetParam("cansend","cansend1");
-    std::string strmemradar = xp.GetParam("radar","radar");
-    std::string strmodulename = xp.GetParam("modulename","detection_radar_delphi_esr");
-#ifdef fujiankuan
-    gstrmemgpsimu = xp.GetParam("gpsimu_name","hcp2_gpsimu");
-    gstrmemcancar = xp.GetParam("cancar","can_car");
-#endif
-
-
-    givlog = new iv::Ivlog(strmodulename.data());
-    givfault = new iv::Ivfault(strmodulename.data());
-
-    givfault->SetFaultState(1,1,"初始化");
-    givlog->info("Initialized");
-
     gpa = iv::modulecomm::RegisterSend(strmemradar.data(),100000,3);
     gpb = iv::modulecomm::RegisterSend(strmemsend.data(),100000,1);
     void * pa = iv::modulecomm::RegisterRecv(strmemcan.data(),Listencan0);
@@ -580,13 +596,13 @@ int main(int argc, char *argv[])
 //    signal(SIGALRM, signalHandler);
 //    ualarm(2000,2000);
 
-    signal(SIGALRM, signalHandler);
+//    signal(SIGALRM, signalHandler);
 
-    struct itimerval new_value, old_value;
-    new_value.it_value.tv_sec = 0;
-    new_value.it_value.tv_usec = 1;
-    new_value.it_interval.tv_sec = 0;
-    new_value.it_interval.tv_usec = 20000;
-    setitimer(ITIMER_REAL, &new_value, NULL);
+//    struct itimerval new_value, old_value;
+//    new_value.it_value.tv_sec = 0;
+//    new_value.it_value.tv_usec = 1;
+//    new_value.it_interval.tv_sec = 0;
+//    new_value.it_interval.tv_usec = 20000;
+//    setitimer(ITIMER_REAL, &new_value, NULL);
     return a.exec();
 }

+ 270 - 0
src/tool/map_lanetoxodr/dialogroadmerge.cpp

@@ -0,0 +1,270 @@
+#include "dialogroadmerge.h"
+#include "ui_dialogroadmerge.h"
+
+#include "xodrfunc.h"
+
+#include <math.h>
+
+DialogRoadMerge::DialogRoadMerge(OpenDrive * pxodr,QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::DialogRoadMerge)
+{
+    ui->setupUi(this);
+
+    mpxodr = pxodr;
+}
+
+DialogRoadMerge::~DialogRoadMerge()
+{
+    delete ui;
+}
+
+
+int DialogRoadMerge::MergeGeometry(Road *pRoad1, Road *pRoad2)
+{
+    double froad1len = pRoad1->GetRoadLength();
+    int nroad2geocount = pRoad2->GetGeometryBlockCount();
+    int i;
+    GeometryBlock * pnewgb;
+    for(i=0;i<nroad2geocount;i++)
+    {
+
+
+        GeometryBlock * pgb = pRoad2->GetGeometryBlock(i);
+
+        RoadGeometry * pgeb = pgb->GetGeometryAt(0);
+        if(pgeb == 0)
+        {
+            continue;
+        }
+        pRoad1->AddGeometryBlock();
+        pnewgb = pRoad1->GetLastAddedGeometryBlock();
+        switch (pgeb->GetGeomType()) {
+        case 0:
+            pnewgb->AddGeometryLine(pgeb->GetS() + froad1len,pgeb->GetX(),pgeb->GetY(),pgeb->GetHdg(),pgeb->GetLength());
+            break;
+        case 1:
+        {
+            GeometrySpiral * pspiral = (GeometrySpiral *)pgeb;
+            pnewgb->AddGeometrySpiral(pgeb->GetS() + froad1len,pgeb->GetX(),pgeb->GetY(),pgeb->GetHdg(),pgeb->GetLength(),
+                                      pspiral->GetCurvatureStart(),pspiral->GetCurvatureEnd());
+        }
+            break;
+        case 2:
+        {
+            GeometryArc * parc = (GeometryArc *)pgeb;
+            pnewgb->AddGeometryArc(pgeb->GetS() + froad1len,parc->GetX(),parc->GetY(),
+                                   parc->GetHdg(),parc->GetLength(),parc->GetCurvature());
+        }
+            break;
+        case 4:
+        {
+            GeometryParamPoly3 * pparmp3d = (GeometryParamPoly3 *)pgeb;
+            pnewgb->AddGeometryParamPoly3(pgeb->GetS() + froad1len,pgeb->GetX(),pgeb->GetY(),
+                                          pgeb->GetHdg(),pgeb->GetLength(),pparmp3d->GetuA(),pparmp3d->GetuB(),
+                                          pparmp3d->GetuC(),pparmp3d->GetuD(),pparmp3d->GetvA(),
+                                          pparmp3d->GetvB(),pparmp3d->GetvC(),pparmp3d->GetvD());
+        }
+        default:
+            break;
+        }
+
+
+    }
+    return 0;
+}
+
+int DialogRoadMerge::MergeElevation(Road *pRoad1, Road *pRoad2)
+{
+    double froad1len = pRoad1->GetRoadLength();
+    int i;
+    int nroad2elecount = pRoad2->GetElevationCount();
+    for(i=0;i<nroad2elecount;i++)
+    {
+        Elevation * pele = pRoad2->GetElevation(i);
+        pRoad1->AddElevation(pele->GetS() + froad1len,pele->GetA(),pele->GetB(),
+                             pele->GetC(),pele->GetD());
+    }
+    return 0;
+}
+
+int DialogRoadMerge::MergeLaneSection(Road *pRoad1, Road *pRoad2)
+{
+    double froad1len = pRoad1->GetRoadLength();
+    int i;
+    bool bAddRoad2LaneSection = true;
+    if((pRoad1->GetLaneSectionCount() == pRoad2->GetLaneSectionCount())&&(pRoad1->GetLaneSectionCount() == 1))
+    {
+        if(pRoad1->GetLaneSection(0)->GetLaneCount() == pRoad2->GetLaneSection(0)->GetLaneCount())
+        {
+            LaneSection * pLS1 = pRoad1->GetLaneSection(0);
+            LaneSection * pLS2 = pRoad2->GetLaneSection(0);
+            Lane * pLane1,*pLane2;
+            pLane1 = 0;
+            pLane2 = 0;
+            unsigned int j;
+            for(j=0;j<pLS1->GetLaneCount();j++)
+            {
+                if(pLS1->GetLane(j)->GetId() != 0)
+                {
+                    pLane1 = pLS1->GetLane(j);
+                    break;
+                }
+            }
+            for(j=0;j<pLS2->GetLaneCount();j++)
+            {
+                if(pLS2->GetLane(j)->GetId() != 0)
+                {
+                    pLane2 = pLS2->GetLane(j);
+                    break;
+                }
+            }
+            if(pLane1 == pLane2)
+            {
+                bAddRoad2LaneSection = false;
+            }
+            if((pLane1 != 0) && (pLane2 != 0))
+            {
+                if((pLane1->GetLaneWidthCount() == pLane2->GetLaneWidthCount())&&(pLane1->GetLaneWidthCount()>0))
+                {
+                    LaneWidth * pLW1 = pLane1->GetLaneWidth(0);
+                    LaneWidth * pLW2 = pLane2->GetLaneWidth(0);
+                    if((pLW1->GetA() == pLW2->GetA())&&(pLW1->GetB() == pLW2->GetB())&&(pLW1->GetC() == pLW2->GetC())&&(pLW1->GetD() == pLW2->GetD()))
+                    {
+                        bAddRoad2LaneSection = false;
+                    }
+                }
+            }
+        }
+    }
+
+    if(bAddRoad2LaneSection == true)
+    {
+        int nroad2lanesectioncount = pRoad2->GetLaneSectionCount();
+        for(i=0;i<nroad2lanesectioncount;i++)
+        {
+            LaneSection ls = *(pRoad2->GetLaneSection(i));
+            ls.SetS(ls.GetS() + froad1len);
+            pRoad1->GetLaneSectionVector()->push_back(ls);
+        }
+    }
+
+    return 0;
+}
+
+int DialogRoadMerge::MergeSignal(Road *pRoad1, Road *pRoad2)
+{
+    double froad1len = pRoad1->GetRoadLength();
+    int i;
+    int nroad2sigcount = pRoad2->GetSignalCount();
+    for(i=0;i<nroad2sigcount;i++)
+    {
+        Signal xs = *(pRoad2->GetSignal(i));
+        xs.Sets(xs.Gets() + froad1len);
+        pRoad1->GetSignalVector()->push_back(xs);
+    }
+}
+
+void DialogRoadMerge::on_pushButton_Merge_clicked()
+{
+    std::string strroad1 = ui->lineEdit_Road1->text().toStdString();
+    std::string strroad2 = ui->lineEdit_Road2->text().toStdString();
+    Road * pRoad1 = xodrfunc::GetRoadByID(mpxodr,strroad1);
+    if(pRoad1 == 0)
+    {
+        QMessageBox::warning(this,"Warning","Not found road1",QMessageBox::YesAll);
+        return;
+    }
+    Road * pRoad2 = xodrfunc::GetRoadByID(mpxodr,strroad2);
+    if(pRoad2 == 0)
+    {
+        QMessageBox::warning(this,"Warning","Not found road2",QMessageBox::YesAll);
+        return;
+    }
+
+    double x1,y1,hdg1;
+    double x2,y2,hdg2;
+    xodrfunc::GetRoadXYByS(pRoad1,pRoad1->GetRoadLength(),x1,y1,hdg1);
+    xodrfunc::GetRoadXYByS(pRoad2,0,x2,y2,hdg2);
+
+    double fdis = sqrt(pow(x1-x2,2)+pow(y1-y2,2));
+
+    if(fdis > 1.0)
+    {
+        char strout[256];
+        snprintf(strout,256,"Road dis very fast. Dis is %6.3f",fdis);
+        QMessageBox::warning(this,"Warning",QString(strout),QMessageBox::YesAll);
+        return;
+    }
+
+
+    //Merge Geometry
+    Road xroad;
+    xroad = *pRoad1;
+    double froad1len = pRoad1->GetRoadLength();
+
+    MergeGeometry(pRoad1,pRoad2);
+//    int nroad2geocount = pRoad2->GetGeometryBlockCount();
+//    int i;
+//    GeometryBlock * pnewgb;
+//    for(i=0;i<nroad2geocount;i++)
+//    {
+
+
+//        GeometryBlock * pgb = pRoad2->GetGeometryBlock(i);
+
+//        RoadGeometry * pgeb = pgb->GetGeometryAt(0);
+//        if(pgeb == 0)
+//        {
+//            continue;
+//        }
+//        pRoad1->AddGeometryBlock();
+//        pnewgb = pRoad1->GetLastAddedGeometryBlock();
+//        switch (pgeb->GetGeomType()) {
+//        case 0:
+//            pnewgb->AddGeometryLine(pgeb->GetS() + froad1len,pgeb->GetX(),pgeb->GetY(),pgeb->GetHdg(),pgeb->GetLength());
+//            break;
+//        case 1:
+//        {
+//            GeometrySpiral * pspiral = (GeometrySpiral *)pgeb;
+//            pnewgb->AddGeometrySpiral(pgeb->GetS() + froad1len,pgeb->GetX(),pgeb->GetY(),pgeb->GetHdg(),pgeb->GetLength(),
+//                                      pspiral->GetCurvatureStart(),pspiral->GetCurvatureEnd());
+//        }
+//            break;
+//        case 2:
+//        {
+//            GeometryArc * parc = (GeometryArc *)pgeb;
+//            pnewgb->AddGeometryArc(pgeb->GetS() + froad1len,parc->GetX(),parc->GetY(),
+//                                   parc->GetHdg(),parc->GetLength(),parc->GetCurvature());
+//        }
+//            break;
+//        case 4:
+//        {
+//            GeometryParamPoly3 * pparmp3d = (GeometryParamPoly3 *)pgeb;
+//            pnewgb->AddGeometryParamPoly3(pgeb->GetS() + froad1len,pgeb->GetX(),pgeb->GetY(),
+//                                          pgeb->GetHdg(),pgeb->GetLength(),pparmp3d->GetuA(),pparmp3d->GetuB(),
+//                                          pparmp3d->GetuC(),pparmp3d->GetuD(),pparmp3d->GetvA(),
+//                                          pparmp3d->GetvB(),pparmp3d->GetvC(),pparmp3d->GetvD());
+//        }
+//        default:
+//            break;
+//        }
+
+
+//    }
+
+
+    //Merge ELevation
+    MergeElevation(pRoad1,pRoad2);
+
+    //Merge LaneSection
+
+    MergeLaneSection(pRoad1,pRoad2);
+
+    //Merge Signal
+    MergeSignal(pRoad1,pRoad2);
+
+
+    pRoad1->SetRoadLength(pRoad1->GetRoadLength() + pRoad2->GetRoadLength());
+     mpxodr->DeleteRoad(xodrfunc::GetRoadIndex(mpxodr,pRoad2));
+}

+ 35 - 0
src/tool/map_lanetoxodr/dialogroadmerge.h

@@ -0,0 +1,35 @@
+#ifndef DIALOGROADMERGE_H
+#define DIALOGROADMERGE_H
+
+#include <QDialog>
+
+#include "OpenDrive/OpenDrive.h"
+#include <QMessageBox>
+
+namespace Ui {
+class DialogRoadMerge;
+}
+
+class DialogRoadMerge : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit DialogRoadMerge(OpenDrive * pxodr,QWidget *parent = nullptr);
+    ~DialogRoadMerge();
+
+private slots:
+    void on_pushButton_Merge_clicked();
+
+private:
+    Ui::DialogRoadMerge *ui;
+    OpenDrive * mpxodr;
+
+private:
+    int MergeGeometry(Road * pRoad1,Road * pRoad2);
+    int MergeElevation(Road * pRoad1,Road * pRoad2);
+    int MergeLaneSection(Road * pRoad1,Road * pRoad2);
+    int MergeSignal(Road * pRoad1,Road * pRoad2);
+};
+
+#endif // DIALOGROADMERGE_H

+ 78 - 0
src/tool/map_lanetoxodr/dialogroadmerge.ui

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DialogRoadMerge</class>
+ <widget class="QDialog" name="DialogRoadMerge">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>432</width>
+    <height>262</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QPushButton" name="pushButton_Merge">
+   <property name="geometry">
+    <rect>
+     <x>160</x>
+     <y>150</y>
+     <width>89</width>
+     <height>25</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Merge</string>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="lineEdit_Road1">
+   <property name="geometry">
+    <rect>
+     <x>200</x>
+     <y>30</y>
+     <width>131</width>
+     <height>31</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="lineEdit_Road2">
+   <property name="geometry">
+    <rect>
+     <x>200</x>
+     <y>90</y>
+     <width>131</width>
+     <height>31</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label">
+   <property name="geometry">
+    <rect>
+     <x>90</x>
+     <y>40</y>
+     <width>67</width>
+     <height>17</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Road1</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_2">
+   <property name="geometry">
+    <rect>
+     <x>90</x>
+     <y>100</y>
+     <width>67</width>
+     <height>17</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Road2</string>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 146 - 0
src/tool/map_lanetoxodr/dialogroadmirror.cpp

@@ -0,0 +1,146 @@
+#include "dialogroadmirror.h"
+#include "ui_dialogroadmirror.h"
+
+#include "gnss_coordinate_convert.h"
+
+#include <math.h>
+
+#include <mainwindow.h>
+
+extern MainWindow * gw;
+
+extern double glon0 ;
+extern double glat0 ;
+
+DialogRoadMirror::DialogRoadMirror(OpenDrive * pxodr,Road * pRoad,QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::DialogRoadMirror)
+{
+    ui->setupUi(this);
+    mpxodr = pxodr;
+    mpRoad = pRoad;
+
+    if(pRoad != 0)
+    {
+        setWindowTitle(QString(pRoad->GetRoadId().data()));
+    }
+}
+
+DialogRoadMirror::~DialogRoadMirror()
+{
+    delete ui;
+}
+
+void DialogRoadMirror::on_pushButton_Mirror_clicked()
+{
+
+    double x0,y0;
+    double rel_x,rel_y;
+    double x,y;
+    double flon,flat;
+    flon = ui->lineEdit_Lon->text().toDouble();
+    flat = ui->lineEdit_Lat->text().toDouble();
+    GaussProjCal(glon0,glat0,&x0,&y0);
+    GaussProjCal(flon,flat,&x,&y);
+    rel_x = x - x0;
+    rel_y = y - y0;
+
+    double hdg = (90 - ui->lineEdit_Heading->text().toDouble())*M_PI/180.0;
+    while(hdg < 0)hdg = hdg + 2.0*M_PI;
+    while(hdg >= 2.0*M_PI)hdg = hdg - 2.0*M_PI;
+
+    x0 = rel_x;
+    y0 = rel_y;
+    double hdg0 = hdg;
+
+    Road newroad = *mpRoad;
+
+    int i;
+    int ngeobcount = mpRoad->GetGeometryBlockCount();
+    for(i=0;i<ngeobcount;i++)
+    {
+        double x,y,hdg;
+        RoadGeometry * pgeo = newroad.GetGeometryBlock(i)->GetGeometryAt(0);
+        if(pgeo == 0)continue;
+        x = newroad.GetGeometryBlock(i)->GetGeometryAt(0)->GetX();
+        y = newroad.GetGeometryBlock(i)->GetGeometryAt(0)->GetY();
+        hdg = newroad.GetGeometryBlock(i)->GetGeometryAt(0)->GetHdg();
+
+        x = x-x0;
+        y = y- y0;
+
+        double s,t;
+        double frotate = hdg0*(-1);
+        s = x*cos(frotate) -y*sin(frotate) ;
+        t = x*sin(frotate) +y*cos(frotate);
+        hdg = hdg + frotate;
+        while(hdg<0)hdg = hdg + 2.0*M_PI;
+        while(hdg>=2.0*M_PI)hdg = hdg - 2.0*M_PI;
+
+        x = s;
+        y = t*(-1);
+        hdg = hdg*(-1);
+
+        while(hdg<0)hdg = hdg + 2.0*M_PI;
+        while(hdg>=2.0*M_PI)hdg = hdg - 2.0*M_PI;
+
+        frotate = hdg0;
+
+        s = x*cos(frotate) -y*sin(frotate) ;
+        t = x*sin(frotate) +y*cos(frotate);
+        hdg = hdg + frotate;
+        while(hdg<0)hdg = hdg + 2.0*M_PI;
+        while(hdg>=2.0*M_PI)hdg = hdg - 2.0*M_PI;
+
+
+        newroad.GetGeometryBlock(i)->GetGeometryAt(0)->SetX(s + x0);
+        newroad.GetGeometryBlock(i)->GetGeometryAt(0)->SetY(t + y0);
+        newroad.GetGeometryBlock(i)->GetGeometryAt(0)->SetHdg(hdg);
+
+        if(pgeo->GetGeomType() == 1)
+        {
+            GeometrySpiral * pSpiral = (GeometrySpiral *)pgeo;
+            double startcurv = pSpiral->GetCurvatureStart() *(-1);
+            double endcurv = pSpiral->GetCurvatureEnd() *(-1);
+            pSpiral->SetCurvatureStart(startcurv);
+            pSpiral->SetCurvatureEnd(endcurv);
+        }
+
+        if(pgeo->GetGeomType() == 2)
+        {
+            GeometryArc * pArc = (GeometryArc *)pgeo;
+            double curv = pArc->GetCurvature();
+            pArc->SetCurvature(curv*(-1));
+        }
+    }
+
+    int nnewroadid = gw->CreateRoadID();
+    newroad.SetRoadId(QString::number(nnewroadid).toStdString());
+
+    mpxodr->GetRoadVector()->push_back(newroad);
+
+    bool bSaveOldRoad = true;
+    QMessageBox::StandardButton button;
+    char strout[256];
+    snprintf(strout,256,"New Road id is %d. Keep the old road.",nnewroadid);
+    button=QMessageBox::question(this,tr("Quest"),QString(strout),QMessageBox::Yes|QMessageBox::No);
+    if(button==QMessageBox::No)
+    {
+        bSaveOldRoad = false;
+    }
+    else if(button==QMessageBox::Yes)
+    {
+        bSaveOldRoad = true;
+    }
+
+    if(bSaveOldRoad == false)
+    {
+        int nroadindex = xodrfunc::GetRoadIndex(mpxodr,mpRoad);
+        if(nroadindex >= 0)
+        {
+            mpxodr->DeleteRoad(nroadindex);
+        }
+    }
+
+    this->accept();
+}

+ 32 - 0
src/tool/map_lanetoxodr/dialogroadmirror.h

@@ -0,0 +1,32 @@
+#ifndef DIALOGROADMIRROR_H
+#define DIALOGROADMIRROR_H
+
+#include <QDialog>
+
+#include "OpenDrive/OpenDrive.h"
+
+#include <QMessageBox>
+
+namespace Ui {
+class DialogRoadMirror;
+}
+
+class DialogRoadMirror : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit DialogRoadMirror(OpenDrive * pxodr,Road * pRoad, QWidget *parent = nullptr);
+    ~DialogRoadMirror();
+
+private slots:
+    void on_pushButton_Mirror_clicked();
+
+private:
+    Ui::DialogRoadMirror *ui;
+
+    OpenDrive * mpxodr;
+    Road * mpRoad;
+};
+
+#endif // DIALOGROADMIRROR_H

+ 101 - 0
src/tool/map_lanetoxodr/dialogroadmirror.ui

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DialogRoadMirror</class>
+ <widget class="QDialog" name="DialogRoadMirror">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>532</width>
+    <height>377</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QLineEdit" name="lineEdit_Lon">
+   <property name="geometry">
+    <rect>
+     <x>250</x>
+     <y>40</y>
+     <width>181</width>
+     <height>41</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="lineEdit_Lat">
+   <property name="geometry">
+    <rect>
+     <x>250</x>
+     <y>120</y>
+     <width>181</width>
+     <height>41</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="lineEdit_Heading">
+   <property name="geometry">
+    <rect>
+     <x>250</x>
+     <y>200</y>
+     <width>181</width>
+     <height>41</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pushButton_Mirror">
+   <property name="geometry">
+    <rect>
+     <x>210</x>
+     <y>280</y>
+     <width>111</width>
+     <height>41</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Mirror</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label">
+   <property name="geometry">
+    <rect>
+     <x>110</x>
+     <y>55</y>
+     <width>91</width>
+     <height>17</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Longitude</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_2">
+   <property name="geometry">
+    <rect>
+     <x>112</x>
+     <y>138</y>
+     <width>67</width>
+     <height>17</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Latitude</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_3">
+   <property name="geometry">
+    <rect>
+     <x>110</x>
+     <y>220</y>
+     <width>101</width>
+     <height>17</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Heading(°)</string>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 102 - 0
src/tool/map_lanetoxodr/dialogroadmove.cpp

@@ -0,0 +1,102 @@
+#include "dialogroadmove.h"
+#include "ui_dialogroadmove.h"
+
+#include <math.h>
+
+#include <mainwindow.h>
+
+extern MainWindow * gw;
+
+DialogRoadMove::DialogRoadMove(OpenDrive * pxodr,Road * pRoad, QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::DialogRoadMove)
+{
+    ui->setupUi(this);
+
+    mpxodr = pxodr;
+    mpRoad = pRoad;
+
+    if(pRoad != 0)
+    {
+        setWindowTitle(QString(pRoad->GetRoadId().data()));
+    }
+}
+
+DialogRoadMove::~DialogRoadMove()
+{
+    delete ui;
+}
+
+void DialogRoadMove::on_pushButton_Move_clicked()
+{
+    if(mpRoad == 0)
+    {
+        QMessageBox::warning(this,"Warning","Not have road.",QMessageBox::YesAll);
+        return;
+    }
+
+    double fMoveX = ui->lineEdit_normal->text().toDouble();
+    double fMoveY = ui->lineEdit_dir->text().toDouble();
+
+    if((fMoveX == 0)&&(fMoveY == 0))
+    {
+        QMessageBox::StandardButton button;
+        button=QMessageBox::question(this,tr("生成道路"),QString(tr("是否在原来位置生成道路")),QMessageBox::Yes|QMessageBox::No);
+        if(button==QMessageBox::No)
+        {
+            return;
+        }
+        else if(button==QMessageBox::Yes)
+        {
+
+        }
+    }
+
+    Road newroad = *mpRoad;
+
+    double hdg = 0;
+    if(mpRoad->GetGeometryBlockCount()>0)
+    {
+        hdg = mpRoad->GetGeometryBlock(0)->GetGeometryAt(0)->GetHdg();
+    }
+
+    double yoff = fMoveX*sin(hdg+M_PI/2.0) + fMoveY *sin(hdg);
+    double xoff = fMoveX*cos(hdg+M_PI/2.0) + fMoveY *cos(hdg);
+    int i;
+    int ngeobcount = mpRoad->GetGeometryBlockCount();
+    for(i=0;i<ngeobcount;i++)
+    {
+        newroad.GetGeometryBlock(i)->GetGeometryAt(0)->SetX(newroad.GetGeometryBlock(i)->GetGeometryAt(0)->GetX() + xoff);
+        newroad.GetGeometryBlock(i)->GetGeometryAt(0)->SetY(newroad.GetGeometryBlock(i)->GetGeometryAt(0)->GetY() + yoff);
+    }
+
+    int nnewroadid = gw->CreateRoadID();
+    newroad.SetRoadId(QString::number(nnewroadid).toStdString());
+
+    mpxodr->GetRoadVector()->push_back(newroad);
+
+    bool bSaveOldRoad = true;
+    QMessageBox::StandardButton button;
+    char strout[256];
+    snprintf(strout,256,"New Road id is %d. Keep the old road.",nnewroadid);
+    button=QMessageBox::question(this,tr("Quest"),QString(strout),QMessageBox::Yes|QMessageBox::No);
+    if(button==QMessageBox::No)
+    {
+        bSaveOldRoad = false;
+    }
+    else if(button==QMessageBox::Yes)
+    {
+        bSaveOldRoad = true;
+    }
+
+    if(bSaveOldRoad == false)
+    {
+        int nroadindex = xodrfunc::GetRoadIndex(mpxodr,mpRoad);
+        if(nroadindex >= 0)
+        {
+            mpxodr->DeleteRoad(nroadindex);
+        }
+    }
+
+    this->accept();
+}

+ 32 - 0
src/tool/map_lanetoxodr/dialogroadmove.h

@@ -0,0 +1,32 @@
+#ifndef DIALOGROADMOVE_H
+#define DIALOGROADMOVE_H
+
+#include <QDialog>
+
+#include "OpenDrive/OpenDrive.h"
+
+#include <QMessageBox>
+
+namespace Ui {
+class DialogRoadMove;
+}
+
+class DialogRoadMove : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit DialogRoadMove(OpenDrive * pxodr,Road * pRoad, QWidget *parent = nullptr);
+    ~DialogRoadMove();
+
+private slots:
+    void on_pushButton_Move_clicked();
+
+private:
+    Ui::DialogRoadMove *ui;
+
+    OpenDrive * mpxodr;
+    Road * mpRoad;
+};
+
+#endif // DIALOGROADMOVE_H

+ 78 - 0
src/tool/map_lanetoxodr/dialogroadmove.ui

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DialogRoadMove</class>
+ <widget class="QDialog" name="DialogRoadMove">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>552</width>
+    <height>283</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QPushButton" name="pushButton_Move">
+   <property name="geometry">
+    <rect>
+     <x>200</x>
+     <y>170</y>
+     <width>89</width>
+     <height>25</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Move</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label">
+   <property name="geometry">
+    <rect>
+     <x>60</x>
+     <y>100</y>
+     <width>181</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Road Direction</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_2">
+   <property name="geometry">
+    <rect>
+     <x>60</x>
+     <y>40</y>
+     <width>171</width>
+     <height>17</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Road Normal Direction</string>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="lineEdit_normal">
+   <property name="geometry">
+    <rect>
+     <x>300</x>
+     <y>32</y>
+     <width>161</width>
+     <height>31</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="lineEdit_dir">
+   <property name="geometry">
+    <rect>
+     <x>300</x>
+     <y>95</y>
+     <width>161</width>
+     <height>31</height>
+    </rect>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 117 - 0
src/tool/map_lanetoxodr/dialogroadrotate.cpp

@@ -0,0 +1,117 @@
+#include "dialogroadrotate.h"
+#include "ui_dialogroadrotate.h"
+
+#include <math.h>
+
+#include <mainwindow.h>
+
+extern MainWindow * gw;
+
+DialogRoadRotate::DialogRoadRotate(OpenDrive * pxodr,Road * pRoad, QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::DialogRoadRotate)
+{
+    ui->setupUi(this);
+
+    mpxodr = pxodr;
+    mpRoad = pRoad;
+
+    if(pRoad != 0)
+    {
+        setWindowTitle(QString(pRoad->GetRoadId().data()));
+    }
+}
+
+DialogRoadRotate::~DialogRoadRotate()
+{
+    delete ui;
+}
+
+void DialogRoadRotate::on_pushButton_Rotate_clicked()
+{
+    if(mpRoad == 0)
+    {
+        QMessageBox::warning(this,"Warning","Not have road.",QMessageBox::YesAll);
+        return;
+    }
+
+    double frotate = ui->lineEdit_rotatedegree->text().toDouble() *M_PI/180.0;
+
+    if(frotate == 0)
+    {
+        QMessageBox::StandardButton button;
+        button=QMessageBox::question(this,tr("生成道路"),QString(tr("是否在原来位置生成道路")),QMessageBox::Yes|QMessageBox::No);
+        if(button==QMessageBox::No)
+        {
+            return;
+        }
+        else if(button==QMessageBox::Yes)
+        {
+
+        }
+    }
+
+    Road newroad = *mpRoad;
+    double hdg0 = 0;
+    double x0 = 0;
+    double y0 = 0;
+    if(mpRoad->GetGeometryBlockCount()>0)
+    {
+        hdg0 = mpRoad->GetGeometryBlock(0)->GetGeometryAt(0)->GetHdg();
+        x0 = mpRoad->GetGeometryBlock(0)->GetGeometryAt(0)->GetX();
+        y0 = mpRoad->GetGeometryBlock(0)->GetGeometryAt(0)->GetY();
+    }
+
+    int i;
+    int ngeobcount = mpRoad->GetGeometryBlockCount();
+    for(i=0;i<ngeobcount;i++)
+    {
+        double x,y,hdg;
+        x = newroad.GetGeometryBlock(i)->GetGeometryAt(0)->GetX();
+        y = newroad.GetGeometryBlock(i)->GetGeometryAt(0)->GetY();
+        hdg = newroad.GetGeometryBlock(i)->GetGeometryAt(0)->GetHdg();
+
+        double s,t;
+        s = (x-x0)*cos(frotate) -(y-y0)*sin(frotate) + x0;
+        t = (x-x0)*sin(frotate) +(y-y0)*cos(frotate) + y0;
+        hdg = hdg + frotate;
+        while(hdg<0)hdg = hdg + 2.0*M_PI;
+        while(hdg>=2.0*M_PI)hdg = hdg - 2.0*M_PI;
+
+
+        newroad.GetGeometryBlock(i)->GetGeometryAt(0)->SetX(s);
+        newroad.GetGeometryBlock(i)->GetGeometryAt(0)->SetY(t);
+        newroad.GetGeometryBlock(i)->GetGeometryAt(0)->SetHdg(hdg);
+    }
+
+    int nnewroadid = gw->CreateRoadID();
+    newroad.SetRoadId(QString::number(nnewroadid).toStdString());
+
+    mpxodr->GetRoadVector()->push_back(newroad);
+
+    bool bSaveOldRoad = true;
+    QMessageBox::StandardButton button;
+    char strout[256];
+    snprintf(strout,256,"New Road id is %d. Keep the old road.",nnewroadid);
+    button=QMessageBox::question(this,tr("Quest"),QString(strout),QMessageBox::Yes|QMessageBox::No);
+    if(button==QMessageBox::No)
+    {
+        bSaveOldRoad = false;
+    }
+    else if(button==QMessageBox::Yes)
+    {
+        bSaveOldRoad = true;
+    }
+
+    if(bSaveOldRoad == false)
+    {
+        int nroadindex = xodrfunc::GetRoadIndex(mpxodr,mpRoad);
+        if(nroadindex >= 0)
+        {
+            mpxodr->DeleteRoad(nroadindex);
+        }
+    }
+
+    this->accept();
+
+}

+ 32 - 0
src/tool/map_lanetoxodr/dialogroadrotate.h

@@ -0,0 +1,32 @@
+#ifndef DIALOGROADROTATE_H
+#define DIALOGROADROTATE_H
+
+#include <QDialog>
+
+#include "OpenDrive/OpenDrive.h"
+
+#include <QMessageBox>
+
+namespace Ui {
+class DialogRoadRotate;
+}
+
+class DialogRoadRotate : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit DialogRoadRotate(OpenDrive * pxodr,Road * pRoad, QWidget *parent = nullptr);
+    ~DialogRoadRotate();
+
+private slots:
+    void on_pushButton_Rotate_clicked();
+
+private:
+    Ui::DialogRoadRotate *ui;
+
+    OpenDrive * mpxodr;
+    Road * mpRoad;
+};
+
+#endif // DIALOGROADROTATE_H

+ 55 - 0
src/tool/map_lanetoxodr/dialogroadrotate.ui

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DialogRoadRotate</class>
+ <widget class="QDialog" name="DialogRoadRotate">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>487</width>
+    <height>242</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QLineEdit" name="lineEdit_rotatedegree">
+   <property name="geometry">
+    <rect>
+     <x>250</x>
+     <y>66</y>
+     <width>181</width>
+     <height>31</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label">
+   <property name="geometry">
+    <rect>
+     <x>90</x>
+     <y>70</y>
+     <width>131</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Degree(°)</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pushButton_Rotate">
+   <property name="geometry">
+    <rect>
+     <x>170</x>
+     <y>140</y>
+     <width>121</width>
+     <height>31</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Rotate</string>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 4 - 1
src/tool/map_lanetoxodr/dialogroadsplit.cpp

@@ -491,10 +491,13 @@ int DialogRoadSplit::SplitLaneSection(Road *proad1, Road *proad2,  vector<LaneSe
             proad2->GetLaneSectionVector()->insert(proad2->GetLaneSectionVector()->begin(),LS);
         }
 
-        for(i=0;i<proad2->GetLaneSectionCount();i++)
+        proad2->GetLaneSectionVector()->at(0).SetS(0);
+
+        for(i=1;i<proad2->GetLaneSectionCount();i++)
         {
             proad2->GetLaneSectionVector()->at(i).SetS(proad2->GetLaneSectionVector()->at(i).GetS() - flen1);
         }
+
     }
     return 0;
 }

+ 2 - 2
src/tool/map_lanetoxodr/mainwindow.cpp

@@ -4170,8 +4170,8 @@ int MainWindow::FindNewRoadID(OpenDrive *pxodr1, OpenDrive *pxodr2)
 int MainWindow::FindNewJunctionID(OpenDrive *pxodr1, OpenDrive *pxodr2)
 {
     int njunctionsize1,njunctionsize2;
-    njunctionsize1 = pxodr1->GetRoadCount();
-    njunctionsize2 = pxodr2->GetRoadCount();
+    njunctionsize1 = pxodr1->GetJunctionCount();
+    njunctionsize2 = pxodr2->GetJunctionCount();
     int i;
     int * pnid = new int[njunctionsize1 + njunctionsize2];
     std::shared_ptr<int> ppnid;ppnid.reset(pnid);

+ 12 - 0
src/tool/map_lanetoxodr/map_lanetoxodr.pro

@@ -33,6 +33,10 @@ SOURCES += \
     dialogeditlane.cpp \
     dialogeditroadmark.cpp \
     dialoglanefromrtk.cpp \
+    dialogroadmerge.cpp \
+    dialogroadmirror.cpp \
+    dialogroadmove.cpp \
+    dialogroadrotate.cpp \
     dialogroadsplit.cpp \
     ivxodrtool.cpp \
         main.cpp \
@@ -77,6 +81,10 @@ HEADERS += \
     dialogeditlane.h \
     dialogeditroadmark.h \
     dialoglanefromrtk.h \
+    dialogroadmerge.h \
+    dialogroadmirror.h \
+    dialogroadmove.h \
+    dialogroadrotate.h \
     dialogroadsplit.h \
     ivxodrtool.h \
         mainwindow.h \
@@ -117,6 +125,10 @@ FORMS += \
         dialogeditlane.ui \
         dialogeditroadmark.ui \
         dialoglanefromrtk.ui \
+        dialogroadmerge.ui \
+        dialogroadmirror.ui \
+        dialogroadmove.ui \
+        dialogroadrotate.ui \
         dialogroadsplit.ui \
         mainwindow.ui \
         roadeditdialog.ui \

+ 90 - 0
src/tool/map_lanetoxodr/roadeditdialog.cpp

@@ -462,3 +462,93 @@ void RoadEditDialog::on_pushButton_RoadSplit_clicked()
     }
     on_comboBox_Road_currentIndexChanged(ncurindex);
 }
+
+void RoadEditDialog::on_pushButton_RoadMerge_clicked()
+{
+    DialogRoadMerge roadmerge(mpxodr,this);
+    roadmerge.exec();
+
+    unsigned int ncurindex = ui->comboBox_Road->currentIndex();
+    ui->comboBox_Road->clear();
+    int i;
+    int nroadcount = mpxodr->GetRoadCount();
+    for(i=0;i<nroadcount;i++)
+    {
+        const char * strname = mpxodr->GetRoad(i)->GetRoadId().data();
+        ui->comboBox_Road->addItem(strname);
+
+    }
+    on_comboBox_Road_currentIndexChanged(ncurindex);
+}
+
+void RoadEditDialog::on_pushButton_MoveRoad_clicked()
+{
+    if(mpCurRoad == 0)
+    {
+        QMessageBox::warning(this,"Warning","Not Select Road");
+        return;
+    }
+
+    DialogRoadMove roadmove(mpxodr,mpCurRoad,this);
+    roadmove.exec();
+
+    unsigned int ncurindex = ui->comboBox_Road->currentIndex();
+    ui->comboBox_Road->clear();
+    int i;
+    int nroadcount = mpxodr->GetRoadCount();
+    for(i=0;i<nroadcount;i++)
+    {
+        const char * strname = mpxodr->GetRoad(i)->GetRoadId().data();
+        ui->comboBox_Road->addItem(strname);
+
+    }
+    on_comboBox_Road_currentIndexChanged(ncurindex);
+}
+
+void RoadEditDialog::on_pushButton_RotateRoad_clicked()
+{
+    if(mpCurRoad == 0)
+    {
+        QMessageBox::warning(this,"Warning","Not Select Road");
+        return;
+    }
+
+    DialogRoadRotate roadrotate(mpxodr,mpCurRoad,this);
+    roadrotate.exec();
+
+    unsigned int ncurindex = ui->comboBox_Road->currentIndex();
+    ui->comboBox_Road->clear();
+    int i;
+    int nroadcount = mpxodr->GetRoadCount();
+    for(i=0;i<nroadcount;i++)
+    {
+        const char * strname = mpxodr->GetRoad(i)->GetRoadId().data();
+        ui->comboBox_Road->addItem(strname);
+
+    }
+    on_comboBox_Road_currentIndexChanged(ncurindex);
+}
+
+void RoadEditDialog::on_pushButton_MirrorRoad_clicked()
+{
+    if(mpCurRoad == 0)
+    {
+        QMessageBox::warning(this,"Warning","Not Select Road");
+        return;
+    }
+
+    DialogRoadMirror roadmirror(mpxodr,mpCurRoad,this);
+    roadmirror.exec();
+
+    unsigned int ncurindex = ui->comboBox_Road->currentIndex();
+    ui->comboBox_Road->clear();
+    int i;
+    int nroadcount = mpxodr->GetRoadCount();
+    for(i=0;i<nroadcount;i++)
+    {
+        const char * strname = mpxodr->GetRoad(i)->GetRoadId().data();
+        ui->comboBox_Road->addItem(strname);
+
+    }
+    on_comboBox_Road_currentIndexChanged(ncurindex);
+}

+ 12 - 0
src/tool/map_lanetoxodr/roadeditdialog.h

@@ -15,6 +15,10 @@
 #include "dialogeditroadmark.h"
 #include "dialoglanefromrtk.h"
 #include "dialogroadsplit.h"
+#include "dialogroadmerge.h"
+#include "dialogroadmove.h"
+#include "dialogroadrotate.h"
+#include "dialogroadmirror.h"
 
 namespace Ui {
 class RoadEditDialog;
@@ -48,6 +52,14 @@ private slots:
 
     void on_pushButton_RoadSplit_clicked();
 
+    void on_pushButton_RoadMerge_clicked();
+
+    void on_pushButton_MoveRoad_clicked();
+
+    void on_pushButton_RotateRoad_clicked();
+
+    void on_pushButton_MirrorRoad_clicked();
+
 private:
     Ui::RoadEditDialog *ui;
     OpenDrive * mpxodr;

+ 53 - 1
src/tool/map_lanetoxodr/roadeditdialog.ui

@@ -262,7 +262,7 @@
   <widget class="QPushButton" name="pushButton_RoadSplit">
    <property name="geometry">
     <rect>
-     <x>878</x>
+     <x>1013</x>
      <y>210</y>
      <width>181</width>
      <height>31</height>
@@ -272,6 +272,58 @@
     <string>Road Split</string>
    </property>
   </widget>
+  <widget class="QPushButton" name="pushButton_RoadMerge">
+   <property name="geometry">
+    <rect>
+     <x>1010</x>
+     <y>283</y>
+     <width>191</width>
+     <height>31</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Road Merge</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pushButton_MoveRoad">
+   <property name="geometry">
+    <rect>
+     <x>1010</x>
+     <y>356</y>
+     <width>191</width>
+     <height>31</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Move Road</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pushButton_RotateRoad">
+   <property name="geometry">
+    <rect>
+     <x>1010</x>
+     <y>431</y>
+     <width>191</width>
+     <height>31</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Rotate Road</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pushButton_MirrorRoad">
+   <property name="geometry">
+    <rect>
+     <x>1010</x>
+     <y>506</y>
+     <width>191</width>
+     <height>31</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Mirror Road</string>
+   </property>
+  </widget>
  </widget>
  <resources/>
  <connections/>

+ 145 - 0
src/tool/map_lanetoxodr/xodrfunc.cpp

@@ -870,3 +870,148 @@ double xodrfunc::GetAcurateDis(const double x, const double y, Road *pRoad,  con
 
 
 }
+
+
+
+int xodrfunc::GetLineXY(GeometryLine *pline, double soff, double &x, double &y, double &hdg)
+{
+    if(soff<0)return -1;
+
+    hdg = pline->GetHdg();
+    x = pline->GetX() + soff*cos(hdg);
+    y = pline->GetY() + soff*sin(hdg);
+    return 0;
+}
+
+Road * xodrfunc::GetRoadByID(OpenDrive * pxodr,std::string strroadid)
+{
+    Road * pRoad = 0;
+    int nroadcount = pxodr->GetRoadCount();
+    int i;
+    for(i=0;i<nroadcount;i++)
+    {
+        if(pxodr->GetRoad(i)->GetRoadId() == strroadid)
+        {
+            pRoad = pxodr->GetRoad(i);
+            break;
+        }
+    }
+    return pRoad;
+}
+
+int xodrfunc::GetSpiralXY(GeometrySpiral *pspira, double soff, double &x, double &y, double &hdg)
+{
+    pspira->GetCoords(pspira->GetS() + soff,x,y,hdg);
+    return 0;
+}
+
+int xodrfunc::GetArcXY(GeometryArc *parc, double soff, double &x, double &y, double &hdg)
+{
+    if(parc->GetCurvature() == 0)return -1;
+    double R = fabs(1.0/parc->GetCurvature());
+
+    //calculate arc center
+    double x_center = parc->GetX() + (1.0/parc->GetCurvature()) * cos(parc->GetHdg() + M_PI/2.0);
+    double y_center = parc->GetY() + (1.0/parc->GetCurvature()) * sin(parc->GetHdg()+ M_PI/2.0);
+
+    double arcdiff = soff/R;
+
+    if(parc->GetCurvature() > 0)
+    {
+        x = x_center + R * cos(parc->GetHdg() + arcdiff - M_PI/2.0);
+        y = y_center + R * sin(parc->GetHdg() + arcdiff - M_PI/2.0);
+        hdg = parc->GetHdg() + arcdiff;
+    }
+    else
+    {
+        x = x_center + R * cos(parc->GetHdg() -arcdiff + M_PI/2.0);
+        y = y_center + R * sin(parc->GetHdg() -arcdiff + M_PI/2.0);
+        hdg = parc->GetHdg() - arcdiff;
+    }
+
+
+
+    return 0;
+}
+
+int xodrfunc::GetParamPoly3XY(GeometryParamPoly3 *pparam3d, double soff, double &x, double &y, double &hdg)
+{
+    double xtem,ytem;
+    double ua,ub,uc,ud,va,vb,vc,vd;
+    ua = pparam3d->GetuA();ub= pparam3d->GetuB();uc= pparam3d->GetuC();ud = pparam3d->GetuD();
+    va = pparam3d->GetvA();vb= pparam3d->GetvB();vc= pparam3d->GetvC();vd = pparam3d->GetvD();
+//        xtem = parc->GetuA() + parc->GetuB() * s * len + parc->GetuC() * s*s *pow(len,2) + parc->GetuD() * s*s*s *pow(len,3);
+//        ytem = parc->GetvA() + parc->GetvB() * s* len + parc->GetvC() * s*s *pow(len,2) + parc->GetvD() * s*s*s *pow(len,3);
+    xtem = ua + ub * soff  + uc * soff * soff  + ud * soff *soff*soff ;
+    ytem = va + vb * soff + vc * soff*soff  + vd * soff*soff*soff ;
+    x = xtem*cos(pparam3d->GetHdg()) - ytem * sin(pparam3d->GetHdg()) + pparam3d->GetX();
+    y = xtem*sin(pparam3d->GetHdg()) + ytem * cos(pparam3d->GetHdg()) + pparam3d->GetY();
+    if(soff<0.3)hdg = pparam3d->GetHdg();
+    else
+    {
+        double soff1 = soff - 0.1;
+        double x1,y1;
+        xtem = ua + ub * soff1  + uc * soff1 * soff1  + ud * soff1 *soff1*soff1 ;
+        ytem = va + vb * soff1 + vc * soff1*soff1  + vd * soff1*soff1*soff1 ;
+        x1 = xtem*cos(pparam3d->GetHdg()) - ytem * sin(pparam3d->GetHdg()) + pparam3d->GetX();
+        y1 = xtem*sin(pparam3d->GetHdg()) + ytem * cos(pparam3d->GetHdg()) + pparam3d->GetY();
+        hdg = CalcHdg(QPointF(x1,y1),QPointF(x,y));
+    }
+    return 0;
+}
+
+int xodrfunc::GetRoadXYByS(Road *pRoad, const double s, double &x, double &y, double &hdg)
+{
+    if(s<0)return -1;
+    if(s>(pRoad->GetRoadLength()+0.1))return -2;
+    if(pRoad == 0)return -3;
+    if(pRoad->GetGeometryBlockCount()<1)return -4;
+    int i;
+    int nroadgeosize = pRoad->GetGeometryBlockCount();
+    RoadGeometry * pgeosel = pRoad->GetGeometryBlock(nroadgeosize -1)->GetGeometryAt(0);
+    for(i=0;i<(nroadgeosize-1);i++)
+    {
+        if(s<pRoad->GetGeometryBlock(i+1)->GetGeometryAt(0)->GetS())
+        {
+
+            pgeosel = pRoad->GetGeometryBlock(0)->GetGeometryAt(0);
+            break;
+        }
+    }
+
+
+    switch (pgeosel->GetGeomType()) {
+    case 0:
+        return GetLineXY((GeometryLine *)pgeosel,(s-pgeosel->GetS()),x,y,hdg);
+        break;
+    case 1:
+        return GetSpiralXY((GeometrySpiral *)pgeosel,(s-pgeosel->GetS()),x,y,hdg);
+        break;
+    case 2:
+        return GetArcXY((GeometryArc *)pgeosel,(s-pgeosel->GetS()),x,y,hdg);
+
+        break;
+    case 3:
+        break;
+    case 4:
+        return GetParamPoly3XY((GeometryParamPoly3 *)pgeosel,(s-pgeosel->GetS()),x,y,hdg);
+        break;
+    default:
+        break;
+    }
+    return -5;
+}
+
+int xodrfunc::GetRoadIndex(OpenDrive * pxodr, Road *pRoad)
+{
+    int nroadcount = pxodr->GetRoadCount();
+    int i;
+    for(i=0;i<nroadcount;i++)
+    {
+        if(pxodr->GetRoad(i) == pRoad)
+        {
+            return i;
+        }
+    }
+    return -1;
+}

+ 11 - 0
src/tool/map_lanetoxodr/xodrfunc.h

@@ -49,6 +49,17 @@ public:
                                 const double neary,const double nearhead,int * pnlane= 0);
 
     static std::vector<iv::LanePoint> GetAllLanePoint(Road * pRoad,const double s,const double x, const double y,const double fhdg);
+
+public:
+    static Road * GetRoadByID(OpenDrive * pxodr,std::string strroadid);
+    static int GetRoadXYByS(Road * pRoad,const double s,double &x, double & y, double & hdg);
+
+    static int GetLineXY(GeometryLine * pline,double soff,double &x, double & y, double & hdg);
+    static int GetSpiralXY(GeometrySpiral * pspira,double soff,double &x, double & y, double & hdg);
+    static int GetArcXY(GeometryArc * parc,double soff,double &x, double & y, double & hdg);
+    static int GetParamPoly3XY(GeometryParamPoly3 * pparam3d,double soff,double &x, double & y, double & hdg);
+
+    static int GetRoadIndex(OpenDrive * pxodr, Road * pRoad);
 };
 
 #endif // XODRFUNC_H