<commit_before>package pipoint

import (
	"math"
	"log"
)

// Parameters for a servo including limits.
type ServoParams struct {
	Pin int
	Span float64

	Min float64
	Max float64
}

// A servo on a pin with limits, demand, and actual position.
type Servo struct {
	params *Param
	sp     *Param
	pv     *Param
	pwm *PwmPin
}

func NewServo(name string, params *Params) *Servo {
	s := &Servo{
		params: params.NewWith(name, &ServoParams{
			Pin: -1,
			Min: 1.1,
			Max: 1.9,
			Span: math.Pi,
		}),
		sp: params.New(name + ".sp"),
		pv: params.New(name + ".pv"),
	}

	return s
}

func (s *Servo) Set(angle float64) {
	params := s.params.Get().(*ServoParams)

	s.sp.SetFloat64(angle)

	// Convert to pulse width.
	angle += math.Pi/2
	angle /= math.Pi

	ms := params.Min + angle*(params.Max - params.Min)
	if ms < 1 {
		ms = 1
	}
	if ms > 2 {
		ms = 2
	}
	s.pv.SetFloat64(ms)

	if params.Pin < 0 {
		return
	}
	if s.pwm == nil || params.Pin != s.pwm.Pin {
		if s.pwm != nil {
			s.pwm.SetEnable(0)
			s.pwm.UnExport()
		}
		s.pwm = &PwmPin{Chip: 0, Pin: params.Pin}
		
		var err error
		s.pwm.Export()
		err = s.pwm.SetEnable(0)
		if err == nil {
			err = s.pwm.SetPeriod(20e6)
		}
		if err == nil {
			s.pwm.SetDuty(int(ms*1e6))
		}
		if err == nil {
			err = s.pwm.SetEnable(1)
		}
		if err != nil {
			log.Printf("error: %v\n", err)
		}
	}
	if s.pwm != nil {
		s.pwm.SetDuty(int(ms*1e6))
	}
}<commit_msg>servo: add limits as well as calibration points.<commit_after>package pipoint

import (
	"log"
	"math"
)

// Parameters for a servo including limits.
type ServoParams struct {
	Pin  int
	Span float64

	Min  float64
	Max  float64
	Low  float64
	High float64
}

// A servo on a pin with limits, demand, and actual position.
type Servo struct {
	params *Param
	sp     *Param
	pv     *Param
	pwm    *PwmPin
}

func NewServo(name string, params *Params) *Servo {
	s := &Servo{
		params: params.NewWith(name, &ServoParams{
			Pin:  -1,
			Min:  1.0,
			Max:  2.0,
			Low:  1.1,
			High: 1.9,
			Span: math.Pi,
		}),
		sp: params.New(name + ".sp"),
		pv: params.New(name + ".pv"),
	}

	return s
}

func (s *Servo) Set(angle float64) {
	params := s.params.Get().(*ServoParams)

	s.sp.SetFloat64(angle)

	// Convert to pulse width.
	angle += math.Pi / 2

	ms := Scale(angle, 0, params.Span, params.Low, params.High)
	ms = math.Min(params.Max, math.Max(params.Min, ms))
	s.pv.SetFloat64(ms)

	if params.Pin < 0 {
		return
	}
	if s.pwm == nil || params.Pin != s.pwm.Pin {
		if s.pwm != nil {
			s.pwm.SetEnable(0)
			s.pwm.UnExport()
		}
		s.pwm = &PwmPin{Chip: 0, Pin: params.Pin}

		var err error
		s.pwm.Export()
		err = s.pwm.SetEnable(0)
		if err == nil {
			err = s.pwm.SetPeriod(20e6)
		}
		if err == nil {
			s.pwm.SetDuty(int(ms * 1e6))
		}
		if err == nil {
			err = s.pwm.SetEnable(1)
		}
		if err != nil {
			log.Printf("error: %v\n", err)
		}
	}
	if s.pwm != nil {
		s.pwm.SetDuty(int(ms * 1e6))
	}
}
{'fraction_non_alphanumeric': 0.16139022711631107, 'fraction_numerical': 0.025120440467997246, 'mean_word_length': 2.5668711656441716, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1535085', 'n_tokens_mistral': 1406, 'n_tokens_neox': 1265, 'n_words': 314}