自动驾驶仿真:python和carsim联合仿真案例

自动驾驶simulation 2024-08-04 12:35:07 阅读 80

文章目录

前言一、Carsim官方案例二、Carsim配置1、车辆模型2、procedure配置3、Run Control配置

三、python编写四、运行carsim五、运行python六、补充vs_solver.py代码总结


前言

carsim内部有许多相关联合仿真的demo,simulink、labview等等都有涉及,这里简单介绍下python和carsim联合仿真的方法,虽然carsim官方有个Steer_Control.py相关的案例,但是感觉比较冗余,这里抽出重点部分和大家交流探讨下。


<code>提示:以下是本篇文章正文内容,下面案例可供参考

一、Carsim官方案例

在carsim项目文件夹路径下,例:C:\Program Files (x86)\CarSim2022.1_Data\Extensions\Custom_Py,里面有几个案例可以参考下。

在这里插入图片描述

二、Carsim配置

1、车辆模型

1)这里的车辆模型随便选一个就行了

在这里插入图片描述

在这里插入图片描述

2、procedure配置

1)开环的节气门开度控制-油门

2)开环的制动主缸压力控制-刹车

3)开环的方向盘角度控制

4)运行条件选择Run forver

在这里插入图片描述

3、Run Control配置

1)选择运行模型为:Self-Contained Solvers

在这里插入图片描述

2)选择类型为C Wrapper,64-bit

在这里插入图片描述

3)按照默认选择外部的解释器

在这里插入图片描述

4)配置输入分别为:节气门开度,制动主缸压力,方向盘角度

在这里插入图片描述

5)配置输出

在这里插入图片描述

三、python编写

1)第一步先找到vs_solver.py,用于调用simfile获取相关carsim dll的引用。vs_solver.py路径在<code>C:\Program Files (x86)\CarSim2022.1_Data\Extensions\Custom_Py,我们在下面代码中会引用vs_solver.py。

2)代码部分都很简单,一个是import vs_solver,另外一个比较重要的是simfile的路径需要填写,一般在你创建项目目录下如:C:\Program Files (x86)\CarSim2022.1_Data\simfile.sim,这个一定要根据你项目路径来填写。

import os

import keyboard

import ctypes

import vs_solver

class carsim_simulation():

def __init__(self):

self.simfile_path = r'C:\Program Files (x86)\CarSim2022.1_Data\simfile.sim'

self.vs = vs_solver.vs_solver()

self.vs_dll_exist_flag = self.vs_dll_is_exist()

self.configuration = self.vs.read_configuration(self.simfile_path)

def vs_dll_is_exist(self):

dll_path = self.vs.get_dll_path(self.simfile_path)

if dll_path is not None and os.path.exists(dll_path):

vs_dll = ctypes.cdll.LoadLibrary(dll_path)

if self.vs.get_api(vs_dll):

exist_flag = True

else:

exist_flag = False

print(f'can not get dll api, please check the dll { dll_path}')

else:

exist_flag = False

print(f'please check dll_path or simfile_path existence or not')

return exist_flag

def get_export_array(self):

return self.vs.copy_export_vars(carsim_sim.configuration.get('n_export'))

def get_time_step(self):

return self.configuration.get('t_step')

def stop(self, t_current):

self.vs.terminate_run(t_current)

if __name__ == '__main__':

carsim_sim = carsim_simulation()

t_current = carsim_sim.get_time_step()

export_array = carsim_sim.get_export_array()

status = 0

while status == 0:

#更新当前时间

t_current = t_current + carsim_sim.get_time_step()

import_array = [0.1, 0, 0]

3 status, export_array = carsim_sim.vs.integrate_io(t_current, import_array, export_array)

print(f'current_x: { export_array[0]}, current_y: { export_array[6]}')

if keyboard.is_pressed('q'):

carsim_sim.stop(t_current)

break

四、运行carsim

1)运行carsim等待几秒会出现黑窗,然后关掉黑窗即可。

在这里插入图片描述

五、运行python

1)运行python脚本之后结果哗啦啦就出来了,就很简单。

在这里插入图片描述

六、补充vs_solver.py代码

<code># Copyright (c) 2019-2020, Mechanical Simulation Corporation

# All rights reserved.

#

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN

# THE SOFTWARE.

import ctypes

import sys,string,os,re

class vs_solver:

def __init__(self):

self.dll_handle = None

def get_api(self, dll_handle):

self.dll_handle = dll_handle

if dll_handle.vs_run is not None and \

dll_handle.vs_initialize is not None and \

dll_handle.vs_read_configuration is not None and \

dll_handle.vs_integrate_io is not None and \

dll_handle.vs_copy_export_vars is not None and \

dll_handle.vs_terminate_run is not None and \

dll_handle.vs_error_occurred is not None and \

dll_handle.vs_set_opt_error_dialog is not None and \

dll_handle.vs_get_error_message is not None and \

dll_handle.vs_road_l is not None:

dll_handle.vs_road_l.restype = ctypes.c_double

#vsimports = (ctypes.c_double*1)()

#vsexports = (ctypes.c_double*1)()

#dll_handle.vs_integrate_io.argtypes = [ctypes.c_double, ctypes.byref(vsimports), ctypes.byref(vsexports)]

##dll_handle.vs.integrate_io.argtypes = [ctypes.c_double, ctypes.c_int]

return True

else:

return False

def get_char_pointer(self, python_string):

# python version is greater or equal to 3.0 then we need to define the encoding when converting a string to

# bytes. Once that is done we can convert the the python string to a char*.

if sys.version_info >= (3, 0):

char_pointer = ctypes.c_char_p(bytes(python_string, 'UTF-8'))

else:

char_pointer = ctypes.c_char_p(bytes(python_string))

return char_pointer

def get_parameter_value(self, line):

index = line.find(' ')

if index >= 0:

return line[index:].strip()

else:

return None

def get_dll_path(self, path_to_sim_file):

dll_path = None

prog_dir = None

veh_code = None

product_name = None

product_ver = None

library_name = None

bitness_suffix = '_64' if ctypes.sizeof(ctypes.c_voidp) == 8 else '_32'

platform = sys.platform

sim_file = open(path_to_sim_file, 'r')

if (platform == 'linux'):

libfiletype = 'SOFILE'

else:

libfiletype = 'DLLFILE'

for line in sim_file:

if line.lstrip().startswith('PROGDIR'):

prog_dir = self.get_parameter_value(line)

if prog_dir == '.':

prog_dir = os.getcwd()

elif line.lstrip().startswith(libfiletype):

dll_path = self.get_parameter_value(line)

elif line.lstrip().startswith('VEHICLE_CODE'):

veh_code = self.get_parameter_value(line)

elif line.lstrip().startswith('PRODUCT_ID'):

product_name = self.get_parameter_value(line)

elif line.lstrip().startswith('PRODUCT_VER'):

product_ver = self.get_parameter_value(line)

sim_file.close()

if "tire" in veh_code:

if platform == 'linux':

library_name = 'libtire.so.%s'%(product_ver)

else:

library_name = "tire" + bitness_suffix

elif product_name == "CarSim":

if platform == 'linux':

library_name = 'libcarsim.so.%s'%(product_ver)

else:

library_name = "carsim" + bitness_suffix

elif product_name == "TruckSim":

if platform == 'linux':

library_name = 'libtrucksim.so.%s'%(product_ver)

else:

library_name = "trucksim" + bitness_suffix

elif product_name == "BikeSim":

if platform == 'linux':

library_name = 'libbikesim.so.%s'%(product_ver)

else:

library_name = "bikesim" + bitness_suffix

else:

if platform == 'linux':

library_name = 'libcarsim.so.%s'%(product_ver)

else:

library_name = veh_code + bitness_suffix

if dll_path is None:

if sys.platform == 'linux':

dll_path = os.path.join(prog_dir, library_name);

else:

dll_path = os.path.join(prog_dir, "Programs", "Solvers", library_name + ".dll")

return dll_path

def run(self, path_to_sim_file):

error_occurred = 1

path_to_sim_file_ptr = self.get_char_pointer(path_to_sim_file)

if path_to_sim_file_ptr is not None:

error_occurred = self.dll_handle.vs_run(path_to_sim_file_ptr)

return error_occurred

def print_error(self):

error_string = ctypes.c_char_p(self.dll_handle.vs_get_error_message())

print(error_string.value.decode('ascii'))

def read_configuration(self, path_to_sim_file):

path_to_sim_file_ptr = self.get_char_pointer(path_to_sim_file)

platform = sys.platform

if path_to_sim_file_ptr is not None:

if platform == 'linux':

ref_n_import = ctypes.c_long()

ref_n_export = ctypes.c_longlong()

else:

ref_n_import = ctypes.c_int32()

ref_n_export = ctypes.c_int64()

ref_t_start = ctypes.c_double()

ref_t_stop = ctypes.c_double()

ref_t_step = ctypes.c_double()

self.dll_handle.vs_read_configuration(path_to_sim_file_ptr,

ctypes.byref(ref_n_import),

ctypes.byref(ref_n_export),

ctypes.byref(ref_t_start),

ctypes.byref(ref_t_stop),

ctypes.byref(ref_t_step))

configuration = { 'n_import': ref_n_import.value,

'n_export': ref_n_export.value,

't_start': ref_t_start.value,

't_stop': ref_t_stop.value,

't_step': ref_t_step.value}

return configuration

def copy_export_vars(self, n_export):

export_array = (ctypes.c_double * n_export)()

self.dll_handle.vs_copy_export_vars(ctypes.cast(export_array, ctypes.POINTER(ctypes.c_double)))

export_list = [export_array[i] for i in range(n_export)]

return export_list

def get_road_l(self, x, y):

x_c_double = ctypes.c_double(x)

y_c_double = ctypes.c_double(y)

c_double_return = self.dll_handle.vs_road_l(x_c_double, y_c_double)

return float(c_double_return)

def integrate_io(self, t_current, import_array, export_array):

t_current_c_double = ctypes.c_double(t_current)

import_c_double_array = (ctypes.c_double * len(import_array))(*import_array)

export_c_double_array = (ctypes.c_double * len(export_array))(*export_array)

c_integer_return = self.dll_handle.vs_integrate_io(t_current_c_double,

ctypes.byref(import_c_double_array),

ctypes.byref(export_c_double_array))

export_array = [export_c_double_array[i] for i in range(len(export_array))]

return c_integer_return, export_array

def initialize(self, t):

t_c_double = ctypes.c_double(t)

self.dll_handle.vs_initialize(t_c_double)

def terminate_run(self, t):

t_c_double = ctypes.c_double(t)

self.dll_handle.vs_terminate_run(t_c_double)


总结

1、这里关于solvers的细节其实都没说,因为里面确实也没什么内容好讲的,本质就是调用carsim.dll,如果你需要更多的函数解析其实可以看vs_api.h,路径在C:\Program Files (x86)\CarSim2022.1_Data\Extensions\Custom_C\common,具体内容如下图所示。

在这里插入图片描述




声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。