当前位置: 代码网 > it编程>前端脚本>Python > 自动驾驶仿真:python和carsim联合仿真案例

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

2024年07月31日 Python 我要评论
carsim内部有许多相关联合仿真的demo,simulink、labview等等都有涉及,这里简单介绍下python和carsim联合仿真的方法,虽然carsim官方有个Steer_Control.py相关的案例,但是感觉比较冗余,这里抽出重点部分和大家交流探讨下。提示:以下是本篇文章正文内容,下面案例可供参考1、这里关于solvers的细节其实都没说,因为里面确实也没什么内容好讲的,本质就是调用carsim.dll,如果你需要更多的函数解析其实可以看vs_api.h,路径在,具体内容如下图所示。


前言

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


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

一、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路径在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代码

#  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,具体内容如下图所示。

在这里插入图片描述


(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com