符合要求的代码并经验证有效

img


符合要求的代码并经验证有效与船舶知识有关,与PYTHON有关。

可以参考下

import gym
from gym import spaces
from gym.utils import seeding
import numpy as np
from os import path
import math


class BoatControl(gym.Env):
    def __init__(self, t=0., dt=.05):
        self.dt = dt # 时间步长
        self.t = t
        high = np.array([np.deg2rad(40), 0.4])   # 我这里在high前面偷偷加了self.想要改的话删了吧。
        self.action_space = spaces.Box(low=-1., high=1., shape=(1,), dtype=np.float32)  # changed many times
        self.l = 0.252
        self.r = 0.018
        self.omega = 100
        self.v = 1.042
        self.observation_space = spaces.Box(low=-high, high=high, dtype=np.float32)
        self.viewer = None
        self.theta = []
        self.seed()

    def seed(self, seed=None):
        self.np_random, seed = seeding.np_random(seed)
        return [seed]

    def runge_kutta_z(self, t, y, z): # 这个用来求thdot角速度的
        k1 = self.f(t, y, z)
        l1 = self.g(t, y, z)
        k2 = self.f(t, y, z) + 0.5 * self.dt * l1
l2 = self.g(t + 0.5 * self.dt, y + 0.5 * self.dt * k1, z + 0.5 * self.dt * l1)
        k3 = self.f(t, y, z) + 0.5 * self.dt * l2
        l3 = self.g(t + 0.5 * self.dt, y + 0.5 * self.dt * k2, z + 0.5 * self.dt * l2)
        k4 = self.f(t, y, z) + 0.5 * self.dt * l3
        l4 = self.g(t + 0.5 * self.dt, y + 0.5 * self.dt * k3, z + 0.5 * self.dt * l3)
        return z + self.dt * (l1 + 2 * l2 + 2 * l3 + l4) / 6.    # 这个返回值就是z,角速度

    def f(self, t, y, z): # 给runge_kutta_z服务的函数
        return z

    def g(self, t, y, z): # 给runge_kutta_z服务的函数
        a = 18.6
        b = 5.25
        D = 1.58 * 10**3
        h = 0.136
        Cl = 5.157
        c = D * h
        # F_magnus = 1.25 * 1025 * self.v * (2 * self.r * self.l) * self.r * action
        d = D * h * np.sin(t)
        # d = D * h * np.sin(t)+F_magnus
        return (d - c * y - b * z) / a

    def step(self, action):
        th, thdot = self.state # th := theta
# 控制
        # 新的状态
        F_magnus = 1.25 * 1025 * self.v * (2 * self.r * self.l) * self.r * action * 50
        # newthdot = self.runge_kutta_z(self.t, th, thdot)
        # F_magnus = 0
        newthdot = self.runge_kutta_z(self.t, th, thdot) + F_magnus * 0.5 * 0.5 * self.dt / 0.18   # used to be 184.559
        # add self. when you use a function defined before
        newth = th + newthdot * self.dt
        self.t += self.dt
        self.state = np.array([newth, newthdot])
        # th = newth
        # thdot = newthdot
        done = False
        reward = -10 * np.abs(newth)
        # 奖励值函数
        if np.abs(newth) > np.deg2rad(35):
            reward = -100.
            done = True # 场景结束
        elif newth > 0. and newthdot < 0.:
            reward += 0.5  # used to be 0.5
        elif newth < 0. and newthdot > 0.:
            reward += 0.5  # used to be 0.5
        elif newth > 0. and newthdot > 0.:
            reward += -0.5
        elif newth < 0. and newthdot < 0.:
            reward += -0.5
        self.theta.append(newth)
        if len(self.theta) == 500:
            import matplotlib.pyplot as plt
            plt.plot(np.rad2deg(np.abs(self.theta)))
            plt.xlabel('Step')
            plt.ylabel('Theta(°)')
            plt.savefig('boat_ddpg_theta1.png')
            plt.close()
 np.save('boat_ddpg_theta1.npy', self.theta)
            self.theta = []
            # another

            self.theta = []
        self.newth = newth
        reward = np.squeeze(reward)
        self.state = np.squeeze(self.state)
        return self.state, reward, done, {}  # 涂鸦说{}里面的info的shape可能不对,叫我删了,原来是{'theta': newth, 'thetadot': newthdot}

    def reset(self):

        high = np.array([np.deg2rad(5), 0.2])
        self.state = self.np_random.uniform(low=-high, high=high)
        self.state = np.array([self.state[0], self.state[1]])
        self.a = 10.
        return self.state

    def render(self, mode='human'):
        screen_width = 500
        screen_height = 500
        self.min_position = -1.0
        self.max_position = 1.0

        world_width = self.max_position - self.min_position
        scale = screen_width / world_width

        if self.viewer is None:
            from gym.envs.classic_control import rendering
            self.viewer = rendering.Viewer(screen_width, screen_height)
            self.viewer.set_bounds(-20, 20, -20, 20)

 # 海浪波形
            xs = np.linspace(100 * self.min_position, 100 * self.max_position, 20000)
            ys =  0.6 * np.sin(0.5 * xs)
            xys = list(zip(xs, ys))
            self.track = rendering.make_polyline(xys)
            self.track.set_linewidth(4)
            self.tracktrans = rendering.Transform()
            self.track.add_attr(self.tracktrans)
            self.viewer.add_geom(self.track)

            # 船
            boatwidth = 3
            boatheight = 2
            l, r, t, b = -boatwidth / 2, boatwidth / 2, boatheight, 0
            self.boat = rendering.FilledPolygon([(l, b), (l - 1, t), (r + 1, t), (r, b)])
            self.boattrans = rendering.Transform()
            self.boat.add_attr(self.boattrans)
            self.viewer.add_geom(self.boat)

        # self.viewer.add_onetime(self.boat)
        # self.tracktrans.set_translation(-self.t, 0)
        # self.boattrans.set_translation(0, 0.6 * (np.sin(0.5 * self.t) - 1))
        self.boattrans.set_rotation(self.newth)

        return self.viewer.render(return_rgb_array=True)

    def close(self):
        if self.viewer:
            self.viewer.close()
            self.viewer = None

你的问题提供的不够详细,具体的功能要求是什么呢。根据你的图片上的文字描述,是要实现一个函数create_ bonjeans(filename),那你的数据文件在哪里呢,由于你的信息有限,这里给你提供一个读取数据文件的示例:

import pandas as pd

def create_bonjeans(filename):
    if filename.endsWith('txt'):
        with open(filename,encoding='utf8') as file:
            data = file.readlines()
    elif filename.endsWith('xlsx'):
        data = pd.read_excel(filename)
    
    ##后面进行数据的处理

python编写的示例,可以参考

import numpy as np
import matplotlib.pyplot as plt

def simpson_rule(f, x, n):
    """
    使用Simpson公式计算积分的值
    :param f: 被积函数
    :param x: 积分区间[x0, xn]
    :param n: 积分区间等分数量,必须是偶数
    """
    h = (x[-1] - x[0]) / n
    S = f(x[0]) + f(x[-1])
    for i in range(1, n):
        if i % 2 == 0:  # 偶数部分
            S += 2 * f(x[i])
        else:           # 奇数部分
            S += 4 * f(x[i])
    return S * h / 3

def station_constant_curve(x, r):
    """
    计算站邦戎曲线的函数
    :param x: 靠离泊距离,单位:米
    :param r: 转弯半径,单位:米
    """
    h = r - np.sqrt(r**2 - x**2)  # 垂直偏移
    return h

def main():
    # 设定转弯半径和靠离泊距离的范围
    r_range = np.linspace(20, 60, 41)
    x_range = np.linspace(-10, 10, 201)

    # 计算面积列表
    area_list = []
    for r in r_range:
        s = 0
        for i in range(len(x_range)-1):
            x = x_range[i]
            h = station_constant_curve(x, r)
            w = x_range[i+1] - x_range[i]
            s += h * w
        area_list.append(abs(s))

    # 绘制曲线和数据
    plt.plot(r_range, area_list, 'r-', label='Area')
    plt.axvline(x=50, color='b', linestyle='--', label='Turning radius')
    plt.xlabel('Turning radius (m)')
    plt.ylabel('Area (sq.m)')
    plt.title('Station Constant Curve')
    plt.legend()
    plt.show()

if __name__ == '__main__':
    main()

有没有详细的公式, 或者 案例, 或者参考啥的

你这没头没尾来一句,怕是没法理解