Algorithm: Euler function

欧拉函数。

phi(n)表示比n小的与n互质的数的个数,比如

phi(1) = 1;

phi(2) = 1;

phi(3) = 2;

phi(4) = 2;

phi(5) = 4;

性质:

1. 如果p为质数,则phi(p) = p-1;

2. 如果p为质数并且a为正整数,则phi(p^a) = p^a - p^(a-1);

证明:p为质数,所以所有可以和p相乘小于p^a的数有p^a/p = p^(a-1)个,剩下的都与p^a互质。

3. phi(ab) = phi(a)*phi(b)

4. n = p1^a1*p2^a2*...*pk^ak

phi(n) = phi(p1^a1)*phi(p2^a2)*...*phi(pk^ak)

= (p1^a1-p1^(a1-1))*(p2^a2-p2^(a2-1))*...(pk^ak-pk^(ak-1))

=n*(1-1/p1)*(1-1/p2)*...*(1-1/pk)

实现代码:

 1 int phi (int n) {
 2     int result = n;
 3     for (int i=2; i*i<=n; ++i)
 4         if (n % i == 0) {
 5             while (n % i == 0)
 6                 n /= i;
 7             result -= result / i;
 8         }
 9     if (n > 1)
10         result -= result / n;
11     return result;
12 }

应用:

欧拉定理:a^(phi(m)) = 1 (mod m)

其中a与m互质

费马定理:a^(m-1) = 1 (mod m)

其中a与m互质

转载于:https://www.cnblogs.com/yingzhongwen/p/3150802.html

#!/usr/bin/env python # Copyright (c) 2016 The UUV Simulator Authors. # All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Import the ROS Python library from __future__ import print_function import rospy # Import the NumPy package for numerical computations import numpy as np # Import the dynamic positioning controller base class to inherit methods such as error computation update, # publishing from some important ROS topics (e.g. trajectory, pose and velocity reference) and access to # the vehicle model class, that is necessary to explicitly use the vehicle model from uuv_control_interfaces import DPControllerBase class TutorialDPController(DPControllerBase): # A new controller that is based on the DPControllerBase must at least provide the implementation of # the method update_controller. # The _reset_controller method can also be overridden and it will be called every time there is a service call # <vehicle namespace>/reset_controller. The default implementation sets the reference and error vectors to # zero. # The update_controller method must contain the implementation of the control algorithm and will be called # by every update of the vehicle's odometry message. It is therefore not necessary to explicitly call this update # function in this controller implementation. # For the controller to send the control torques to the vehicle's thruster manager, at the end of the # update_controller function the 6 x 1 control vector (type numpy.ndarray) sent using the function # publish_control_wrench from the super class, which will generate a Wrench ROS message and publish it to the # correspondent thruster manager node. # For this tutorial, a simple PID controller will be implemented. The controller's control torque output is # "tau" therefore computed as: # # tau = Kp * e + Kd * de/dt + Ki int_e # # where e is the pose error vector, in this case defined as e = (x, y, z, roll, pitch, yaw)^T def __init__(self): # Calling the constructor of the super-class DPControllerBase, which has the implementation of the error # computation update and to publish the resulting torque control vector. super(TutorialDPController, self).__init__(self) # The controller should read its parameters from the ROS parameter server for initial setup # One way to do this is to read the parameters from the node's private parameter namespace, which is done by # reading the parameter tag with an "~" at the beginning. If this method is used, the parameters should be # initialized accordingly in the controller startup launch file, such as # # <launch> # <node pkg="example_package" type="example_node.py" name="example_node" output="screen"> # <rosparam> # param_1: 0.0 # param_2: 0.0 # </rosparam> # </node> # </launch> # # For more information, see http://wiki.ros.org/roscpp_tutorials/Tutorials/AccessingPrivateNamesWithNodeHandle # Let's initialize the controller gain matrices Kp, Kd and Ki self._Kp = np.zeros(shape=(6, 6)) self._Kd = np.zeros(shape=(6, 6)) self._Ki = np.zeros(shape=(6, 6)) # Initialize the integrator component self._int = np.zeros(shape=(6,)) # Initialize variable that will store the vehicle pose error self._error_pose = np.zeros(shape=(6,)) # Now the gain matrices need to be set according to the variables stored in the parameter server # For simplicity, the gain matrices are defined as diagonal matrices, so only 6 coefficients are # needed if rospy.get_param('~Kp'): Kp_diag = rospy.get_param('~Kp') if len(Kp_diag) == 6: self._Kp = np.diag(Kp_diag) else: # If the vector provided has the wrong dimension, raise an exception raise rospy.ROSException('For the Kp diagonal matrix, 6 coefficients are needed') # Do the same for the other two matrices if rospy.get_param('~Kd'): diag = rospy.get_param('~Kd') if len(diag) == 6: self._Kd = np.diag(diag) print('Kd=\n', self._Kd) else: # If the vector provided has the wrong dimension, raise an exception raise rospy.ROSException('For the Kd diagonal matrix, 6 coefficients are needed') if rospy.get_param('~Ki'): diag = rospy.get_param('~Ki') if len(diag) == 6: self._Ki = np.diag(diag) print('Ki=\n', self._Ki) else: # If the vector provided has the wrong dimension, raise an exception raise rospy.ROSException('For the Ki diagonal matrix, 6 coefficients are needed') self._is_init = True def _reset_controller(self): # The _reset_controller method from the super class DPControllerBase already sets the error # and reference vectors to zero, but this class has additional attributes that should also # be taken care of. # This implementation will, therefore, first call the super class reset method super(TutorialDPController, self)._reset_controller() # And then proceed to set the internal variables back to zero self._error_pose = np.zeros(shape=(6,)) self._int = np.zeros(shape=(6,)) def update_controller(self): if not self._is_init: return False # The controller algorithm must be implemented here, the super class will connect this method # to the odometry update as a callback function # First test whether or not the odometry topic subscriber has already been initialized if not self.odom_is_init: return # Update the integrator, read the super class vector for the pose error (orientation is represented # with Euler angles in RPY convention) and integrate to the stored pose error from the last # iteration self._int = self._int + 0.5 * (self.error_pose_euler + self._error_pose) * self._dt # Store the current pose error for the next iteration self._error_pose = self.error_pose_euler # Compute the control forces and torques using the current error vectors available tau = np.dot(self._Kp, self.error_pose_euler) + np.dot(self._Kd, self._errors['vel']) + \ np.dot(self._Ki, self._int) # Use the super class method to convert the control force vector into a ROS message # and publish it as an input to the vehicle's thruster manager. The thruster manager module # will then distribute the efforts amongst the thrusters using the thruster allocation matrix self.publish_control_wrench(tau) if __name__ == '__main__': # Since this is an ROS node, this Python script has to be treated as an executable # Remember to convert this Python file into an executable. This can be done with # # cd <path_to_ros_package>/scripts # chmod 777 tutorial_dp_controller.py # # This file has also to be included in this package's CMakeLists.txt # After the line catkin_package() in the CMakeLists.txt, include the following # # catkin_install_python(PROGRAMS scripts/tutorial_dp_controller.py DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) print('Tutorial - DP Controller') rospy.init_node('tutorial_dp_controller') try: node = TutorialDPController() rospy.spin() except rospy.ROSInterruptException: print('caught exception') print('exiting')学习这个代码,编写一个lqr控制器
05-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值