use kcan::{
CanFrame, CanId, DirectCommand, FeedbackMessageConfig, KnottDynamicsMode, KnottDynamicsModel,
MOTOR_DISABLE_ACKNOWLEDGEMENT, MitCommand, MotorFeedbackUpdate, MotorModel, RobStrideCommand,
RobStrideModel, direct_command_frame, knott_dynamics_nmt_frame,
knott_dynamics_position_velocity_frame, mit_command_frame, parse_position_32bit_feedback,
robstride_command_frame, robstride_status_query_frame,
};
#[test]
fn root_exports_build_common_frames() -> kcan::Result<()> {
let mit = mit_command_frame(MotorModel::Ak60_6, 0x03, MitCommand::neutral())?;
assert_eq!(mit.id().raw(), 0x0803);
assert_eq!(mit.len(), 8);
let ak60_39 = mit_command_frame(MotorModel::Ak60_39, 0x03, MitCommand::neutral())?;
assert_eq!(ak60_39.id().raw(), 0x0803);
assert_eq!(ak60_39.len(), 8);
let direct = direct_command_frame(0x03, DirectCommand::Velocity(1_000))?;
assert_eq!(direct.id().raw(), 0x0303);
assert_eq!(direct.data(), &[0x00, 0x00, 0x03, 0xE8]);
let feedback_config = direct_command_frame(
0x03,
DirectCommand::ConfigureFeedback(FeedbackMessageConfig {
position_32bit_feedback: true,
single_turn_position: false,
}),
)?;
assert_eq!(feedback_config.id().raw(), 0x1003);
assert_eq!(feedback_config.data()[6..], [0x80, 0x00]);
assert_eq!(MOTOR_DISABLE_ACKNOWLEDGEMENT, 0x77);
let position = parse_position_32bit_feedback(&100_i32.to_be_bytes())?;
assert_eq!(position.position_degrees, 1.0);
assert!(matches!(
MotorFeedbackUpdate::Position32(position),
MotorFeedbackUpdate::Position32(value) if value.raw_position == 100
));
let status = robstride_status_query_frame(0x01)?;
let status_from_command =
robstride_command_frame(RobStrideModel::Rs01, 0x01, RobStrideCommand::StatusQuery)?;
assert_eq!(status_from_command, status);
assert_eq!(status.id().raw(), 0x501);
let model: KnottDynamicsModel = "k01".parse()?;
assert_eq!(model, KnottDynamicsModel::K01);
let nmt = knott_dynamics_nmt_frame(Some(1), KnottDynamicsMode::Idle)?;
assert_eq!(nmt.id().raw(), 0);
assert_eq!(nmt.data(), &[0x01, 0x01]);
let position_velocity = knott_dynamics_position_velocity_frame(1, 1.0, -2.0)?;
assert_eq!(position_velocity.id().raw(), 0x301);
Ok(())
}
#[test]
fn can_ids_and_frames_have_stable_display_output() -> kcan::Result<()> {
let standard = CanId::standard(0x123)?;
let extended = CanId::extended(0x501)?;
let frame = CanFrame::new(extended, &[0x0A, 0xB0])?;
assert_eq!(standard.kind_name(), "standard");
assert_eq!(extended.kind_name(), "extended");
assert_eq!(standard.to_string(), "standard 0x123");
assert_eq!(extended.to_string(), "extended 0x501");
assert_eq!(frame.to_string(), "extended 0x501 len=2 data=0A B0");
assert_eq!(standard.to_string().parse::<CanId>().unwrap(), standard);
assert_eq!(extended.to_string().parse::<CanId>().unwrap(), extended);
assert_eq!("s:0x123".parse::<CanId>().unwrap(), standard);
assert_eq!("e:0x501".parse::<CanId>().unwrap(), extended);
assert!("0x123".parse::<CanId>().is_err());
assert!("standard 0x800".parse::<CanId>().is_err());
Ok(())
}