fixed all warnings and restored original ethercat discovery behaviour
This commit is contained in:
1 parent
025464ebff
commit
e93e10d14d
6 files changed
+200
-138
No files matched your search
@@ -0,0 +1,38 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use control_core::socketio::namespace::NamespaceCacheingLogic;
|
||||
|
||||
use crate::{
|
||||
app_state::AppState,
|
||||
socketio::main_namespace::{
|
||||
MainNamespaceEvents, ethercat_interface_discovery_event::EthercatInterfaceDiscoveryEvent,
|
||||
},
|
||||
};
|
||||
|
||||
pub async fn send_ethercat_discovering(app_state: Arc<AppState>) {
|
||||
{
|
||||
let main_namespace = &mut app_state
|
||||
.socketio_setup
|
||||
.namespaces
|
||||
.write()
|
||||
.await
|
||||
.main_namespace;
|
||||
let event = EthercatInterfaceDiscoveryEvent::Discovering(true).build();
|
||||
main_namespace.emit(MainNamespaceEvents::EthercatInterfaceDiscoveryEvent(event));
|
||||
}
|
||||
}
|
||||
pub async fn send_ethercat_found(app_state: Arc<AppState>, interface: &str) {
|
||||
// Notify client via socketio
|
||||
let interface = interface.to_string();
|
||||
let app_state_socketio = app_state.clone();
|
||||
smol::block_on(async move {
|
||||
let main_namespace = &mut app_state_socketio
|
||||
.socketio_setup
|
||||
.namespaces
|
||||
.write()
|
||||
.await
|
||||
.main_namespace;
|
||||
let event = EthercatInterfaceDiscoveryEvent::Done(interface).build();
|
||||
main_namespace.emit(MainNamespaceEvents::EthercatInterfaceDiscoveryEvent(event));
|
||||
});
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod config;
|
||||
pub mod ethercat_discovery_info;
|
||||
pub mod init;
|
||||
pub mod setup;
|
||||
@@ -52,6 +52,7 @@ pub async fn setup_loop(interface: &str, app_state: Arc<AppState>) -> Result<(),
|
||||
let _ = set_core_affinity(3);
|
||||
|
||||
// Set the thread to real-time priority
|
||||
#[cfg(not(feature = "development-build"))]
|
||||
let _ = set_realtime_priority();
|
||||
|
||||
#[cfg(not(all(target_os = "linux", feature = "io-uring")))]
|
||||
@@ -85,13 +86,13 @@ pub async fn setup_loop(interface: &str, app_state: Arc<AppState>) -> Result<(),
|
||||
// Default 30_000us
|
||||
pdu: Duration::from_micros(30_000),
|
||||
// Default 10ms
|
||||
eeprom: Duration::from_millis(100),
|
||||
eeprom: Duration::from_millis(10),
|
||||
// Default 0ms
|
||||
wait_loop_delay: Duration::from_millis(0),
|
||||
// Default 100ms
|
||||
mailbox_echo: Duration::from_millis(1000),
|
||||
mailbox_echo: Duration::from_millis(100),
|
||||
// Default 1000ms
|
||||
mailbox_response: Duration::from_millis(10000),
|
||||
mailbox_response: Duration::from_millis(1000),
|
||||
},
|
||||
MainDeviceConfig {
|
||||
// Default RetryBehaviour::None
|
||||
|
||||
+15
-2
@@ -1,4 +1,4 @@
|
||||
use crate::app_state::AppState;
|
||||
use crate::{app_state::AppState, ethercat::setup::setup_loop};
|
||||
use bitvec::prelude::*;
|
||||
use control_core::machines::connection::MachineConnection;
|
||||
use control_core::realtime::set_core_affinity;
|
||||
@@ -9,8 +9,20 @@ use std::time::Instant;
|
||||
use tracing::{instrument, trace_span};
|
||||
|
||||
pub fn start_loop_thread(
|
||||
interface: &str,
|
||||
app_state: Arc<AppState>,
|
||||
) -> Result<std::thread::JoinHandle<()>, std::io::Error> {
|
||||
let res = smol::block_on(async { setup_loop(interface, app_state.clone()).await });
|
||||
match res {
|
||||
Ok(_) => tracing::info!("Successfully initialized EtherCAT network"),
|
||||
Err(e) => {
|
||||
tracing::error!(
|
||||
"[{}::init_loop] Failed to initialize EtherCAT network \n{:?}",
|
||||
module_path!(),
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
// Start control loop
|
||||
let res = std::thread::Builder::new()
|
||||
.name("loop".to_owned())
|
||||
@@ -43,7 +55,8 @@ pub fn start_loop_thread(
|
||||
#[cfg(feature = "development-build")]
|
||||
std::thread::park_timeout(std::time::Duration::from_millis(600));
|
||||
}
|
||||
// Exit the entire program if the Loop fails (gets restarted by systemd if running on NixOS)
|
||||
// Exit the entire program if the Loop fails
|
||||
// gets restarted by systemd if running on NixOS, or different distro wtih the same sysd service
|
||||
std::process::exit(1);
|
||||
});
|
||||
return res;
|
||||
|
||||
+19
-131
@@ -1,34 +1,21 @@
|
||||
use anyhow::Result;
|
||||
use control_core::{
|
||||
machines::identification::MachineIdentificationUnique,
|
||||
serial::{
|
||||
SerialDeviceIdentification, SerialDeviceNew, SerialDeviceNewParams,
|
||||
serial_detection::SerialDetection,
|
||||
},
|
||||
socketio::namespace::NamespaceCacheingLogic,
|
||||
};
|
||||
use futures::{FutureExt, select};
|
||||
use machines::{laser::LaserMachine, registry::MACHINE_REGISTRY};
|
||||
#[cfg(feature = "mock-machine")]
|
||||
use mock::init::init_mock;
|
||||
use serialport::UsbPortInfo;
|
||||
|
||||
#[cfg(feature = "mock-machine")]
|
||||
pub mod mock;
|
||||
|
||||
use crate::panic::init_panic_handling;
|
||||
use app_state::AppState;
|
||||
use ethercat::init::start_interface_discovery;
|
||||
use ethercat::{
|
||||
ethercat_discovery_info::{send_ethercat_discovering, send_ethercat_found},
|
||||
init::start_interface_discovery,
|
||||
};
|
||||
use r#loop::start_loop_thread;
|
||||
use rest::init::start_api_thread;
|
||||
use serial::{
|
||||
devices::laser::Laser, init::start_serial_discovery, registry::SERIAL_DEVICE_REGISTRY,
|
||||
};
|
||||
use socketio::{
|
||||
main_namespace::{MainNamespaceEvents, machines_event::MachinesEventBuilder},
|
||||
queue::start_socketio_queue,
|
||||
};
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
use serial::init::{handle_serial_device_hotplug, start_serial_discovery};
|
||||
use socketio::queue::start_socketio_queue;
|
||||
use std::sync::Arc;
|
||||
pub mod app_state;
|
||||
pub mod ethercat;
|
||||
pub mod logging;
|
||||
@@ -40,112 +27,6 @@ pub mod rest;
|
||||
pub mod serial;
|
||||
pub mod socketio;
|
||||
|
||||
// This function handles a disconnection and or reconnection of Laser
|
||||
// You can easily rewrite it when we have more serialdevices
|
||||
// TODO: Add A static list of known SeriadeviceIdents
|
||||
async fn handle_serial_device_hotplug(
|
||||
app_state: Arc<AppState>,
|
||||
map: Option<HashMap<String, UsbPortInfo>>,
|
||||
) {
|
||||
let laser_ident = SerialDeviceIdentification {
|
||||
vendor_id: 0x0403,
|
||||
product_id: 0x6001,
|
||||
};
|
||||
|
||||
let laser = match map {
|
||||
Some(map) => SerialDetection::get_path_by_id(laser_ident, map),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let mut unique_ident: Option<MachineIdentificationUnique> = None;
|
||||
|
||||
{
|
||||
let machines = app_state.machines.read_arc_blocking();
|
||||
for (id, _) in machines.iter() {
|
||||
if id.machine_identification == LaserMachine::MACHINE_IDENTIFICATION {
|
||||
unique_ident = Some(id.clone());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Machine isnt connected, so add it back
|
||||
if laser.is_some() && unique_ident.is_none() {
|
||||
let serial_params = SerialDeviceNewParams {
|
||||
path: laser.unwrap(),
|
||||
};
|
||||
let _ = match Laser::new_serial(&serial_params) {
|
||||
Ok((device_identification, serial_device)) => {
|
||||
{
|
||||
let mut machines = app_state.machines.write().await;
|
||||
machines.add_serial_device(
|
||||
&device_identification,
|
||||
serial_device,
|
||||
&MACHINE_REGISTRY,
|
||||
app_state.socketio_setup.socket_queue_tx.clone(),
|
||||
Arc::downgrade(&app_state.machines),
|
||||
);
|
||||
}
|
||||
|
||||
let app_state_event = app_state.clone();
|
||||
let main_namespace = &mut app_state_event
|
||||
.socketio_setup
|
||||
.namespaces
|
||||
.write()
|
||||
.await
|
||||
.main_namespace;
|
||||
let event = MachinesEventBuilder().build(app_state_event.clone());
|
||||
main_namespace.emit(MainNamespaceEvents::MachinesEvent(event));
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
} else if laser.is_none() && unique_ident.is_some() {
|
||||
tracing::info!("hello non existing laser");
|
||||
let serial_params = SerialDeviceNewParams {
|
||||
path: "".to_string(),
|
||||
};
|
||||
|
||||
let _ = match Laser::new_serial(&serial_params) {
|
||||
Ok((device_identification, _)) => {
|
||||
app_state
|
||||
.machines
|
||||
.write()
|
||||
.await
|
||||
.remove_serial_device(&device_identification);
|
||||
drop(app_state.machines.clone());
|
||||
|
||||
app_state
|
||||
.machines
|
||||
.write_arc()
|
||||
.await
|
||||
.serial_machines
|
||||
.remove(&unique_ident.clone().unwrap());
|
||||
|
||||
app_state
|
||||
.machines
|
||||
.write_arc()
|
||||
.await
|
||||
.ethercat_machines
|
||||
.remove(&unique_ident.clone().unwrap());
|
||||
|
||||
drop(app_state.machines.clone());
|
||||
|
||||
let main_namespace = &mut app_state
|
||||
.socketio_setup
|
||||
.namespaces
|
||||
.write()
|
||||
.await
|
||||
.main_namespace;
|
||||
|
||||
tracing::info!("{:?}", app_state.machines);
|
||||
let event = MachinesEventBuilder().build(app_state.clone());
|
||||
main_namespace.emit(MainNamespaceEvents::MachinesEvent(event));
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
logging::init_tracing();
|
||||
tracing::info!("Tracing initialized successfully");
|
||||
@@ -154,28 +35,35 @@ fn main() {
|
||||
let app_state = Arc::new(AppState::new());
|
||||
|
||||
let _ = start_api_thread(app_state.clone());
|
||||
let _ = start_loop_thread(app_state.clone());
|
||||
|
||||
let mut socketio_fut = start_socketio_queue(app_state.clone()).fuse();
|
||||
let mut ethercat_fut = start_interface_discovery().fuse();
|
||||
let mut serial_fut = start_serial_discovery().fuse();
|
||||
|
||||
smol::block_on(async { send_ethercat_discovering(app_state.clone()).await });
|
||||
|
||||
smol::block_on(async {
|
||||
loop {
|
||||
// lets the async runtime decide which future to run next
|
||||
select! {
|
||||
res = ethercat_fut => {
|
||||
// Should only complete once
|
||||
tracing::info!("EtherCAT task finished: {:?}", res);
|
||||
match res {
|
||||
Ok(interface) =>
|
||||
{
|
||||
send_ethercat_found(app_state.clone(), &interface).await;
|
||||
let _ = start_loop_thread(&interface, app_state.clone());
|
||||
},
|
||||
Err(_) => (),
|
||||
};
|
||||
|
||||
},
|
||||
res = serial_fut => {
|
||||
// tracing::info!("Serial discovery finished: {:?}", res);
|
||||
let _ = handle_serial_device_hotplug(app_state.clone(),res).await;
|
||||
serial_fut = start_serial_discovery().fuse();
|
||||
},
|
||||
res = socketio_fut => {
|
||||
// In theory it should never finish
|
||||
tracing::info!("SocketIO task finished: {:?}", res);
|
||||
tracing::warn!("SocketIO task finished: {:?}", res);
|
||||
},
|
||||
_ = smol::Timer::after(std::time::Duration::from_millis(250)).fuse() => {} // Nothing to do just sleep
|
||||
}
|
||||
|
||||
+123
-2
@@ -1,7 +1,22 @@
|
||||
use control_core::serial::serial_detection::SerialDetection;
|
||||
use control_core::{
|
||||
machines::identification::MachineIdentificationUnique,
|
||||
serial::{
|
||||
SerialDeviceIdentification, SerialDeviceNew, SerialDeviceNewParams,
|
||||
serial_detection::SerialDetection,
|
||||
},
|
||||
socketio::namespace::NamespaceCacheingLogic,
|
||||
};
|
||||
use serialport::UsbPortInfo;
|
||||
use smol::Task;
|
||||
use std::{collections::HashMap, time::Duration};
|
||||
use std::{collections::HashMap, sync::Arc, time::Duration};
|
||||
|
||||
use crate::{
|
||||
app_state::AppState,
|
||||
machines::{laser::LaserMachine, registry::MACHINE_REGISTRY},
|
||||
socketio::main_namespace::{MainNamespaceEvents, machines_event::MachinesEventBuilder},
|
||||
};
|
||||
|
||||
use super::devices::laser::Laser;
|
||||
|
||||
// Async function that runs until at least one serial device is found.
|
||||
pub async fn find_serial() -> Option<HashMap<String, UsbPortInfo>> {
|
||||
@@ -18,3 +33,109 @@ pub async fn find_serial() -> Option<HashMap<String, UsbPortInfo>> {
|
||||
pub fn start_serial_discovery() -> Task<Option<HashMap<String, UsbPortInfo>>> {
|
||||
smol::spawn(find_serial())
|
||||
}
|
||||
|
||||
// This function handles a disconnection and or reconnection of Laser
|
||||
// You can easily rewrite it when we have more serialdevices
|
||||
// TODO: Add A static list of known SeriadeviceIdents
|
||||
pub async fn handle_serial_device_hotplug(
|
||||
app_state: Arc<AppState>,
|
||||
map: Option<HashMap<String, UsbPortInfo>>,
|
||||
) {
|
||||
let laser_ident = SerialDeviceIdentification {
|
||||
vendor_id: 0x0403,
|
||||
product_id: 0x6001,
|
||||
};
|
||||
|
||||
let laser = match map {
|
||||
Some(map) => SerialDetection::get_path_by_id(laser_ident, map),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let mut unique_ident: Option<MachineIdentificationUnique> = None;
|
||||
|
||||
{
|
||||
let machines = app_state.machines.read_arc_blocking();
|
||||
for (id, _) in machines.iter() {
|
||||
if id.machine_identification == LaserMachine::MACHINE_IDENTIFICATION {
|
||||
unique_ident = Some(id.clone());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Machine isnt connected, so add it back
|
||||
if laser.is_some() && unique_ident.is_none() {
|
||||
let serial_params = SerialDeviceNewParams {
|
||||
path: laser.unwrap(),
|
||||
};
|
||||
let _ = match Laser::new_serial(&serial_params) {
|
||||
Ok((device_identification, serial_device)) => {
|
||||
{
|
||||
let mut machines = app_state.machines.write().await;
|
||||
machines.add_serial_device(
|
||||
&device_identification,
|
||||
serial_device,
|
||||
&MACHINE_REGISTRY,
|
||||
app_state.socketio_setup.socket_queue_tx.clone(),
|
||||
Arc::downgrade(&app_state.machines),
|
||||
);
|
||||
}
|
||||
|
||||
let app_state_event = app_state.clone();
|
||||
let main_namespace = &mut app_state_event
|
||||
.socketio_setup
|
||||
.namespaces
|
||||
.write()
|
||||
.await
|
||||
.main_namespace;
|
||||
let event = MachinesEventBuilder().build(app_state_event.clone());
|
||||
main_namespace.emit(MainNamespaceEvents::MachinesEvent(event));
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
} else if laser.is_none() && unique_ident.is_some() {
|
||||
tracing::info!("hello non existing laser");
|
||||
let serial_params = SerialDeviceNewParams {
|
||||
path: "".to_string(),
|
||||
};
|
||||
|
||||
let _ = match Laser::new_serial(&serial_params) {
|
||||
Ok((device_identification, _)) => {
|
||||
app_state
|
||||
.machines
|
||||
.write()
|
||||
.await
|
||||
.remove_serial_device(&device_identification);
|
||||
drop(app_state.machines.clone());
|
||||
|
||||
app_state
|
||||
.machines
|
||||
.write_arc()
|
||||
.await
|
||||
.serial_machines
|
||||
.remove(&unique_ident.clone().unwrap());
|
||||
|
||||
app_state
|
||||
.machines
|
||||
.write_arc()
|
||||
.await
|
||||
.ethercat_machines
|
||||
.remove(&unique_ident.clone().unwrap());
|
||||
|
||||
drop(app_state.machines.clone());
|
||||
|
||||
let main_namespace = &mut app_state
|
||||
.socketio_setup
|
||||
.namespaces
|
||||
.write()
|
||||
.await
|
||||
.main_namespace;
|
||||
|
||||
tracing::info!("{:?}", app_state.machines);
|
||||
let event = MachinesEventBuilder().build(app_state.clone());
|
||||
main_namespace.emit(MainNamespaceEvents::MachinesEvent(event));
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user