예제 #1
0
파일: fwi_tests.c 프로젝트: Hopobcn/FWI
void assert_equal_float_array( float* ref, float* opt, const int nelems, const char* file, const int line )
{
    // OBS: the maximum ULP difference observed is 16384 and it seems to come from difference
    //      optimizations applied by NVCC compiler in "stress_update" function in scell_BR
    //      causes an accumulation of errors.
    int maxULP = 16384;
    int max_diff = 0;

    for (int elem = 0; elem < nelems; elem++)
    {
        float ref_e = ref[elem];
        float opt_e = opt[elem];
        const int diff = diff_in_ULPs(ref_e, opt_e);

        if (max_diff < diff) max_diff = diff;

        if ( !assert_float_equal_ULPs(ref_e, opt_e, maxULP) )
        {
            fprintf(stderr, "ERROR:%s:%d: in element %d : ref %e !=\t %e \topt by %d ULP\n",
                   file, line, elem, ref_e, opt_e, diff );

            Float_t uref, uopt;
            uref.f = ref_e;
            uopt.f = opt_e;
            fprintf(stderr, "REF: sign %d mantissa %023d exponent %08d\n",
                is_negative(uref), raw_mantissa(uref), raw_exponent(uref));
            fprintf(stderr, "OPT: sign %d mantissa %023d exponent %08d\n",
                is_negative(uopt), raw_mantissa(uopt), raw_exponent(uopt));


            exit(1); //UNITY_FAIL_AND_BAIL;
        }
    }
    fprintf(stdout, "\nMAX DIFF: %d ULPs", max_diff);
}
예제 #2
0
// Proportional controller with piecewise sqrt sections to constrain second derivative
float AC_AttitudeControl::sqrt_controller(float error, float p, float second_ord_lim, float dt)
{
    float correction_rate;
    if (is_negative(second_ord_lim) || is_zero(second_ord_lim)) {
        // second order limit is zero or negative.
        correction_rate = error*p;
    } else if (is_zero(p)) {
        // P term is zero but we have a second order limit.
        if (is_positive(error)) {
            correction_rate = safe_sqrt(2.0f*second_ord_lim*(error));
        } else if (is_negative(error)) {
            correction_rate = -safe_sqrt(2.0f*second_ord_lim*(-error));
        } else {
            correction_rate = 0.0f;
        }
    } else {
        // Both the P and second order limit have been defined.
        float linear_dist = second_ord_lim/sq(p);
        if (error > linear_dist) {
            correction_rate = safe_sqrt(2.0f*second_ord_lim*(error-(linear_dist/2.0f)));
        } else if (error < -linear_dist) {
            correction_rate = -safe_sqrt(2.0f*second_ord_lim*(-error-(linear_dist/2.0f)));
        } else {
            correction_rate = error*p;
        }
    }
    if (!is_zero(dt)) {
        // this ensures we do not get small oscillations by over shooting the error correction in the last time step.
        return constrain_float(correction_rate, -fabsf(error)/dt, fabsf(error)/dt);
    } else {
        return correction_rate;
    }
}
예제 #3
0
파일: fwi_tests.c 프로젝트: Hopobcn/FWI
bool assert_float_equal_ULPs(float A, float B, int maxUlpsDiff)
{
    Float_t uA;
    Float_t uB;

    uA.f = A;
    uB.f = B;

    // NaN or Infinite means they do not match.
    if (isnan(A) || isnan(B) || (A == INFINITY) || (B == INFINITY))
        return false;

    // Different signs means they do not match.
    if (is_negative(uA) != is_negative(uB))
    {
        // Check for equality to make sure +0==-0
        if (A == B)
            return true;
        return false;
    }

    // Find the difference in ULPs.
    int ulpsDiff = abs(uA.i - uB.i);
    if (ulpsDiff <= maxUlpsDiff)
        return true;

    return false;
}
예제 #4
0
// output to regular steering and throttle channels
void AP_MotorsUGV::output_regular(bool armed, float ground_speed, float steering, float throttle)
{
    // output to throttle channels
    if (armed) {
        if (_scale_steering) {
            // vectored thrust handling
            if (have_vectored_thrust()) {
                if (fabsf(throttle) > _vector_throttle_base) {
                    // scale steering down linearly as throttle increases above _vector_throttle_base
                    steering *= constrain_float(_vector_throttle_base / fabsf(throttle), 0.0f, 1.0f);
                }
            } else {
                // scale steering down as speed increase above MOT_SPD_SCA_BASE (1 m/s default)
                if (is_positive(_speed_scale_base) && (fabsf(ground_speed) > _speed_scale_base)) {
                    steering *= (_speed_scale_base / fabsf(ground_speed));
                } else {
                    // regular steering rover at low speed so set limits to stop I-term build-up in controllers
                    if (!have_skid_steering()) {
                        limit.steer_left = true;
                        limit.steer_right = true;
                    }
                }
                // reverse steering direction when backing up
                if (is_negative(ground_speed)) {
                    steering *= -1.0f;
                }
            }
        } else {
            // reverse steering direction when backing up
            if (is_negative(throttle)) {
                steering *= -1.0f;
            }
        }
        output_throttle(SRV_Channel::k_throttle, throttle);
    } else {
        // handle disarmed case
        if (_disarm_disable_pwm) {
            SRV_Channels::set_output_limit(SRV_Channel::k_throttle, SRV_Channel::SRV_CHANNEL_LIMIT_ZERO_PWM);
        } else {
            SRV_Channels::set_output_limit(SRV_Channel::k_throttle, SRV_Channel::SRV_CHANNEL_LIMIT_TRIM);
        }
    }

    // clear and set limits based on input
    // we do this here because vectored thrust or speed scaling may have reduced steering request
    set_limits_from_input(armed, steering, throttle);

    // constrain steering
    steering = constrain_float(steering, -4500.0f, 4500.0f);

    // always allow steering to move
    SRV_Channels::set_output_scaled(SRV_Channel::k_steering, steering);
}
예제 #5
0
// decode pilot steering and throttle inputs and return in steer_out and throttle_out arguments
// steering_out is in the range -4500 ~ +4500 with positive numbers meaning rotate clockwise
// throttle_out is in the range -100 ~ +100
void Mode::get_pilot_desired_steering_and_throttle(float &steering_out, float &throttle_out)
{
    // do basic conversion
    get_pilot_input(steering_out, throttle_out);

    // check for special case of input and output throttle being in opposite directions
    float throttle_out_limited = g2.motors.get_slew_limited_throttle(throttle_out, rover.G_Dt);
    if ((is_negative(throttle_out) != is_negative(throttle_out_limited)) &&
        ((g.pilot_steer_type == PILOT_STEER_TYPE_DEFAULT) ||
         (g.pilot_steer_type == PILOT_STEER_TYPE_DIR_REVERSED_WHEN_REVERSING))) {
        steering_out *= -1;
    }
    throttle_out = throttle_out_limited;
}
예제 #6
0
// decode pilot steering and return steering_out and speed_out (in m/s)
void Mode::get_pilot_desired_steering_and_speed(float &steering_out, float &speed_out)
{
    float desired_throttle;
    get_pilot_input(steering_out, desired_throttle);
    speed_out = desired_throttle * 0.01f * calc_speed_max(g.speed_cruise, g.throttle_cruise * 0.01f);
    // check for special case of input and output throttle being in opposite directions
    float speed_out_limited = g2.attitude_control.get_desired_speed_accel_limited(speed_out, rover.G_Dt);
    if ((is_negative(speed_out) != is_negative(speed_out_limited)) &&
        ((g.pilot_steer_type == PILOT_STEER_TYPE_DEFAULT) ||
         (g.pilot_steer_type == PILOT_STEER_TYPE_DIR_REVERSED_WHEN_REVERSING))) {
        steering_out *= -1;
    }
    speed_out = speed_out_limited;
}
예제 #7
0
void Mode::get_pilot_desired_steering_and_throttle(float &steering_out, float &throttle_out)
{
    // no RC input means no throttle and centered steering
    if (rover.failsafe.bits & FAILSAFE_EVENT_THROTTLE) {
        steering_out = 0;
        throttle_out = 0;
        return;
    }

    // apply RC skid steer mixing
    switch ((enum pilot_steer_type_t)rover.g.pilot_steer_type.get())
    {
        case PILOT_STEER_TYPE_DEFAULT:
        default: {
            // by default regular and skid-steering vehicles reverse their rotation direction when backing up
            // (this is the same as PILOT_STEER_TYPE_DIR_REVERSED_WHEN_REVERSING below)
            throttle_out = rover.channel_throttle->get_control_in();
            steering_out = rover.channel_steer->get_control_in();
            break;
        }

        case PILOT_STEER_TYPE_TWO_PADDLES: {
            // convert the two radio_in values from skid steering values
            // left paddle from steering input channel, right paddle from throttle input channel
            // steering = left-paddle - right-paddle
            // throttle = average(left-paddle, right-paddle)
            const float left_paddle = rover.channel_steer->norm_input();
            const float right_paddle = rover.channel_throttle->norm_input();

            throttle_out = 0.5f * (left_paddle + right_paddle) * 100.0f;

            const float steering_dir = is_negative(throttle_out) ? -1 : 1;
            steering_out = steering_dir * (left_paddle - right_paddle) * 4500.0f;
            break;
        }

        case PILOT_STEER_TYPE_DIR_REVERSED_WHEN_REVERSING:
            throttle_out = rover.channel_throttle->get_control_in();
            steering_out = rover.channel_steer->get_control_in();
            break;

        case PILOT_STEER_TYPE_DIR_UNCHANGED_WHEN_REVERSING: {
            throttle_out = rover.channel_throttle->get_control_in();
            const float steering_dir = is_negative(throttle_out) ? -1 : 1;
            steering_out = steering_dir * rover.channel_steer->get_control_in();
            break;
        }
    }
}
예제 #8
0
파일: removed.cpp 프로젝트: himura/p-stade
int main()
{
    namespace oven = pstade::oven;
    namespace bll = boost::lambda;

    int a[] = { 9,1,3,7,4,31,1,76,9,2,3 };
    int b[] = { -1,0,9,-3,-6,1,3,7,4,31,-2,1,-2,76,-1,9,-6,2,3 };

    BOOST_TEST(oven::equals(a, b | oven::removed(is_negative())));
    BOOST_TEST(oven::equals(a, b | oven::removed(oven::regular(is_negative()))));
    BOOST_TEST(oven::equals(a, b | oven::removed(oven::regular(0 >= bll::_1))));
//  BOOST_TEST(oven::equals(a, b | oven::removed(oven::regular([](int x) { return 0 >= x; }))));

    return boost::report_errors();
}
예제 #9
0
파일: ft_itoa_base.c 프로젝트: xSkyZie/42
char			*ft_itoa_base(int value, int base)
{
	int		sign;
	int		count;
	char	*str;

	count = 0;
	sign = is_negative(&value);
	if (base < 2 || base > 16)
		return ("");
	if (value == 0 || value == -0)
		return ("0");
	if (value == -2147483648)
		return ("-2147483648");
	if (value == 2147483647)
		return ("2147483647");
	if ((str = ft_strnew(ft_getlen(value, base) + sign))
			== NULL)
		return (NULL);
	count = ft_getstr(value, base, str);
	if (sign < 0 && base == 10)
		str[count++] = '-';
	str[count] = '\0';
	ft_strrev(str);
	return (str);
}
예제 #10
0
	inline void fast_sin_cos(float x, float& s, float& c)
	{
		while (is_positive(x) && x >= anglef::_2pi) x -= anglef::_2pi;
		while (is_negative(x) && x < 0) x += anglef::_2pi;
		
		if (x >= anglef::pi)
		{
			if (x >= anglef::_3pi2)
			{
				//64 + anglef::_2pi
				s = 1.f - fast_sin_pi2(64.f + anglef::_2pi - x);
				c = fast_sin_pi2(64.f - anglef::_3pi2 + x) - 1.f;
			}
			else
			{
				//64 + x - anglef::pi
				s = 1.f - fast_sin_pi2(64.f - anglef::pi + x);
				c = 1.f - fast_sin_pi2(64.f + anglef::_3pi2 - x);
			}
		}
		else
		{
			if (x >= anglef::pi2)
			{
				//64 + anglef::pi - x
				s = fast_sin_pi2(64.f + anglef::pi - x) - 1.f;
				c = 1.f - fast_sin_pi2(64.f - anglef::pi2 + x);
			}
			else
			{
				s = fast_sin_pi2(64.f + x) - 1.f;
				c = fast_sin_pi2(64.f + anglef::pi2 - x) - 1.f;
			}
		}
	}
예제 #11
0
// scale a throttle using the _throttle_min and _thrust_curve_expo parameters.  throttle should be in the range -100 to +100
float AP_MotorsUGV::get_scaled_throttle(float throttle) const
{
    // exit immediately if throttle is zero
    if (is_zero(throttle)) {
        return throttle;
    }

    // scale using throttle_min
    if (_throttle_min > 0) {
        if (is_negative(throttle)) {
            throttle = -_throttle_min + (throttle * ((100.0f - _throttle_min) / 100.0f));
        } else {
            throttle = _throttle_min + (throttle * ((100.0f - _throttle_min) / 100.0f));
        }
    }

    // skip further scaling if thrust curve disabled or invalid
    if (is_zero(_thrust_curve_expo) || (_thrust_curve_expo > 1.0f) || (_thrust_curve_expo < -1.0f)) {
        return throttle;
    }

    // calculate scaler
    const float sign = (throttle < 0.0f) ? -1.0f : 1.0f;
    const float throttle_pct = constrain_float(throttle, -100.0f, 100.0f) / 100.0f;
    return 100.0f * sign * ((_thrust_curve_expo - 1.0f) + safe_sqrt((1.0f - _thrust_curve_expo) * (1.0f - _thrust_curve_expo) + 4.0f * _thrust_curve_expo * fabsf(throttle_pct))) / (2.0f * _thrust_curve_expo);
}
예제 #12
0
// return a steering servo output from -1.0 to +1.0 given a desired lateral acceleration rate in m/s/s.
// positive lateral acceleration is to the right.
float AR_AttitudeControl::get_steering_out_lat_accel(float desired_accel, bool motor_limit_left, bool motor_limit_right, float dt)
{
    // record desired accel for reporting purposes
    _steer_lat_accel_last_ms = AP_HAL::millis();
    _desired_lat_accel = desired_accel;

    // get speed forward
    float speed;
    if (!get_forward_speed(speed)) {
        // we expect caller will not try to control heading using rate control without a valid speed estimate
        // on failure to get speed we do not attempt to steer
        return 0.0f;
    }

    // enforce minimum speed to stop oscillations when first starting to move
    if (fabsf(speed) < AR_ATTCONTROL_STEER_SPEED_MIN) {
        if (is_negative(speed)) {
            speed = -AR_ATTCONTROL_STEER_SPEED_MIN;
        } else {
            speed = AR_ATTCONTROL_STEER_SPEED_MIN;
        }
    }

    // Calculate the desired steering rate given desired_accel and speed
    const float desired_rate = desired_accel / speed;

    return get_steering_out_rate(desired_rate, motor_limit_left, motor_limit_right, dt);
}
예제 #13
0
int		my_put_nbr(int nb)
{
  unsigned char	len;
  int		copy;
  int		diz;

  if (nb == -2147483648)
    {
      cheat();
      return (0);
    }
  nb = is_negative(nb);
  copy = nb;
  len = 1;
  while (copy > 9)
    {
      copy = copy / 10;
      len = len + 1;
    }
  while (len != 0)
    {
      diz = nb / my_pow(len-1);
      my_putchar(diz + 48);
      nb = nb - diz * my_pow(len-1);
      len = len - 1;
    }
}
예제 #14
0
// get throttle output in the range -100 to +100 given a desired rate expressed as a percentage of the rate_max (-100 to +100)
// instance can be 0 or 1
float AP_WheelRateControl::get_rate_controlled_throttle(uint8_t instance, float desired_rate_pct, float dt)
{
    if (!enabled(instance)) {
        return 0;
    }

    // determine which PID instance to use
    AC_PID& rate_pid = (instance == 0) ? _rate_pid0 : _rate_pid1;

    // set PID's dt
    rate_pid.set_dt(dt);

    // check for timeout
    uint32_t now = AP_HAL::millis();
    if (now - _last_update_ms > AP_WHEEL_RATE_CONTROL_TIMEOUT_MS) {
        rate_pid.reset_filter();
        rate_pid.reset_I();
        _limit[instance].lower = false;
        _limit[instance].upper = false;
    }
    _last_update_ms = now;

    // convert desired rate as a percentage to radians/sec
    float desired_rate = desired_rate_pct / 100.0f * get_rate_max_rads();

    // get actual rate from wheeel encoder
    float actual_rate = _wheel_encoder.get_rate(instance);

    // calculate rate error and pass to pid controller
    float rate_error = desired_rate - actual_rate;
    rate_pid.set_input_filter_all(rate_error);

    // store desired and actual for logging purposes
    rate_pid.set_desired_rate(desired_rate);
    rate_pid.set_actual_rate(actual_rate);

    // get ff
    float ff = rate_pid.get_ff(desired_rate);

    // get p
    float p = rate_pid.get_p();

    // get i unless we hit limit on last iteration
    float i = rate_pid.get_integrator();
    if (((is_negative(rate_error) && !_limit[instance].lower) || (is_positive(rate_error) && !_limit[instance].upper))) {
        i = rate_pid.get_i();
    }

    // get d
    float d = rate_pid.get_d();

    // constrain and set limit flags
    float output = ff + p + i + d;

    // set limits for next iteration
    _limit[instance].upper = output >= 100.0f;
    _limit[instance].lower = output <= -100.0f;

    return output;
}
예제 #15
0
//main function
int main(void){

//variables for main function
char *yes = "y";
char *no = "n";
int progcontinue = 0;
int continuetest = 0;	

printf("Brian Sator, masc0916\n\n");//output program setup information

	for(;;){
		//at the beginning of each cycle we check to see if we need to run the main routine again
		if(progcontinue != 0){
			break;//exit loop
		}
		printf("Please enter a fraction to reduce: ");//prompt user
		scanf("%25s",buffer1);//read from input
		flushinstream();//flush the input stream
		if(in_validate(buffer1) == 1){//the input string is a valid fraction proceed with reduction
			int numtest = atoi(num);
			int denomtest = atoi(denom);
			negative = is_negative(numtest, denomtest);
			commondivisor = abs(findGCD(numtest,denomtest));
			numtest = abs(numtest/commondivisor);
			denomtest = abs(denomtest/commondivisor);
			if(negative == 0){//check if negative
				printf("The reduced fraction is: %d/%d\n\n",numtest, denomtest);
			}else{
				printf("The reduced fraction is: -%d/%d\n\n",numtest, denomtest);
			}
			numtest = 0;
			numtest = 0;
			
		}
		else{//the input string is not valid, start routine over to prompt for new input
			continue;
		}
		
		while(continuetest == 0){//here we check to see if user wants to reduce another fraction
			printf("Do you want to reduce another fraction(y/n)? ");
			scanf("%25s",buffer1);
			flushinstream();
			if(buffer1[0] == *no){//end program
				progcontinue = 1;
				continuetest = 1;
			}else if(buffer1[0] == *yes){//new fraction
				continuetest = 1;
			}
			else{//invalid input
				printf("Sorry, invalid input\n\n");
			}
		}
		continuetest = 0;
		memset(num,0,30);
		memset(denom,0,30);
	}
	
printf("Program Terminated\n");
return 0;//exit program
}
예제 #16
0
void mp_int<A,T>::sub_digit(digit_type b)
{
  if (is_negative())
  {
    const digit_type carry =
      ops_type::add_single_digit(digits_, digits_, size_, b);
    if (carry)
      push(carry);
    return;
  }

  if (size_ == 1)
  {
    if (digits_[0] < b) // example: 2 - 6 = -4
    {
      digits_[0] = b - digits_[0];
      set_sign(-1);
    }
    else // example: 8 - 7 = 1 or 5 - 5 = 0
      digits_[0] -= b;
  }
  else
  {
    ops_type::subtract_single_digit(digits_, digits_, size_, b);
    if (!digits_[size_-1])
      --size_;
  }
}
예제 #17
0
	inline float fast_sin(float x)
	{
		while (is_positive(x) && x >= anglef::_2pi) x -= anglef::_2pi;
		while (is_negative(x) && x < 0) x += anglef::_2pi;

		if (x >= anglef::pi)
		{
			if (x >= anglef::_3pi2)
			{
				//64 + anglef::_2pi
				return 1.f - fast_sin_pi2(64.f + anglef::_2pi - x);
			}
			else
			{
				//64 + x - anglef::pi
				return 1.f - fast_sin_pi2(64.f - anglef::pi + x);
			}
		}
		else
		{
			if (x >= anglef::pi2)
			{
				//64 + anglef::pi - x
				return fast_sin_pi2(64.f + anglef::pi - x) - 1.f;
			}
			else
			{
				return fast_sin_pi2(64 + x) - 1.f;
			}
		}
	}
예제 #18
0
// output to regular steering and throttle channels
void AP_MotorsUGV::output_regular(bool armed, float ground_speed, float steering, float throttle)
{
    // output to throttle channels
    if (armed) {
        if (_scale_steering) {
            // vectored thrust handling
            if (have_vectored_thrust()) {
                if (fabsf(throttle) > _vector_throttle_base) {
                    // scale steering down linearly as throttle increases above _vector_throttle_base
                    steering *= constrain_float(_vector_throttle_base / fabsf(throttle), 0.0f, 1.0f);
                }
            } else {
                // scale steering down as speed increase above 1m/s
                if (fabsf(ground_speed) > 1.0f) {
                    steering *= (1.0f / fabsf(ground_speed));
                } else {
                    // regular steering rover at low speed so set limits to stop I-term build-up in controllers
                    if (!have_skid_steering()) {
                        limit.steer_left = true;
                        limit.steer_right = true;
                    }
                }
                // reverse steering output if backing up
                if (is_negative(ground_speed)) {
                    steering *= -1.0f;
                }
            }
        } else {
            // reverse steering direction when backing up
            if (is_negative(throttle)) {
                steering *= -1.0f;
            }
        }
        output_throttle(SRV_Channel::k_throttle, throttle);
    } else {
        // handle disarmed case
        if (_disarm_disable_pwm) {
            SRV_Channels::set_output_limit(SRV_Channel::k_throttle, SRV_Channel::SRV_CHANNEL_LIMIT_ZERO_PWM);
        } else {
            SRV_Channels::set_output_limit(SRV_Channel::k_throttle, SRV_Channel::SRV_CHANNEL_LIMIT_TRIM);
        }
    }

    // always allow steering to move
    SRV_Channels::set_output_scaled(SRV_Channel::k_steering, steering);
}
예제 #19
0
// set desired speed in m/s
bool Mode::set_desired_speed(float speed)
{
    if (!is_negative(speed)) {
        _desired_speed = speed;
        return true;
    }
    return false;
}
예제 #20
0
int main(void) {
  int iai[] = {-1,0,1,2,3,4,5,6,7,8,9,10};
  int i = 0;
  for( i = 0; i < sizeof(iai)/sizeof(int); i++) {
    printf("\t%3d has a sign of %c\n", iai[i], is_negative(iai[i]) ? '-':'+');
  }
  return EXIT_SUCCESS;
}
예제 #21
0
Out floor(X x)
{
    static_assert(!std::is_integral<X>::value, "type must be non-integral");
    static_assert(std::is_integral<Out>::value, "type must be integral");
    if (is_negative(x))
        x -= 1;
    return static_cast<Out>(x);
}
예제 #22
0
// return a steering servo output from -1 to +1 given a
// desired yaw rate in radians/sec. Positive yaw is to the right.
float AR_AttitudeControl::get_steering_out_rate(float desired_rate, bool motor_limit_left, bool motor_limit_right, float dt)
{
    // sanity check dt
    dt = constrain_float(dt, 0.0f, 1.0f);

    // if not called recently, reset input filter and desired turn rate to actual turn rate (used for accel limiting)
    const uint32_t now = AP_HAL::millis();
    if ((_steer_turn_last_ms == 0) || ((now - _steer_turn_last_ms) > AR_ATTCONTROL_TIMEOUT_MS)) {
        _steer_rate_pid.reset_filter();
        _steer_rate_pid.reset_I();
        _desired_turn_rate = _ahrs.get_yaw_rate_earth();
    }
    _steer_turn_last_ms = now;

    // acceleration limit desired turn rate
    if (is_positive(_steer_accel_max)) {
        const float change_max = radians(_steer_accel_max) * dt;
        desired_rate = constrain_float(desired_rate, _desired_turn_rate - change_max, _desired_turn_rate + change_max);
    }
    _desired_turn_rate = desired_rate;

    // rate limit desired turn rate
    if (is_positive(_steer_rate_max)) {
        const float steer_rate_max_rad = radians(_steer_rate_max);
        _desired_turn_rate = constrain_float(_desired_turn_rate, -steer_rate_max_rad, steer_rate_max_rad);
    }

    // Calculate the steering rate error (rad/sec)
    // We do this in earth frame to allow for rover leaning over in hard corners
    const float rate_error = (_desired_turn_rate - _ahrs.get_yaw_rate_earth());

    // set PID's dt
    _steer_rate_pid.set_dt(dt);

    // record desired rate for logging purposes only
    _steer_rate_pid.set_desired_rate(_desired_turn_rate);

    // pass error to PID controller
    _steer_rate_pid.set_input_filter_all(rate_error);

    // get feed-forward
    const float ff = _steer_rate_pid.get_ff(_desired_turn_rate);

    // get p
    const float p = _steer_rate_pid.get_p();

    // get i unless non-skid-steering rover at low speed or steering output has hit a limit
    float i = _steer_rate_pid.get_integrator();
    if ((is_negative(rate_error) && !motor_limit_left) || (is_positive(rate_error) && !motor_limit_right)) {
        i = _steer_rate_pid.get_i();
    }

    // get d
    const float d = _steer_rate_pid.get_d();

    // constrain and return final output
    return constrain_float(ff + p + i + d, -1.0f, 1.0f);
}
예제 #23
0
// output throttle value to main throttle channel, left throttle or right throttle.  throttle should be scaled from -100 to 100
void AP_MotorsUGV::output_throttle(SRV_Channel::Aux_servo_function_t function, float throttle)
{
    // sanity check servo function
    if (function != SRV_Channel::k_throttle && function != SRV_Channel::k_throttleLeft && function != SRV_Channel::k_throttleRight && function != SRV_Channel::k_motor1 && function != SRV_Channel::k_motor2 && function != SRV_Channel::k_motor3) {
        return;
    }

    // constrain and scale output
    throttle = get_scaled_throttle(throttle);

    // set relay if necessary
    if (_pwm_type == PWM_TYPE_BRUSHED_WITH_RELAY) {
        // find the output channel, if not found return
        const SRV_Channel *out_chan = SRV_Channels::get_channel_for(function);
        if (out_chan == nullptr) {
            return;
        }
        const int8_t reverse_multiplier = out_chan->get_reversed() ? -1 : 1;
        bool relay_high = is_negative(reverse_multiplier * throttle);

        switch (function) {
            case SRV_Channel::k_throttle:
            case SRV_Channel::k_throttleLeft:
            case SRV_Channel::k_motor1:
                _relayEvents.do_set_relay(0, relay_high);
                break;
            case SRV_Channel::k_throttleRight:
            case SRV_Channel::k_motor2:
                _relayEvents.do_set_relay(1, relay_high);
                break;
            case SRV_Channel::k_motor3:
                _relayEvents.do_set_relay(2, relay_high);
                break;
            default:
                // do nothing
                break;
        }
        // invert the output to always have positive value calculated by calc_pwm
        throttle = reverse_multiplier * fabsf(throttle);
    }

    // output to servo channel
    switch (function) {
        case SRV_Channel::k_throttle:
        case SRV_Channel::k_motor1:
        case SRV_Channel::k_motor2:
        case SRV_Channel::k_motor3:
            SRV_Channels::set_output_scaled(function,  throttle);
            break;
        case SRV_Channel::k_throttleLeft:
        case SRV_Channel::k_throttleRight:
            SRV_Channels::set_output_scaled(function,  throttle * 10.0f);
            break;
        default:
            // do nothing
            break;
    }
}
예제 #24
0
void ModeSteering::update()
{
    float desired_steering, desired_throttle;
    get_pilot_desired_steering_and_throttle(desired_steering, desired_throttle);

    // convert pilot throttle input to desired speed (up to twice the cruise speed)
    const float target_speed = desired_throttle * 0.01f * calc_speed_max(g.speed_cruise, g.throttle_cruise * 0.01f);

    // get speed forward
    float speed;
    if (!attitude_control.get_forward_speed(speed)) {
        // no valid speed so stop
        g2.motors.set_throttle(0.0f);
        g2.motors.set_steering(0.0f);
        _desired_lat_accel = 0.0f;
        return;
    }

    // determine if pilot is requesting pivot turn
    bool is_pivot_turning = g2.motors.have_skid_steering() && is_zero(target_speed) && (!is_zero(desired_steering));

    // In steering mode we control lateral acceleration directly.
    // For pivot steering vehicles we use the TURN_MAX_G parameter
    // For regular steering vehicles we use the maximum lateral acceleration at full steering lock for this speed: V^2/R where R is the radius of turn.
    float max_g_force;
    if (is_pivot_turning) {
        max_g_force = g.turn_max_g * GRAVITY_MSS;
    } else {
        max_g_force = speed * speed / MAX(g2.turn_radius, 0.1f);
    }

    // constrain to user set TURN_MAX_G
    max_g_force = constrain_float(max_g_force, 0.1f, g.turn_max_g * GRAVITY_MSS);

    // convert pilot steering input to desired lateral acceleration
    _desired_lat_accel = max_g_force * (desired_steering / 4500.0f);

    // reverse target lateral acceleration if backing up
    bool reversed = false;
    if (is_negative(target_speed)) {
        reversed = true;
        _desired_lat_accel = -_desired_lat_accel;
    }

    // mark us as in_reverse when using a negative throttle
    rover.set_reverse(reversed);

    // run speed to throttle output controller
    if (is_zero(target_speed) && !is_pivot_turning) {
        stop_vehicle();
    } else {
        // run lateral acceleration to steering controller
        calc_steering_from_lateral_acceleration(false);
        calc_throttle(target_speed, false);
    }
}
예제 #25
0
파일: radio.cpp 프로젝트: LanderU/ardupilot
void Rover::read_radio()
{
    if (!hal.rcin->new_input()) {
        // check if we lost RC link
        control_failsafe(channel_throttle->get_radio_in());
        return;
    }

    failsafe.last_valid_rc_ms = AP_HAL::millis();
    // read the RC value
    RC_Channels::set_pwm_all();
    // check that RC value are valid
    control_failsafe(channel_throttle->get_radio_in());

    // apply RC skid steer mixing
    if (g.skid_steer_in) {
        // convert the two radio_in values from skid steering values
        /*
          mixing rule:
          steering = motor1 - motor2
          throttle = 0.5*(motor1 + motor2)
          motor1 = throttle + 0.5*steering
          motor2 = throttle - 0.5*steering
        */          

        const float left_input = channel_steer->norm_input();
        const float right_input = channel_throttle->norm_input();
        const float throttle_scaled = 0.5f * (left_input + right_input);
        float steering_scaled = constrain_float(left_input - right_input, -1.0f, 1.0f);

        // flip the steering direction if requesting the vehicle reverse (to be consistent with separate steering-throttle frames)
        if (is_negative(throttle_scaled)) {
            steering_scaled = -steering_scaled;
        }

        int16_t steer = channel_steer->get_radio_trim();
        int16_t thr   = channel_throttle->get_radio_trim();
        if (steering_scaled > 0.0f) {
            steer += steering_scaled * (channel_steer->get_radio_max() - channel_steer->get_radio_trim());
        } else {
            steer += steering_scaled * (channel_steer->get_radio_trim() - channel_steer->get_radio_min());
        }
        if (throttle_scaled > 0.0f) {
            thr += throttle_scaled * (channel_throttle->get_radio_max() - channel_throttle->get_radio_trim());
        } else {
            thr += throttle_scaled * (channel_throttle->get_radio_trim() - channel_throttle->get_radio_min());
        }
        channel_steer->set_pwm(steer);
        channel_throttle->set_pwm(thr);
    }

    // check if we try to do RC arm/disarm
    rudder_arm_disarm_check();
}
예제 #26
0
X int_power(X base, X exp)
{
    static_assert(std::is_integral<X>::value,
        "type must be unsigned integral");
    assert(!is_negative(exp));
    if (exp == 0)
        return 1;
    if (exp == 1)
        return base;
    return base * int_power(base, exp - 1);
}
예제 #27
0
T fast_power_0(T a, I n, Op op) 
{ 
  assert(!is_negative(n)); 
  T result = identity_element(op); 
  while (!is_zero(n)) {  
    if (is_odd(n)) result = op(result, a); 
    a = op(a, a); 
    halve_non_negative(n); 
  } 
  return result; 
} 
예제 #28
0
파일: io.cpp 프로젝트: sig-vip/skeleton
std::basic_ostream<Ch, ChT>& output_pow_default
(std::basic_ostream<Ch, ChT>& out, const T& x)
{
    // ѕ–≈ƒ”ѕ–≈∆ƒ≈Ќ»≈. “олько дл¤ тех T, дл¤ которых определЄн is_negative.

    if(is_negative(x))
        out << "(" << x << ")";
    else
        out << x;
    return out;
}
예제 #29
0
파일: big_base.cpp 프로젝트: AlekSi/Jabbin
/*************************************************
* Convert this number to a u32bit, if possible   *
*************************************************/
u32bit BigInt::to_u32bit() const
   {
   if(is_negative())
      throw Encoding_Error("BigInt::to_u32bit: Number is negative");
   if(bits() >= 32)
      throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert");

   u32bit out = 0;
   for(u32bit j = 0; j != 4; ++j)
      out = (out << 8) | byte_at(3-j);
   return out;
   }
예제 #30
0
Out round(X x)
{
    static_assert(!std::is_integral<X>::value, "type must be non-integral");
    static_assert(std::is_integral<Out>::value, "type must be integral");
    if (static_cast<double>(x) < static_cast<double>(std::numeric_limits<Out>::lowest()))
        return std::numeric_limits<Out>::lowest();
    if (static_cast<double>(x) > static_cast<double>(std::numeric_limits<Out>::max()))
        return std::numeric_limits<Out>::max();
    if (is_negative(x))
        x -= 1;
    return static_cast<Out>(x + 0.5);
}