This commit is contained in:
Astro 2019-09-19 03:29:06 +02:00
parent 63aa2347b7
commit 35dfba99e1
2 changed files with 33 additions and 27 deletions

View File

@ -123,17 +123,22 @@ fn whitespace(input: &[u8]) -> IResult<&[u8], ()> {
fold_many1(char(' '), (), |(), _| ())(input) fold_many1(char(' '), (), |(), _| ())(input)
} }
fn unsigned(input: &[u8]) -> IResult<&[u8], Result<u32, lexical::Error>> { fn unsigned(input: &[u8]) -> IResult<&[u8], Result<u32, Error>> {
take_while1(is_digit)(input) take_while1(is_digit)(input)
.map(|(input, digits)| (input, lexical::parse(digits))) .map(|(input, digits)| {
let result = lexical::parse(digits)
.map_err(|e| e.into());
(input, result)
})
} }
fn float(input: &[u8]) -> IResult<&[u8], Result<f32, lexical::Error>> { fn float(input: &[u8]) -> IResult<&[u8], Result<f32, Error>> {
let (input, sign) = is_a("-")(input)?; let (input, sign) = is_a("-")(input)?;
let negative = sign.len() > 0; let negative = sign.len() > 0;
let (input, digits) = take_while1(|c| is_digit(c) || c == '.' as u8)(input)?; let (input, digits) = take_while1(|c| is_digit(c) || c == '.' as u8)(input)?;
let result = lexical::parse(digits) let result = lexical::parse(digits)
.map(|result: f32| if negative { -result } else { result }); .map(|result: f32| if negative { -result } else { result })
.map_err(|e| e.into());
Ok((input, result)) Ok((input, result))
} }
@ -172,9 +177,7 @@ fn report(input: &[u8]) -> IResult<&[u8], Command> {
} }
/// `pwm <0-1> <width> <total>` - Set pwm duty cycle /// `pwm <0-1> <width> <total>` - Set pwm duty cycle
fn pwm_manual(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> { fn pwm_manual(input: &[u8]) -> IResult<&[u8], Result<PwmMode, Error>> {
let (input, channel) = channel(input)?;
let (input, _) = whitespace(input)?;
let (input, width) = unsigned(input)?; let (input, width) = unsigned(input)?;
let width = match width { let width = match width {
Ok(width) => width, Ok(width) => width,
@ -186,20 +189,12 @@ fn pwm_manual(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
Ok(total) => total, Ok(total) => total,
Err(e) => return Ok((input, Err(e.into()))), Err(e) => return Ok((input, Err(e.into()))),
}; };
Ok((input, Ok(Command::Pwm { Ok((input, Ok(PwmMode::Manual { width, total })))
channel,
mode: PwmMode::Manual { width, total },
})))
} }
/// `pwm <0-1> pid` - Set PWM to be controlled by PID /// `pwm <0-1> pid` - Set PWM to be controlled by PID
fn pwm_pid(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> { fn pwm_pid(input: &[u8]) -> IResult<&[u8], Result<PwmMode, Error>> {
let (input, channel) = channel(input)?; value(Ok(PwmMode::Pid), tag("pid"))(input)
let (input, _) = whitespace(input)?;
value(Ok(Command::Pwm {
channel,
mode: PwmMode::Pid,
}), tag("pid"))(input)
} }
fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> { fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
@ -207,10 +202,18 @@ fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
alt(( alt((
preceded( preceded(
whitespace, whitespace,
alt(( map(
pwm_pid, separated_pair(
pwm_manual, channel,
))), whitespace,
alt((
pwm_pid,
pwm_manual,
))
),
|(channel, mode)| mode.map(|mode| Command::Pwm { channel, mode })
)
),
value(Ok(Command::Show(ShowCommand::Pwm)), end) value(Ok(Command::Show(ShowCommand::Pwm)), end)
))(input) ))(input)
} }
@ -232,8 +235,7 @@ fn pid_parameter(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
let (input, _) = whitespace(input)?; let (input, _) = whitespace(input)?;
let (input, value) = float(input)?; let (input, value) = float(input)?;
let result = value let result = value
.map(|value| Command::Pid { channel, parameter, value }) .map(|value| Command::Pid { channel, parameter, value });
.map_err(|e| e.into());
Ok((input, result)) Ok((input, result))
} }

View File

@ -280,7 +280,7 @@ fn main() -> ! {
Command::Show(ShowCommand::Pid) => { Command::Show(ShowCommand::Pid) => {
for (channel, state) in states.iter().enumerate() { for (channel, state) in states.iter().enumerate() {
let _ = writeln!(socket, "PID settings for channel {}", channel); let _ = writeln!(socket, "PID settings for channel {}", channel);
let pid = &states[channel].pid; let pid = &state.pid;
let _ = writeln!(socket, "- target={:.4}", pid.get_target()); let _ = writeln!(socket, "- target={:.4}", pid.get_target());
let p = pid.get_parameters(); let p = pid.get_parameters();
macro_rules! out { macro_rules! out {
@ -299,7 +299,8 @@ fn main() -> ! {
} }
Command::Show(ShowCommand::Pwm) => { Command::Show(ShowCommand::Pwm) => {
for (channel, state) in states.iter().enumerate() { for (channel, state) in states.iter().enumerate() {
let _ = writeln!(socket, "PWM {}: PID {}", let _ = writeln!(
socket, "PWM {}: PID {}",
channel, channel,
if state.pid_enabled { "engaged" } else { "disengaged" } if state.pid_enabled { "engaged" } else { "disengaged" }
); );
@ -327,7 +328,10 @@ fn main() -> ! {
states[channel].pid_enabled = false; states[channel].pid_enabled = false;
board::set_timer_pwm(width, total); board::set_timer_pwm(width, total);
if channel == 0 { // TODO if channel == 0 { // TODO
let _ = writeln!(socket, "channel {}: PWM duty cycle manually set to {}/{}", channel, width, total); let _ = writeln!(
socket, "channel {}: PWM duty cycle manually set to {}/{}",
channel, width, total
);
} }
} }
Command::Pwm { channel, mode: PwmMode::Pid } => { Command::Pwm { channel, mode: PwmMode::Pid } => {